/
ulupapi
/
Race_game
Обзор
Документация
Войти
/
ulupapi
/
Race_game
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/PitMenu.gd
179 строк
5 KB
ulupapi
Game
26 дек 2025, 19:34
26 дек 2025, 19:34
7574b6d
Код
Авторство
О чём код?
extends Node class_name PitMenu signal closed @export var dim_color: Color = Color(0, 0, 0, 0.55) @export var debug_print: bool = true var _car: Node = null var _left_s: float = 0.0 var _countdown_total: float = 4.0 var _in_countdown: bool = false var _overlay: CanvasLayer = null var _root: Control = null var _dim: ColorRect = null var _panel: PanelContainer = null var _title: Label = null var _count: Label = null var _btn_soft: Button = null var _btn_med: Button = null var _btn_hard: Button = null func _ready() -> void: _ensure_ui() _root.visible = false set_process(false) # безопасный вызов из PitLane func open_for_with_hold(car: Node, hold_seconds_after_choice: float) -> void: _ensure_ui() _car = car if hold_seconds_after_choice < 0.0: hold_seconds_after_choice = 0.0 _countdown_total = hold_seconds_after_choice _in_countdown = false _left_s = 0.0 _title.text = "PIT STOP — Select Tyres" _update_count_label() _hud_set_visible(false) _root.visible = true set_process(true) if debug_print: print("[PitMenu] Open (await choice), hold=", _countdown_total) func open_for(car: Node, hold_seconds_after_choice: float) -> void: open_for_with_hold(car, hold_seconds_after_choice) func close_now() -> void: _ensure_ui() _root.visible = false _hud_set_visible(true) set_process(false) if _car != null and _car.has_method("start_pit_hold"): _car.call("start_pit_hold", 0.05) emit_signal("closed") _car = null _in_countdown = false _left_s = 0.0 if debug_print: print("[PitMenu] Closed") func _on_tyre_pressed(compound: String) -> void: if _car != null and _car.has_method("apply_tyre_choice"): _car.call("apply_tyre_choice", compound) _title.text = "Selected: " + compound _in_countdown = true _left_s = _countdown_total _update_count_label() if debug_print: print("[PitMenu] Tyre chosen: ", compound) func _process(delta: float) -> void: if _root == null or not _root.visible: return if _in_countdown: _left_s -= delta if _left_s < 0.0: _left_s = 0.0 _update_count_label() if _left_s == 0.0: close_now() # ---------- UI ---------- func _ensure_ui() -> void: if _overlay != null and is_instance_valid(_overlay): return if get_tree() == null: return # будет вызвано снова, когда нода войдёт в дерево _overlay = CanvasLayer.new() _overlay.layer = 300 _overlay.process_mode = Node.PROCESS_MODE_ALWAYS get_tree().get_root().add_child(_overlay) _root = Control.new() _root.name = "Root" _root.set_anchors_preset(Control.PRESET_FULL_RECT) _overlay.add_child(_root) _dim = ColorRect.new() _dim.color = dim_color _dim.set_anchors_preset(Control.PRESET_FULL_RECT) _root.add_child(_dim) _panel = PanelContainer.new() _panel.custom_minimum_size = Vector2(520, 320) _panel.anchor_left = 0.5 _panel.anchor_top = 0.5 _panel.anchor_right = 0.5 _panel.anchor_bottom = 0.5 _panel.offset_left = -260 _panel.offset_right = 260 _panel.offset_top = -160 _panel.offset_bottom = 160 _root.add_child(_panel) var pad := MarginContainer.new() pad.add_theme_constant_override("margin_left", 20) pad.add_theme_constant_override("margin_right", 20) pad.add_theme_constant_override("margin_top", 20) pad.add_theme_constant_override("margin_bottom", 20) _panel.add_child(pad) var vb := VBoxContainer.new() vb.grow_vertical = Control.GROW_DIRECTION_BOTH vb.size_flags_vertical = Control.SIZE_EXPAND_FILL vb.alignment = BoxContainer.ALIGNMENT_CENTER pad.add_child(vb) _title = Label.new() _title.text = "PIT STOP — Select Tyres" _title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _title.add_theme_font_size_override("font_size", 28) vb.add_child(_title) _count = Label.new() _count.text = "00.0 s" _count.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _count.add_theme_font_size_override("font_size", 24) vb.add_child(_count) var hb := HBoxContainer.new() hb.size_flags_horizontal = Control.SIZE_EXPAND_FILL hb.alignment = BoxContainer.ALIGNMENT_CENTER vb.add_child(hb) _btn_soft = Button.new() _btn_soft.text = "SOFT" _btn_soft.custom_minimum_size = Vector2(120, 48) hb.add_child(_btn_soft) _btn_med = Button.new() _btn_med.text = "MEDIUM" _btn_med.custom_minimum_size = Vector2(120, 48) hb.add_child(_btn_med) _btn_hard = Button.new() _btn_hard.text = "HARD" _btn_hard.custom_minimum_size = Vector2(120, 48) hb.add_child(_btn_hard) _btn_soft.pressed.connect(Callable(self, "_on_tyre_pressed").bind("Soft")) _btn_med.pressed.connect(Callable(self, "_on_tyre_pressed").bind("Medium")) _btn_hard.pressed.connect(Callable(self, "_on_tyre_pressed").bind("Hard")) func _update_count_label() -> void: if _count == null: return var s_int: int = int(floor(_left_s)) var tenth: int = int(floor((_left_s - float(s_int)) * 10.0)) _count.text = str(s_int) + "." + str(tenth) + " s" # скрыть/показать HUD (оба/несколько HUD должны быть в группе "hud") func _hud_set_visible(v: bool) -> void: var nodes := get_tree().get_nodes_in_group("hud") for n in nodes: if n is CanvasItem: (n as CanvasItem).visible = v