feat: Introduce player movement manager with push mechanics, multiplayer synchronization, and new touch controls and powerup inventory UI.

This commit is contained in:
Yogi Wiguna
2026-03-10 11:05:14 +08:00
parent aaf246d873
commit da7192ac07
3 changed files with 39 additions and 16 deletions
+15 -9
View File
@@ -166,6 +166,21 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
player.sync_bump(target_pos, true) player.sync_bump(target_pos, true)
return false return false
# SAFE ZONE PROTECTION (Only in Stop n Go)
if LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO):
var safe_columns = [6, 7, 8, 14, 15, 16]
# 1. Prevent attacker from attacking IF THEY ARE in a Safe Zone
if player.current_position.x in safe_columns:
print(" - Attack BLOCKED: Attacker is in Safe Zone!")
NotificationManager.send_message(player, "Cannot Attack while in Safe Zone!", NotificationManager.MessageType.WARNING)
return false
# 2. Prevent attacking players WHO ARE in a Safe Zone (existing logic)
if target_pos.x in safe_columns:
print(" - Attack BLOCKED: Target is in Safe Zone!")
NotificationManager.send_message(player, "Target is in Safe Zone!", NotificationManager.MessageType.WARNING)
return false
# === SUPER PUSH (Attack Mode) === # === SUPER PUSH (Attack Mode) ===
print("Player %s SUPER PUSHING %s!" % [player.name, other_player.name]) print("Player %s SUPER PUSHING %s!" % [player.name, other_player.name])
@@ -175,15 +190,6 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
elif player.has_method("sync_bump"): elif player.has_method("sync_bump"):
player.sync_bump(target_pos, false) player.sync_bump(target_pos, false)
# SAFE ZONE PROTECTION (Only in Stop n Go)
if LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO):
# Columns 6, 7, 8 and 14, 15, 16 are Safe Zones
var safe_columns = [6, 7, 8, 14, 15, 16]
if target_pos.x in safe_columns:
print(" - Attack BLOCKED by Safe Zone!")
NotificationManager.send_message(player, "Cannot Attack in Safe Zone!", NotificationManager.MessageType.WARNING)
return false
# 1. 3-Floor Knockback towards Starting Line (X=0) # 1. 3-Floor Knockback towards Starting Line (X=0)
var push_direction = Vector2i(-1, 0) # Backwards var push_direction = Vector2i(-1, 0) # Backwards
var pushed_to_pos = target_pos var pushed_to_pos = target_pos
+11 -2
View File
@@ -128,6 +128,10 @@ func _create_touch_ui():
else: else:
print("[TouchControls] Found existing ActionsBtn container") print("[TouchControls] Found existing ActionsBtn container")
# Center buttons in the container instead of spreading them out
if actions_container is BoxContainer:
actions_container.alignment = BoxContainer.ALIGNMENT_CENTER
# Create action buttons (parented to actions_container if possible, or use logic) # Create action buttons (parented to actions_container if possible, or use logic)
# User Request: "move those button to ActionsBtn children" # User Request: "move those button to ActionsBtn children"
@@ -249,6 +253,11 @@ func _style_button(btn: Button, opacity: float):
# Prevent buttons from stealing focus (fixes Spacebar activation) # Prevent buttons from stealing focus (fixes Spacebar activation)
btn.focus_mode = Control.FOCUS_NONE btn.focus_mode = Control.FOCUS_NONE
# Fix "Floating" issue: don't expand button to fill whole container height
# This keeps the button (and its labels) centered near the icon/text
btn.size_flags_vertical = Control.SIZE_SHRINK_CENTER
btn.custom_minimum_size.y = 70 # Consistent height
func _ensure_shortcut_label(btn: Button, button_name: String): func _ensure_shortcut_label(btn: Button, button_name: String):
if btn.has_node("ShortcutLabel"): if btn.has_node("ShortcutLabel"):
# Update Label content if it exists to match potential remapping # Update Label content if it exists to match potential remapping
@@ -265,7 +274,7 @@ func _ensure_shortcut_label(btn: Button, button_name: String):
# Ensure correct placement (Top Right) # Ensure correct placement (Top Right)
existing_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT existing_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
existing_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP existing_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP
existing_lbl.offset_top = -5 # Closer to top existing_lbl.offset_top = -8 # Lowered slightly from -18
existing_lbl.offset_right = 0 # Aligned with right edge existing_lbl.offset_right = 0 # Aligned with right edge
# Ensure Outline # Ensure Outline
@@ -279,7 +288,7 @@ func _ensure_shortcut_label(btn: Button, button_name: String):
shortcut_lbl.set_anchors_preset(Control.PRESET_FULL_RECT) shortcut_lbl.set_anchors_preset(Control.PRESET_FULL_RECT)
shortcut_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT shortcut_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
shortcut_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP shortcut_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP
shortcut_lbl.offset_top = -5 # Closer to top shortcut_lbl.offset_top = -8 # Lowered slightly from -18
shortcut_lbl.offset_right = 0 # Aligned with right edge shortcut_lbl.offset_right = 0 # Aligned with right edge
shortcut_lbl.add_theme_font_size_override("font_size", 16) shortcut_lbl.add_theme_font_size_override("font_size", 16)
shortcut_lbl.add_theme_color_override("font_outline_color", Color.BLACK) shortcut_lbl.add_theme_color_override("font_outline_color", Color.BLACK)
+13 -5
View File
@@ -17,9 +17,12 @@ func _ready():
# We try to get them immediately. If they are children, they should be accessible. # We try to get them immediately. If they are children, they should be accessible.
var container = get_node_or_null("Container") var container = get_node_or_null("Container")
if not container: if not container:
print("[PowerUpUI] ERROR: HBoxContainer not found in ", get_path()) print("[PowerUpUI] ERROR: Container not found in ", get_path())
return return
# Center buttons in the container instead of spreading them out
container.alignment = BoxContainer.ALIGNMENT_CENTER
# Mapping based on User Request # Mapping based on User Request
# 11: FASTER_SPEED (0) -> SpeedBtn # 11: FASTER_SPEED (0) -> SpeedBtn
# 12: AREA_FREEZE (1) -> FreezeAreaBtn # 12: AREA_FREEZE (1) -> FreezeAreaBtn
@@ -65,6 +68,11 @@ func _setup_btn(effect_id: int, btn: Button):
btn.modulate = Color(0.5, 0.5, 0.5, 0.5) # Grayed out btn.modulate = Color(0.5, 0.5, 0.5, 0.5) # Grayed out
btn.focus_mode = Control.FOCUS_NONE btn.focus_mode = Control.FOCUS_NONE
# Fix "Floating" issue: don't expand button to fill whole container height
# This keeps the buttons grouped tightly together
btn.size_flags_vertical = Control.SIZE_SHRINK_CENTER
btn.custom_minimum_size.y = 80 # Consistent height
# Add Level Label # Add Level Label
if not btn.has_node("LevelLabel"): if not btn.has_node("LevelLabel"):
var lvl_lbl = Label.new() var lvl_lbl = Label.new()
@@ -100,9 +108,9 @@ func _setup_btn(effect_id: int, btn: Button):
sc_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE sc_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE
sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
sc_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP sc_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP
sc_lbl.set_anchors_preset(Control.PRESET_TOP_LEFT) sc_lbl.set_anchors_preset(Control.PRESET_FULL_RECT)
sc_lbl.offset_left = 0 sc_lbl.offset_left = 5
sc_lbl.offset_top = -5 sc_lbl.offset_top = -4 # Lowered slightly from -12
sc_lbl.add_theme_font_size_override("font_size", 16) sc_lbl.add_theme_font_size_override("font_size", 16)
sc_lbl.add_theme_color_override("font_outline_color", Color.BLACK) sc_lbl.add_theme_color_override("font_outline_color", Color.BLACK)
sc_lbl.add_theme_constant_override("outline_size", 4) sc_lbl.add_theme_constant_override("outline_size", 4)
@@ -185,7 +193,7 @@ func _connect_special_manager(special_manager):
# Initial State Sync # Initial State Sync
if icon_containers.is_empty(): if icon_containers.is_empty():
print("[PowerUpUI] Warning: Icon containers empty during setup. Attempting _ready logic now...") print("[PowerUpUI] Warning: Icon containers empty during setup. Attempting _ready logic now...")
var container = get_node_or_null("HBoxContainer") var container = get_node_or_null("Container")
if container: if container:
# Fix: Use correct IDs 0-3 here too # Fix: Use correct IDs 0-3 here too
_setup_btn(0, container.get_node_or_null("SpeedBtn")) _setup_btn(0, container.get_node_or_null("SpeedBtn"))