feat: Implement core game managers for power-ups, UI, goals, and player actions, and establish initial game scene and player.

This commit is contained in:
2025-12-17 03:51:15 +08:00
parent e41ffcfb67
commit 75eb398649
8 changed files with 216 additions and 56 deletions
+69 -11
View File
@@ -62,41 +62,99 @@ func _init_managers():
# Message Bar Configuration
const MAX_MESSAGES := 5
const MESSAGE_DURATION := 3.0
const MESSAGE_DURATION := 4.0
@onready var message_bar: PanelContainer = $MessageBar
@onready var message_container: VBoxContainer = $MessageBar/MarginContainer/MessageContainer
func add_message_to_bar(player_name: String, message: String):
# Message types for different styling
enum MessageType {NORMAL, POWERUP, GOAL, CYCLE, WARNING}
func add_message_to_bar(player_name: String, message: String, type: int = MessageType.NORMAL):
if not message_container:
return
# Create message label
# Create message label with rich styling
var label = Label.new()
label.text = "[%s] %s" % [player_name, message]
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.add_theme_color_override("font_color", Color.WHITE)
label.add_theme_font_size_override("font_size", 14)
label.add_theme_font_size_override("font_size", 16)
label.modulate.a = 0.0 # Start invisible for fade-in
# Style based on message type
var icon = ""
var color = Color.WHITE
match type:
MessageType.POWERUP:
icon = ""
color = Color(0.4, 1.0, 0.4) # Bright green
MessageType.GOAL:
icon = "🎯 "
color = Color(1.0, 0.85, 0.2) # Gold
MessageType.CYCLE:
icon = "⏱️ "
color = Color(0.4, 0.8, 1.0) # Light blue
MessageType.WARNING:
icon = "⚠️ "
color = Color(1.0, 0.5, 0.3) # Orange
_:
icon = "💬 "
color = Color(0.9, 0.9, 0.9) # Light gray
label.text = "%s%s" % [icon, message]
label.add_theme_color_override("font_color", color)
# Add shadow for better visibility
label.add_theme_constant_override("shadow_offset_x", 2)
label.add_theme_constant_override("shadow_offset_y", 2)
label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.7))
# Add to container
message_container.add_child(label)
# Show the message bar
message_bar.visible = true
# Show the message bar with fade
if not message_bar.visible:
message_bar.visible = true
message_bar.modulate.a = 0.0
var bar_tween = create_tween()
bar_tween.tween_property(message_bar, "modulate:a", 1.0, 0.2)
# Animate label entrance (slide in + fade)
label.position.x = -50
var entrance_tween = create_tween()
entrance_tween.set_parallel(true)
entrance_tween.tween_property(label, "modulate:a", 1.0, 0.3)
entrance_tween.tween_property(label, "position:x", 0.0, 0.3).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
# Powerup gets extra pulse effect
if type == MessageType.POWERUP:
await entrance_tween.finished
var pulse_tween = create_tween()
pulse_tween.set_loops(2)
pulse_tween.tween_property(label, "scale", Vector2(1.1, 1.1), 0.15).set_trans(Tween.TRANS_SINE)
pulse_tween.tween_property(label, "scale", Vector2(1.0, 1.0), 0.15).set_trans(Tween.TRANS_SINE)
# Remove oldest messages if over limit
while message_container.get_child_count() > MAX_MESSAGES:
var oldest = message_container.get_child(0)
oldest.queue_free()
# Auto-remove after duration
# Auto-remove after duration with fade-out
await get_tree().create_timer(MESSAGE_DURATION).timeout
if is_instance_valid(label):
label.queue_free()
var exit_tween = create_tween()
exit_tween.set_parallel(true)
exit_tween.tween_property(label, "modulate:a", 0.0, 0.3)
exit_tween.tween_property(label, "position:x", 50.0, 0.3)
await exit_tween.finished
if is_instance_valid(label):
label.queue_free()
# Hide bar when empty
# Hide bar when empty with fade
await get_tree().process_frame
if message_container.get_child_count() == 0:
var hide_tween = create_tween()
hide_tween.tween_property(message_bar, "modulate:a", 0.0, 0.3)
await hide_tween.finished
message_bar.visible = false
@rpc("any_peer", "call_local")