extends Control class_name HUDLayer ## 스트립 왼쪽 위에 붙는 한 줄짜리 정보 바와 짧은 알림. ## 스트립은 화면에 도킹되므로 창을 끌어 옮기는 기능은 없다. 위치는 메뉴에서 바꾼다. signal shop_pressed signal menu_pressed @onready var control_bar: PanelContainer = $ControlBar @onready var bubbles_label: Label = %BubblesLabel @onready var bps_label: Label = %BpsLabel @onready var beauty_label: Label = %BeautyLabel @onready var zone_label: Label = %ZoneLabel @onready var shop_button: Button = %ShopButton @onready var menu_button: Button = %MenuButton @onready var toast: Label = %Toast @onready var trash: PanelContainer = %Trash @onready var trash_label: Label = %TrashLabel var _toast_tween: Tween func _ready() -> void: control_bar.add_theme_stylebox_override("panel", UIStyle.panel(UIStyle.PANEL_BG, 12)) UIStyle.label(bubbles_label, 24, UIStyle.INK) UIStyle.label(bps_label, 13, UIStyle.INK_DIM) UIStyle.label(beauty_label, 13, UIStyle.GOLD) UIStyle.label(zone_label, 13, UIStyle.ACCENT) UIStyle.label(toast, 14, UIStyle.INK) toast.modulate.a = 0.0 trash.add_theme_stylebox_override("panel", UIStyle.panel(Color(0.35, 0.06, 0.10, 0.88), 12)) UIStyle.label(trash_label, 13, UIStyle.INK) trash.hide() UIStyle.style_button(shop_button) UIStyle.style_button(menu_button) shop_button.pressed.connect(func(): shop_pressed.emit()) menu_button.pressed.connect(func(): menu_pressed.emit()) GameState.zone_unlocked.connect(func(_i: int): _refresh_zone_label()) GameState.state_changed.connect(_refresh_zone_label) GameState.reloaded.connect(_refresh_zone_label) SaveManager.offline_earned.connect(_on_offline_earned) _refresh_zone_label() func _process(_delta: float) -> void: bubbles_label.text = NumberFormat.short(GameState.bubbles) bps_label.text = "초당 %s" % NumberFormat.short(GameState.bps) beauty_label.text = "아름다움 %s · x%.2f" % [ NumberFormat.short(GameState.beauty), GameState.beauty_mult ] ## 몇 개 구역을 열었고 다음은 무엇인지. 해금 조건 자체는 잠긴 구역 위에 직접 표시된다. func _refresh_zone_label() -> void: var opened := GameState.unlocked_zones var total := Catalog.zone_count() if not GameState.has_next_zone(): zone_label.text = "구역 %d/%d · 모두 열었어요" % [opened, total] return var next_zone := Catalog.zone(GameState.next_zone_index()) zone_label.text = "구역 %d/%d · 다음 %s %s" % [ opened, total, next_zone.name, NumberFormat.short(GameState.next_zone_cost()) ] func _on_offline_earned(amount: float, seconds: int) -> void: show_toast("%s 동안 거품 %s를 모았어요" % [ NumberFormat.duration(seconds), NumberFormat.short(amount) ], 4.5) func show_toast(text: String, duration := 2.0) -> void: toast.text = text if _toast_tween and _toast_tween.is_valid(): _toast_tween.kill() _toast_tween = create_tween() _toast_tween.tween_property(toast, "modulate:a", 1.0, 0.2) _toast_tween.tween_interval(duration) _toast_tween.tween_property(toast, "modulate:a", 0.0, 0.5) ## 클릭했을 때 얻은 양이 위로 떠오르는 숫자. func float_number(at: Vector2, amount: float) -> void: var l := Label.new() add_child(l) l.text = "+%s" % NumberFormat.short(amount) UIStyle.label(l, 15, UIStyle.ACCENT) l.position = at - Vector2(14, 10) l.mouse_filter = Control.MOUSE_FILTER_IGNORE var t := create_tween().set_parallel(true) t.tween_property(l, "position:y", l.position.y - 42.0, 0.9) \ .set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) t.tween_property(l, "modulate:a", 0.0, 0.9) t.chain().tween_callback(l.queue_free) ## 무언가를 집어 든 동안만 휴지통을 보여준다. 평소에는 자리를 차지하지 않는다. func set_trash_visible(on: bool) -> void: trash.visible = on ## 휴지통의 사각형. HUD와 바다가 같은 좌표계(Main의 전체 영역)를 쓰므로 그대로 넘길 수 있다. func trash_area() -> Rect2: return Rect2(trash.position, trash.size)