extends CanvasLayer const _VP_W := 1280.0 const _VP_H := 720.0 const _MARGIN := 16.0 const _SFX_PATH := "res://assets/music&sfx/sfx/achievement_unlock.wav" var _font = preload("res://assets/fonts/slkscre.ttf") var _panel: PanelContainer func _ready() -> void: layer = 100 process_mode = Node.PROCESS_MODE_ALWAYS _panel = PanelContainer.new() _panel.custom_minimum_size = Vector2(310.0, 76.0) _panel.mouse_filter = Control.MOUSE_FILTER_IGNORE var style := StyleBoxFlat.new() style.bg_color = Color(0.04, 0.04, 0.12, 0.96) style.border_width_left = 2 style.border_width_top = 2 style.border_width_right = 2 style.border_width_bottom = 2 style.border_color = Color(0.78, 0.62, 0.18, 1.0) style.corner_radius_top_left = 3 style.corner_radius_top_right = 3 style.corner_radius_bottom_right = 3 style.corner_radius_bottom_left = 3 style.content_margin_left = 8.0 style.content_margin_top = 8.0 style.content_margin_right = 12.0 style.content_margin_bottom = 8.0 _panel.add_theme_stylebox_override("panel", style) _panel.position = Vector2(_VP_W + 8.0, _VP_H - 76.0 - _MARGIN) add_child(_panel) func show_unlock(ach: Dictionary) -> void: var hbox := HBoxContainer.new() hbox.add_theme_constant_override("separation", 10) hbox.mouse_filter = Control.MOUSE_FILTER_IGNORE _panel.add_child(hbox) # Icon square var icon_wrap := Control.new() icon_wrap.custom_minimum_size = Vector2(52, 52) icon_wrap.mouse_filter = Control.MOUSE_FILTER_IGNORE hbox.add_child(icon_wrap) var icon_bg := ColorRect.new() icon_bg.color = ach.color icon_bg.mouse_filter = Control.MOUSE_FILTER_IGNORE icon_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) icon_wrap.add_child(icon_bg) var icon_lbl := Label.new() icon_lbl.text = ach.icon_char icon_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER icon_lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER icon_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE icon_lbl.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) icon_lbl.add_theme_font_override("font", _font) icon_lbl.add_theme_font_size_override("font_size", 22) icon_lbl.add_theme_color_override("font_color", Color(1.0, 1.0, 0.88)) icon_lbl.add_theme_color_override("font_outline_color", Color(0.0, 0.0, 0.0, 0.8)) icon_lbl.add_theme_constant_override("outline_size", 2) icon_wrap.add_child(icon_lbl) # Text block var vbox := VBoxContainer.new() vbox.size_flags_vertical = Control.SIZE_SHRINK_CENTER vbox.mouse_filter = Control.MOUSE_FILTER_IGNORE hbox.add_child(vbox) var header := Label.new() header.text = "Achievement Unlocked!" header.mouse_filter = Control.MOUSE_FILTER_IGNORE header.add_theme_font_override("font", _font) header.add_theme_font_size_override("font_size", 13) header.add_theme_color_override("font_color", Color(0.78, 0.62, 0.18, 1.0)) vbox.add_child(header) var title_lbl := Label.new() title_lbl.text = ach.title title_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE title_lbl.add_theme_font_override("font", _font) title_lbl.add_theme_font_size_override("font_size", 20) title_lbl.add_theme_color_override("font_color", Color(1.0, 0.95, 0.8, 1.0)) vbox.add_child(title_lbl) _play_sound() # Wait one frame so the panel has its final size before animating await get_tree().process_frame _animate() func _play_sound() -> void: if not ResourceLoader.exists(_SFX_PATH): return var sfx := AudioStreamPlayer.new() sfx.stream = load(_SFX_PATH) sfx.volume_db = -2.0 sfx.process_mode = Node.PROCESS_MODE_ALWAYS add_child(sfx) sfx.play() sfx.finished.connect(sfx.queue_free) func _animate() -> void: var pw := _panel.size.x var target_x := _VP_W - pw - _MARGIN _panel.position.x = _VP_W + 8.0 var tween := create_tween() tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS) tween.tween_property(_panel, "position:x", target_x, 0.4)\ .set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUART) tween.tween_interval(3.5) tween.tween_property(_panel, "position:x", _VP_W + 8.0, 0.3)\ .set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_QUART) tween.tween_callback(queue_free)