123 lines
4.5 KiB
GDScript
123 lines
4.5 KiB
GDScript
extends SceneTree
|
|
|
|
# Headless test: run with
|
|
# godot --headless -s res://tests/test_joystick_recentres.gd
|
|
# Both sticks float: the base jumps to wherever the finger lands, so a player
|
|
# does not have to hit an exact spot on a screen they cannot feel. Releasing
|
|
# used to put only the KNOB back onto the base, leaving the base parked
|
|
# wherever that touch had been - so an idle stick sat off-centre, in a
|
|
# different place every time, and read as a control still in use.
|
|
#
|
|
# Covers, for the movement stick AND the fire stick:
|
|
# A. an untouched stick sits in the middle of its own rect
|
|
# B. pressing off-centre moves the base there - the floating behaviour is
|
|
# still intact, which is the thing this must not break
|
|
# C. releasing puts base AND knob back in the middle
|
|
# D. releasing also clears the reported direction, so nothing keeps acting
|
|
# on a stick nobody is holding
|
|
|
|
const OFFSET := Vector2(-58.0, 41.0)
|
|
const MIN_TOUCH_AREA: float = 160000.0
|
|
const MIN_VISIBLE_RADIUS: float = 138.0
|
|
|
|
var main: Node
|
|
var stage: int = 0
|
|
var elapsed: float = 0.0
|
|
|
|
|
|
func _initialize() -> void:
|
|
main = load("res://world/Main.tscn").instantiate()
|
|
root.add_child(main)
|
|
current_scene = main
|
|
|
|
|
|
func _check(stick: Control, label: String) -> bool:
|
|
var home: Vector2 = stick.home_pos()
|
|
if stick.size.x * stick.size.y < MIN_TOUCH_AREA:
|
|
return _fail("%s touch zone is only %s (%.0f area)" \
|
|
% [label, stick.size, stick.size.x * stick.size.y])
|
|
if stick.max_radius < MIN_VISIBLE_RADIUS:
|
|
return _fail("%s visible radius is only %.0f" % [label, stick.max_radius])
|
|
|
|
# --- A. idle means centred -------------------------------------------
|
|
if stick.base_pos.distance_to(home) > 0.01 or stick.knob_pos.distance_to(home) > 0.01:
|
|
return _fail("%s starts at base %s knob %s, expected both at %s" \
|
|
% [label, stick.base_pos, stick.knob_pos, home])
|
|
|
|
# --- B. it still floats to the finger ---------------------------------
|
|
var press := InputEventScreenTouch.new()
|
|
press.index = 2
|
|
press.pressed = true
|
|
press.position = stick.global_position + home + OFFSET
|
|
if not stick.handle_touch(press):
|
|
return _fail("%s refused a touch inside its own rect" % label)
|
|
if stick.base_pos.distance_to(home + OFFSET) > 0.01:
|
|
return _fail("%s did not float its base to the finger: base %s, expected %s" \
|
|
% [label, stick.base_pos, home + OFFSET])
|
|
|
|
var drag := InputEventScreenDrag.new()
|
|
drag.index = 2
|
|
drag.position = press.position + Vector2(stick.max_radius, 0.0)
|
|
stick.handle_drag(drag)
|
|
if stick.direction == Vector2.ZERO:
|
|
return _fail("%s reported no direction while pushed" % label)
|
|
if stick.knob_pos.distance_to(stick.base_pos) < stick.max_radius * 0.5:
|
|
return _fail("%s knob barely moved while pushed" % label)
|
|
|
|
# --- C/D. release recentres everything and stops reporting ------------
|
|
var release := InputEventScreenTouch.new()
|
|
release.index = 2
|
|
release.pressed = false
|
|
release.position = drag.position
|
|
stick.handle_touch(release)
|
|
if stick.base_pos.distance_to(home) > 0.01:
|
|
return _fail("%s left its base at %s after release, expected %s" \
|
|
% [label, stick.base_pos, home])
|
|
if stick.knob_pos.distance_to(home) > 0.01:
|
|
return _fail("%s left its knob at %s after release, expected %s" \
|
|
% [label, stick.knob_pos, home])
|
|
if stick.direction != Vector2.ZERO:
|
|
return _fail("%s still reports %s after release" % [label, stick.direction])
|
|
if stick.is_active():
|
|
return _fail("%s still claims to be held after release" % label)
|
|
print("%s: floats to the finger, and returns to centre on release" % label)
|
|
return true
|
|
|
|
|
|
func _check_pair(host: Node, label: String) -> bool:
|
|
var movement: Control = host.get_node("UI/Joystick")
|
|
var fire: Control = host.get_node("UI/FireStick")
|
|
if movement.get_global_rect().intersects(fire.get_global_rect()):
|
|
return _fail("%s joystick touch zones overlap" % label)
|
|
if not _check(movement, "%s movement stick" % label):
|
|
return false
|
|
if not _check(fire, "%s fire stick" % label):
|
|
return false
|
|
return true
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
elapsed += delta
|
|
if stage != 0:
|
|
return false
|
|
if elapsed < 0.2:
|
|
return false
|
|
stage = 1
|
|
if not _check_pair(main, "space"):
|
|
return true
|
|
var surface: Node = load("res://surface/PlanetSurface.tscn").instantiate()
|
|
root.add_child(surface)
|
|
if not _check_pair(surface, "surface"):
|
|
return true
|
|
surface.queue_free()
|
|
print("both scenes provide non-overlapping 480x350 zones with %.0f-radius rings" \
|
|
% main.get_node("UI/Joystick").max_radius)
|
|
print("TEST_JOYSTICK_RECENTRES: PASS")
|
|
quit(0)
|
|
return true
|
|
|
|
|
|
func _fail(message: String) -> bool:
|
|
print("TEST_JOYSTICK_RECENTRES: FAIL (%s)" % message)
|
|
quit(1)
|
|
return false
|