Files
foxfox/scripts/test_physics.gd

141 lines
4.6 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends Node2D
## Строгий headless-тест механик Этапа 1.
## Сцена: основной пол 800x40 (центр x=0), страховочный пол ниже (y=1000).
## Лиса стартует на (0,300).
var fox: CharacterBody2D
var phase: int = 0
var pt: float = 0.0 # время внутри фазы
var ground_y: float = 0.0
var min_y: float = 99999.0
var results: Array = []
# служебные флаги
var pressed_jump: bool = false
var airborne_at: float = -1.0
var left_ledge: bool = false
func _ready() -> void:
fox = $FoxInstance
func _reset_phase() -> void:
pt = 0.0
min_y = 99999.0
pressed_jump = false
left_ledge = false
airborne_at = -1.0
func _physics_process(delta: float) -> void:
pt += delta
match phase:
0: # ждём приземления
if fox.is_on_floor() and pt > 0.2:
ground_y = fox.position.y
results.append("landing: y=%.1f [OK]" % ground_y)
phase = 1
_reset_phase()
1: # ДЛИННЫЙ прыжок (держим кнопку)
if pt < 0.02:
Input.action_press("jump")
min_y = minf(min_y, fox.position.y)
if pt > 1.4:
Input.action_release("jump")
results.append("long jump rise: %.1f px (теория v^2/2g = 103.3)" % (ground_y - min_y))
phase = 2
_reset_phase()
2: # ждём приземления
if fox.is_on_floor() and pt > 0.3:
phase = 3
_reset_phase()
3: # КОРОТКИЙ прыжок (отпускаем через 0.05с)
if pt < 0.02:
Input.action_press("jump")
if pt > 0.05 and not pressed_jump:
Input.action_release("jump")
pressed_jump = true
min_y = minf(min_y, fox.position.y)
if pt > 1.2:
Input.action_release("jump")
results.append("short jump rise: %.1f px (должен быть заметно меньше длинного)" % (ground_y - min_y))
phase = 4
_reset_phase()
4: # ждём приземления
if fox.is_on_floor() and pt > 0.3:
phase = 5
_reset_phase()
5: # COYOTE TIME: бежим вправо, после схода прыгаем через ~0.05с
Input.action_press("move_right")
Input.action_press("run")
if not fox.is_on_floor() and not left_ledge:
left_ledge = true
airborne_at = 0.0
if left_ledge:
airborne_at += delta
if airborne_at >= 0.05 and not pressed_jump:
Input.action_press("jump")
pressed_jump = true
results.append("coyote: jump нажат через %.3fс после схода" % airborne_at)
phase = 6
_reset_phase()
if pt > 3.0:
results.append("coyote: FAIL — не дошёл до края")
phase = 8
_reset_phase()
6: # проверяем результат coyote-прыжка
if pt > 0.12:
var ok := fox.velocity.y < -100.0
results.append("coyote jump: %s (vel.y=%.0f)" % ["PASS" if ok else "FAIL", fox.velocity.y])
Input.action_release("jump")
phase = 7
_reset_phase()
7: # JUMP BUFFER (детерминированно): один телепорт в воздух, затем jump за ~0.07с до земли
Input.action_release("move_left")
Input.action_release("move_right")
Input.action_release("run")
if not fox.has_meta("tp"):
fox.set_meta("tp", true)
fox.position = Vector2(0.0, ground_y - 120.0)
fox.velocity = Vector2.ZERO
results.append("buffer: лиса телепортирована на y=%.1f, ждём падения" % fox.position.y)
elif not pressed_jump:
var dist: float = maxf(ground_y - fox.position.y, 0.0)
var v: float = maxf(fox.velocity.y, 0.0)
var ttl: float = (-v + sqrt(v * v + 2.0 * 980.0 * dist)) / 980.0
if dist > 0.0 and ttl <= 0.07:
Input.action_press("jump")
pressed_jump = true
results.append("buffer: jump нажат за %.3fс до земли (y=%.1f, vel.y=%.0f)" % [ttl, fox.position.y, v])
if pressed_jump:
if fox.velocity.y < -100.0:
results.append("buffer jump: PASS (vel.y=%.0f — прыжок сработал при касании)" % fox.velocity.y)
Input.action_release("jump")
phase = 8
_reset_phase()
elif pt > 3.0:
results.append("buffer jump: FAIL (vel.y=%.0f, on_floor=%s)" % [fox.velocity.y, fox.is_on_floor()])
Input.action_release("jump")
phase = 8
_reset_phase()
8:
Input.action_release("move_left")
Input.action_release("move_right")
Input.action_release("run")
Input.action_release("jump")
if pt > 0.3:
print("")
print("========== RESULTS: STAGE 1 PHYSICS ==========")
for r in results:
print(" * ", r)
print("==============================================")
get_tree().quit(0)