Polish dialog and intro transitions
This commit is contained in:
parent
3975959017
commit
d413d1da9f
7 changed files with 228 additions and 4 deletions
87
tests/test_dialog_releases_joysticks.gd
Normal file
87
tests/test_dialog_releases_joysticks.gd
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
extends SceneTree
|
||||
|
||||
# Forgejo #182: opening a dialog releases both touch joysticks before the
|
||||
# world is paused. A finger-up event during the pause cannot reach their
|
||||
# ordinary input path, so waiting for it would resume stale movement/fire.
|
||||
|
||||
var state: Node
|
||||
var main: Node
|
||||
var fleet: Node
|
||||
var narration: Control
|
||||
var movement: Control
|
||||
var firing: Control
|
||||
var stage: int = 0
|
||||
var elapsed: float = 0.0
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
state = root.get_node("GameState")
|
||||
state.reset_new_game()
|
||||
state.intro_active = false
|
||||
state.reset_quests()
|
||||
main = load("res://world/Main.tscn").instantiate()
|
||||
root.add_child(main)
|
||||
current_scene = main
|
||||
fleet = main.get_node("Fleet")
|
||||
narration = main.get_node("UI/NarrationBanner")
|
||||
movement = main.get_node("UI/Joystick")
|
||||
firing = main.get_node("UI/FireStick")
|
||||
|
||||
|
||||
func _hold(stick: Control, index: int, direction: Vector2) -> void:
|
||||
var centre: Vector2 = stick.global_position + stick.size * 0.5
|
||||
var press := InputEventScreenTouch.new()
|
||||
press.index = index
|
||||
press.pressed = true
|
||||
press.position = centre
|
||||
stick.handle_touch(press)
|
||||
var drag := InputEventScreenDrag.new()
|
||||
drag.index = index
|
||||
drag.position = centre + direction.normalized() * stick.max_radius
|
||||
stick.handle_drag(drag)
|
||||
|
||||
|
||||
func _process(delta: float) -> bool:
|
||||
elapsed += delta
|
||||
if stage != 0 or elapsed < 0.3:
|
||||
return false
|
||||
stage = 1
|
||||
main.get_node("EnemySpawner").set_process(false)
|
||||
main.get_node("AsteroidField").set_process(false)
|
||||
_hold(movement, 21, Vector2.RIGHT)
|
||||
_hold(firing, 22, Vector2.UP)
|
||||
main._process(0.0)
|
||||
main.get_node("FireStickController")._process(0.0)
|
||||
if not movement.is_active() or not firing.is_active():
|
||||
return _fail("the test could not hold both joysticks")
|
||||
if movement.direction == Vector2.ZERO or firing.direction == Vector2.ZERO:
|
||||
return _fail("a held joystick reported no direction")
|
||||
if fleet.steer_direction == Vector2.ZERO:
|
||||
return _fail("the movement joystick had not begun steering")
|
||||
|
||||
narration.say("Hands clear.", "TEST")
|
||||
if not paused:
|
||||
return _fail("the dialog did not pause the game")
|
||||
for stick in [movement, firing]:
|
||||
if stick.is_active() or stick.direction != Vector2.ZERO:
|
||||
return _fail("%s remained held behind the dialog" % stick.name)
|
||||
if stick.base_pos.distance_to(stick.home_pos()) > 0.01 \
|
||||
or stick.knob_pos.distance_to(stick.home_pos()) > 0.01:
|
||||
return _fail("%s did not visually recenter" % stick.name)
|
||||
if fleet.steer_direction != Vector2.ZERO:
|
||||
return _fail("releasing the movement joystick did not stop the fleet")
|
||||
|
||||
narration.clear()
|
||||
main.get_node("FireStickController")._process(0.0)
|
||||
if main.get_node("FireStickController").is_firing():
|
||||
return _fail("fire resumed from stale joystick input after the dialog")
|
||||
print("dialog released and recentered movement and fire joysticks before pausing")
|
||||
print("TEST_DIALOG_RELEASES_JOYSTICKS: PASS")
|
||||
quit(0)
|
||||
return true
|
||||
|
||||
|
||||
func _fail(message: String) -> bool:
|
||||
print("TEST_DIALOG_RELEASES_JOYSTICKS: FAIL (%s)" % message)
|
||||
quit(1)
|
||||
return true
|
||||
1
tests/test_energy_propulser_dash.gd.uid
Normal file
1
tests/test_energy_propulser_dash.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bxn8xvfo3v7v0
|
||||
|
|
@ -35,6 +35,8 @@ extends SceneTree
|
|||
# R. #139 - no belt rock is laid down inside the visible screen
|
||||
# S. #170 - the prologue opens on the PICTURE: the convoy is flying and the
|
||||
# game is running for a few seconds before the guide says anything
|
||||
# T. #183 - absorption whites out the full screen, teleports only once the
|
||||
# cover is opaque, then reveals the fleet at the normal spawn
|
||||
|
||||
var game_state: Node
|
||||
var scene: Node
|
||||
|
|
@ -45,6 +47,7 @@ var stage: int = 0
|
|||
var elapsed: float = 0.0
|
||||
var convoy_size: int = 0
|
||||
var skipped_props: Array = []
|
||||
var whiteout_mid_checked: bool = false
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
|
|
@ -367,6 +370,14 @@ func _process(delta: float) -> bool:
|
|||
|
||||
# --- H. the vortex --------------------------------------
|
||||
director._begin(director.Beat.VORTEX)
|
||||
var fade: ColorRect = scene.get_node("FadeOverlay/FadeRect")
|
||||
var viewport_size: Vector2 = scene.get_viewport().get_visible_rect().size
|
||||
if fade.size.distance_to(viewport_size) > 1.0:
|
||||
return _fail("whiteout is %s, viewport is %s" % [fade.size, viewport_size])
|
||||
if fade.color.r < 0.99 or fade.color.g < 0.99 or fade.color.b < 0.99:
|
||||
return _fail("the vortex transition is not white")
|
||||
if fade.color.a > 0.01:
|
||||
return _fail("the whiteout began fully opaque instead of fading in")
|
||||
elapsed = 0.0
|
||||
stage = 3
|
||||
return false
|
||||
|
|
@ -374,6 +385,15 @@ func _process(delta: float) -> bool:
|
|||
# Left to the director's own clock rather than ticked by hand:
|
||||
# the vortex is a timed animation and driving it twice would not
|
||||
# be the thing that ships.
|
||||
if not whiteout_mid_checked and elapsed >= director.WHITEOUT_IN_SECONDS * 0.5:
|
||||
whiteout_mid_checked = true
|
||||
var mid_fade: ColorRect = scene.get_node("FadeOverlay/FadeRect")
|
||||
if mid_fade.color.a <= 0.05 or mid_fade.color.a >= 0.95:
|
||||
return _fail("whiteout did not gradually fade in (alpha %.2f)" % mid_fade.color.a)
|
||||
if director.whiteout_teleported:
|
||||
return _fail("fleet teleported before the screen was fully white")
|
||||
if fleet.get_formation_origin().distance_to(director.DEFAULT_SPAWN) <= 1.0:
|
||||
return _fail("fleet reached default spawn before full white")
|
||||
if elapsed < 4.2:
|
||||
return false
|
||||
var alive: int = 0
|
||||
|
|
@ -386,6 +406,15 @@ func _process(delta: float) -> bool:
|
|||
return _fail("the survivor is a %s, not the default interceptor" \
|
||||
% fleet.ships[0].vessel_type)
|
||||
print("the vortex took %d vessels and left one interceptor" % (convoy_size - 1))
|
||||
if not director.whiteout_teleported:
|
||||
return _fail("the screen reached white without teleporting the fleet")
|
||||
if fleet.get_formation_origin().distance_to(director.DEFAULT_SPAWN) > 1.0:
|
||||
return _fail("whiteout revealed the fleet at %s instead of default spawn %s" \
|
||||
% [fleet.get_formation_origin(), director.DEFAULT_SPAWN])
|
||||
var revealing: ColorRect = scene.get_node("FadeOverlay/FadeRect")
|
||||
if revealing.color.a >= 0.99:
|
||||
return _fail("screen stayed fully white after teleport")
|
||||
print("whiteout hid the teleport to default spawn, then began revealing it")
|
||||
|
||||
# --- I. the handover ------------------------------------
|
||||
director.finish()
|
||||
|
|
@ -426,6 +455,9 @@ func _process(delta: float) -> bool:
|
|||
return _fail("the breach lens is still over the screen after the handover")
|
||||
if is_instance_valid(director) and director.breach != null:
|
||||
return _fail("the black hole outlived the prologue")
|
||||
var finished_fade: ColorRect = scene.get_node("FadeOverlay/FadeRect")
|
||||
if finished_fade.color.a > 0.001 or finished_fade.color.r > 0.001:
|
||||
return _fail("intro left the shared fade overlay tinted white")
|
||||
print("handover: flags clear, 1 interceptor, waves and rocks running, buttons back")
|
||||
_drop_scene()
|
||||
elapsed = 0.0
|
||||
|
|
|
|||
Loading…
Reference in a new issue