extends CanvasLayer @onready var content_label = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/TextPanel/ContentLabel @onready var prev_btn = $CenterContainer/PanelContainer/VBoxContainer/Footer/PrevButton @onready var next_btn = $CenterContainer/PanelContainer/VBoxContainer/Footer/NextButton @onready var dots_container = $CenterContainer/PanelContainer/VBoxContainer/Footer/DotsContainer @onready var content_container = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer # Mock Data var pages = [ { "text": "欢迎来到 [color=#3399ff]Datawhale Town[/color]!\n\n这里是开源学习者的家园。在这里,我们一同探索知识,分享成长。\n\n[center]🐋[/center]", # 使用社区图片作为封面 "image_path": "res://assets/sprites/environment/community_512_512.png", "image_color": Color(0.9, 0.9, 0.9) # 保留作为后备选项 }, { "text": "最新活动:\n\n- 镇长刚刚搬进来了,就在喷泉左边。\n- 欢迎板已经设立,查看最新动态。\n- 玩家名字现在显示在头顶了!", # 使用喷泉图片对应"喷泉左边"的描述 "image_path": "res://assets/sprites/environment/fountain_256_192.png", "image_color": Color(0.8, 0.9, 0.8) }, { "text": "操作提示:\n\n- 按 [color=#ffaa00]F[/color] 键可以与物体互动。\n- 在下方输入框输入文字并在气泡中显示。\n- 点击右下角按钮发送聊天。", # 使用公告板图片对应"操作提示" "image_path": "res://assets/sprites/environment/board.png", "image_color": Color(0.9, 0.8, 0.8) } ] var current_page = 0 var tween: Tween var mock_pages = [] func _ready(): # Pause the game get_tree().paused = true $CenterContainer/PanelContainer/VBoxContainer/Header/RightContainer/CloseButton.pressed.connect(_on_close_pressed) prev_btn.pressed.connect(_on_prev_pressed) next_btn.pressed.connect(_on_next_pressed) # Network Integration - Use direct callback for better error handling # Short timeout (2.0s) so mock data appears quickly if server is down NetworkManager.get_request("/notices", _on_notices_response, 2.0) # Initial Setup (with generic "Loading" state) mock_pages = pages.duplicate(true) pages = [{"text": "[center]Loading notices...[/center]", "image_color": Color(0.9, 0.9, 0.9)}] _setup_dots() _update_ui(false) func _on_notices_response(success: bool, data: Dictionary, _error_info: Dictionary): var new_pages = [] if success and data.has("data") and data["data"] is Array: new_pages = data["data"] if new_pages.is_empty(): pages = mock_pages else: pages = new_pages # Handle color strings from JSON if necessary for p in pages: if p.has("image_color") and p["image_color"] is String: p["image_color"] = Color(p["image_color"]) current_page = 0 _setup_dots() _update_ui(true) func _setup_dots(): for child in dots_container.get_children(): child.queue_free() for i in range(pages.size()): var dot = ColorRect.new() dot.custom_minimum_size = Vector2(10, 10) # Base size dots_container.add_child(dot) func _update_ui(animate: bool = true): if pages.is_empty(): return # Update Buttons prev_btn.disabled = (current_page == 0) next_btn.disabled = (current_page == pages.size() - 1) # Update Dots Logic var dots = dots_container.get_children() for i in range(dots.size()): if i == current_page: dots[i].color = Color(0.2, 0.2, 0.2, 1) # Dark Active dots[i].custom_minimum_size = Vector2(12, 12) # Active Slightly Larger else: dots[i].color = Color(0.8, 0.8, 0.8, 1) # Light Inactive dots[i].custom_minimum_size = Vector2(10, 10) # Update Content if animate: _animate_content_change() else: _set_content_immediate() @onready var image_rect = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel/ImageRect @onready var image_label = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel/ImageLabel func _set_content_immediate(): var page = pages[current_page] content_label.text = page.get("text", "") if page.has("image_path") and page["image_path"] != "": var path = page["image_path"] if ResourceLoader.exists(path): image_rect.texture = load(path) image_label.visible = false else: image_rect.texture = null image_label.visible = true image_label.text = "Image Not Found" else: image_rect.texture = null image_label.visible = true image_label.text = "No Image" func _animate_content_change(): if tween and tween.is_valid(): tween.kill() tween = create_tween() # Fade Out tween.tween_property(content_container, "modulate:a", 0.0, 0.15) # Callback to change text tween.tween_callback(self._set_content_immediate) # Fade In tween.tween_property(content_container, "modulate:a", 1.0, 0.15) func _on_prev_pressed(): if current_page > 0: current_page -= 1 _update_ui() func _on_next_pressed(): if current_page < pages.size() - 1: current_page += 1 _update_ui() func _on_close_pressed(): # Unpause the game get_tree().paused = false queue_free()