extends Node # Кадры интерфейса ников и рейтинга для проверки глазами (окно мелькнёт; кадры пишет Godot через --write-movie). # Рейтинг подставляется «из головы» (сервер не нужен). Режимы: # --mode=hub доски над порталами (кадр ~20), панель ника (~40), таблица с вкладками (~65, ~85) # --mode=race HUD с индикатором сдачи (кадры 10..25), итоги с рейтингом (~50), таблица Tab поверх (~70) # --mode=parkour таймер (~20), итоги забега (~40), таблица Tab (~125) # Запуск (кадры a00000040.png и т. д.): # godot --path . --resolution 1152x648 --fixed-fps 10 --write-movie /tmp/shots/hub.png --quit-after 100 res://tools/test/ui_tour.tscn -- --client --mode=hub --profile=/tmp/shots/prof.cfg --server-url=ws://127.0.0.1:1 var mode := "hub" var level var p var frame := 0 func fake_board(rank: int, with_me: bool) -> Dictionary: var names := ["Алиса", "Bob [b]жирный", "Мир", "Zed", "Игрок 417", "Кирилл_К", "NightRunner", "Тень", "ab", "Макс"] var top := [] for i in 10: top.append([names[i], 52.318 + i * 1.7321, 0]) return {"top": top, "my_rank": rank, "my_time": 52.318 + (rank - 1) * 1.7321 if rank <= 10 else 71.456, "tick": Time.get_ticks_msec()} func _ready() -> void: for a in OS.get_cmdline_user_args(): if a.begins_with("--mode="): mode = a.substr(7) Net.my_nick = "Мир" Net.nick_asked = true Net.boards["race"] = fake_board(3, true) Net.boards["parkour"] = fake_board(14, true) Net.boards["parkour"].top = Net.boards["parkour"].top.slice(0, 10) Net.nicks[111] = "Алиса" Net.nicks[222] = "Bob [b]жирный" Net.nicks[333] = "Тень" var scene: String = {"hub": "res://maps/hub/hub.tscn", "race": "res://maps/race/race.tscn", "parkour": "res://maps/parkour/parkour.tscn"}[mode] level = (load(scene) as PackedScene).instantiate() add_child(level) p = level.get_node("Player") if mode == "hub": Net.current_map = "hub" p.set_physics_process(false) p.global_position = Vector3(0, 1.2, 0.5) p.head.rotation.x = deg_to_rad(21) # доски в хабе: подставляем топ вручную (сервера нет) level._on_board_updated("race") level._on_board_updated("parkour") else: p.set_physics_process(false) func _process(_d: float) -> void: frame += 1 match mode: "hub": _hub() "race": _race() "parkour": _parkour() func _hub() -> void: if frame == 35: Overlay.open_nick(true) Overlay._edit.text = "Алиса" Overlay._edit.caret_column = 5 if frame == 55: Overlay._nick_layer.visible = false # (настоящее закрытие захватило бы мышь окна) Overlay.nick_open = false Net.input_blocked = false if frame == 60: Overlay.open_lb() if frame == 80: Overlay._lb_index = 1 Overlay._lb_refresh() func _race() -> void: var rules = level.get_node("Rules") if frame == 3: var now := Time.get_ticks_msec() rules.participants = [rules.my_id] rules.passed = {rules.my_id: 3} rules.start_tick = now - 31000 rules.phase = rules.Phase.RACE Input.action_press("giveup") if frame == 28: Input.action_release("giveup") if frame == 40: # итоги: эксперимент вне _process правил (иначе вымышленные игроки «выйдут») rules.set_process(false) rules.set_physics_process(false) rules.participants = [111, 222, 333, rules.my_id] rules.finish = {111: 52.318, rules.my_id: 55.78} rules.gave_up = {333: true} rules.passed = {111: 8, 222: 5, 333: 2, rules.my_id: 8} Net.last_record["race"] = {"time": 55.78, "rank": 3, "personal": true, "map_record": false} rules._end_race() rules._timer_label.visible = false rules._giveup_label.visible = false if frame == 70: Overlay.open_lb() func _parkour() -> void: if frame == 5: p.global_position = Vector3(0, 1.25, -20) level.run_active = true level.run_start_tick = Time.get_ticks_msec() - 23400 level._hud_timer = 0.0 if frame == 30: level.run_time = 47.512 level._finish_run() Net.last_record["parkour"] = {"time": 47.512, "rank": 14, "personal": true, "map_record": false} level._show_results() if frame == 125: Overlay.open_lb()