extends Node # Облёт карты Race для скриншотов (окно мелькнёт; кадры пишет Godot через --write-movie). # --mode=gates (по умолчанию): телепорт игрока к воротам и видам трассы, смотрит вдоль трассы # --mode=hud: «жмёт R», ждёт отсчёт, пробегает ворота (телепортом перед воротами + шаг вперёд), финиш, итоги # Запуск: # godot --path . --resolution 1152x648 --fixed-fps 10 --write-movie /tmp/shots/r.png --quit-after 60 res://tools/test/race_tour.tscn -- --client # godot --path . --resolution 1152x648 --fixed-fps 10 --write-movie /tmp/shots/h.png --quit-after 260 res://tools/test/race_tour.tscn -- --client --mode=hud --race-best=/tmp/shots/best.cfg const Data = preload("res://maps/race/race_data.gd") var level var p var frame := 0 var mode := "gates" var gate := 0 # (позиция центра капсулы, рыскание°, наклон°) — виды вдоль трассы var spots := [ [Vector3(0, 1.25, -20), 0, 4], [Vector3(0, 1.25, -70), 0, 4], [Vector3(0, 5.7, -100), 0, 4], [Vector3(40, 5.7, -195), -90, 4], [Vector3(120, 5.2, -195), -90, 4], [Vector3(163, 0.4, -290), 0, 4], [Vector3(162, -5.7, -350), 0, 4], [Vector3(161, -5.7, -420), 0, 4], [Vector3(161, -5.7, -470), 0, 4], [Vector3(161, -6.7, -495), 180, 4], ] func _ready() -> void: for a in OS.get_cmdline_user_args(): if a.begins_with("--mode="): mode = a.substr(7) level = (load("res://maps/race/race.tscn") as PackedScene).instantiate() add_child(level) p = level.get_node("Player") if mode == "gates": p.set_physics_process(false) func _process(_d: float) -> void: frame += 1 if mode == "gates": var i := int(frame / 5) if i < spots.size() and frame % 5 == 1: var s = spots[i] p.global_position = s[0] p.rotation.y = deg_to_rad(s[1]) p.head.rotation.x = deg_to_rad(s[2]) return var rules = level.get_node("Rules") if frame == 8: rules.toggle_ready() # после старта: каждые 25 кадров ставим игрока за 4 м до очередных ворот лицом вперёд и бежим if rules.phase == 2 and not rules.finish.has(rules.my_id) and frame % 25 == 0: var g: int = rules.passed.get(rules.my_id, 0) if g < Data.CHECKPOINTS.size(): var gp: Vector3 = Data.CHECKPOINTS[g][0] var yaw := deg_to_rad(Data.CHECKPOINTS[g][2]) if g < 6: p.global_position = gp - Vector3(-sin(yaw), 0, -cos(yaw)) * 6.0 p.rotation.y = yaw p.velocity = Vector3.ZERO Input.action_press("move_forward") Input.action_press("sprint") else: # дальше просто засчитываем ворота (облёт проверяет только HUD; проход трассы — в race_game_test) Input.action_release("move_forward") Input.action_release("sprint") p.global_position = gp rules._pass_gate(g)