Files
my-world/tools/test/ui_tour.gd
T
aibrashandClaude Sonnet 5.5 666bebfb60 Ники, общий рейтинг (топ-10 по картам), таблица Tab, сдача в гонке, таймер Parkour
- Ники: профиль user://profile.cfg (client_id + ник), панель при первом запуске и по N;
  Net.nick_of(id); ники над призраками, в HUD/итогах гонки и таблицах
- Рейтинг на сервере: лучшее время каждого игрока по картам race/parkour/metro, топ-10,
  user://leaderboard.json (атомарная запись, лимиты, проверка карты/комнаты/времени)
- Таблица лидеров по Tab, доски топ-3 над порталами в хабе, итоги гонки с общим рейтингом
- Гонка: сдача (G, удержание 1,5 с), RACE_GIVEUP; Parkour: таймер, финиш на вершине, R — перезапуск
- Новые RPC (submit_profile, recv_nick, submit_record, recv_record_result, request_leaderboard,
  recv_leaderboard): клиент и сервер выкладываются вместе
- Тесты: nicks_lb_test, race_giveup_test, parkour_run_test, nick_ui_test, ui_tour; README обновлён

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

109 lines
4.4 KiB
GDScript
Raw 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 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.boards["metro"] = {"top": [], "my_rank": 0, "my_time": 0.0, "tick": 0}
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()