Files
my-world/tools/test/parkour_gaps.gd
T
aibrashandClaude Sonnet 5.5 556d3af615 README: заметки для будущего меня; тестовые сцены в tools/test
- Договорённости с владельцем, замеры мувсета (стенами высоту не набрать), исправление
  подтягивания, конвейер Parkour и его грабли, ловушка с ресурсами, загружаемыми по строке
- tools/test: measure_movement, mantle_test, parkour_gaps, parkour_tour, parkour_check.txt

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxZo3ekR5m1af437Qzqwc1
2026-10-28 15:05:29 +05:00

69 lines
3.6 KiB
GDScript

extends Node
# Проходимость пропасти контейнеров на настоящей карте Parkour: прыжок у края, двойной прыжок на спуске, подруливание к цели.
# Запуск: godot --headless --path . res://tools/test/parkour_gaps.tscn -- --client (ожидание: все зазоры «ДА»)
# Стартовые точки заданы в коде — после правки layout.py обнови их
var level
var p
var f := 0
# (имя, x, z_старта(центр), z_края, ожидаемая посадка z-диапазон, высота пола)
var cases := [
["k0->k1 (18 м)", 4.0, -465.0, -475.0, 45.0],
["k2->k3 (22 м)", 2.0, -544.0, -549.0, 48.0] ,
]
func _ready() -> void:
level = (load("res://maps/parkour/parkour.tscn") as PackedScene).instantiate()
add_child(level)
p = level.get_node("Player")
p.set_physics_process(false)
await get_tree().physics_frame
for variant in ["dj", "dash+dj"]:
# имя, x старта, пол старта, z старта, z края, пол цели, z цели ближний, дальний, x цели
for c in [
["exit->k1 18", 4.0, 44.0, -446.0, -457.7, 45.0, -476.0, -488.0, 5.0],
["k1->k2 16", 0.0, 45.0, -479.0, -487.7, 46.5, -504.0, -516.0, -4.0],
["k2->k3 22", -2.5, 46.5, -507.0, -515.7, 48.0, -538.0, -550.0, -2.5],
["k3->k4 24", 7.0, 48.0, -541.0, -549.7, 49.0, -574.0, -586.0, 7.5],
["k4->k5 20", 7.0, 49.0, -577.0, -585.7, 50.5, -606.0, -618.0, 2.0],
["k5->k6 22", 2.0, 50.5, -609.0, -617.7, 52.0, -640.0, -656.0, 0.0]]:
await trial(c, variant)
get_tree().quit()
func key(a: String, down: bool) -> void:
if down: Input.action_press(a)
else: Input.action_release(a)
func trial(c: Array, variant: String) -> void:
p.set_physics_process(true)
p.global_position = Vector3(c[1], c[2] + 1.18, c[3])
p.velocity = Vector3.ZERO
p.is_dead = false
await get_tree().physics_frame
key("move_forward", true); key("sprint", true)
var fr := 0; var jumped := false; var did := 0; var res := "промах"
while fr < 360:
await get_tree().physics_frame; fr += 1
if not jumped and p.is_on_floor() and p.global_position.z < c[4] + 1.0 and fr > 20:
jumped = true; key("jump", true); did = 0
if jumped and not p.is_on_floor(): # подруливание к центру цели
var dx: float = c[8] - p.global_position.x
key("move_left", dx < -0.6); key("move_right", dx > 0.6)
if jumped and did == 0 and not p.is_on_floor() and p.velocity.y < 0.0:
did = fr
if variant == "dj" or variant == "dj+dash": key("jump", false); await get_tree().physics_frame; key("jump", true)
if variant == "dash+dj":
var e := InputEventAction.new(); e.action = "dash"; e.pressed = true; Input.parse_input_event(e)
if jumped and did > 0 and variant == "dj+dash" and fr == did + 8:
var e2 := InputEventAction.new(); e2.action = "dash"; e2.pressed = true; Input.parse_input_event(e2)
if jumped and did > 0 and variant == "dash+dj" and fr == did + 14:
key("jump", false); await get_tree().physics_frame; key("jump", true)
if jumped and fr > did + 25 and did > 0 and p.is_on_floor():
var z: float = p.global_position.z
if z < c[6] + 0.5 and z > c[7] - 0.5 and absf(p.global_position.y - (c[5] + 1.16)) < 0.3:
res = "ДА (z=%.1f)" % z
else:
res = "упал/на старте (z=%.1f y=%.1f)" % [z, p.global_position.y]
break
if p.global_position.y < c[2] - 25.0:
res = "упал вниз"; break
for a in ["move_forward","sprint","jump","move_left","move_right"]: key(a, false)
print("%-8s %-10s %s" % [variant, c[0], res])
p.set_physics_process(false)