feat: implement PlayerboardManager for handling tile collection, power-up consumption, and grid synchronization.

This commit is contained in:
Yogi Wiguna
2026-03-30 12:21:46 +08:00
parent 37b84f2ab3
commit 52d9b4bffb
14 changed files with 133 additions and 44 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dqdntrjuarixl"
path="res://.godot/imported/gogo_sprite.png-9c7123654645ea9aeba75ebe74a547bf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/vfx/gogo_sprite.png"
dest_files=["res://.godot/imported/gogo_sprite.png-9c7123654645ea9aeba75ebe74a547bf.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.
@@ -1,19 +0,0 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://8ctpkvemgvmt"
path="res://.godot/imported/pick_up_tekton_roaming.mp3-fcbc7bdfbf724091b491495057817c9b.mp3str"
[deps]
source_file="res://assets/sfx/pick_up_tekton_roaming.mp3"
dest_files=["res://.godot/imported/pick_up_tekton_roaming.mp3-fcbc7bdfbf724091b491495057817c9b.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://db4vo6r3kpquq"
path="res://.godot/imported/pick_up_tekton_roaming.wav-8942d5b7e57f38a308199ed30a36e90f.sample"
[deps]
source_file="res://assets/sfx/pick_up_tekton_roaming.wav"
dest_files=["res://.godot/imported/pick_up_tekton_roaming.wav-8942d5b7e57f38a308199ed30a36e90f.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://d2i01ld0puh3m"
path="res://.godot/imported/pick_up_tiles.wav-00c55b444fa0e1c1bc5e092df839b61e.sample"
[deps]
source_file="res://assets/sfx/pick_up_tiles.wav"
dest_files=["res://.godot/imported/pick_up_tiles.wav-00c55b444fa0e1c1bc5e092df839b61e.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
-19
View File
@@ -1,19 +0,0 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://cpgg54uaogaaq"
path="res://.godot/imported/tile_scatter.mp3-73bb39bcbdf43b4782c4b8f6a040f991.mp3str"
[deps]
source_file="res://assets/sfx/tile_scatter.mp3"
dest_files=["res://.godot/imported/tile_scatter.mp3-73bb39bcbdf43b4782c4b8f6a040f991.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://c13vw2lorgv6q"
path="res://.godot/imported/tile_scatter.wav-aa9d8fa0a43423ae0619a49b773da03e.sample"
[deps]
source_file="res://assets/sfx/tile_scatter.wav"
dest_files=["res://.godot/imported/tile_scatter.wav-aa9d8fa0a43423ae0619a49b773da03e.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
+11 -2
View File
@@ -530,9 +530,14 @@ func sync_walk_animation() -> void:
play_walk_animation()
@rpc("any_peer", "call_local", "reliable")
func sync_pickup_animation() -> void:
"""Sync pickup/grab animation across network."""
func sync_pickup_animation(item_id: int = -1) -> void:
"""Sync pickup/grab animation across network and play sound."""
play_pickup_animation()
if item_id >= 11 and item_id <= 14:
SfxManager.play("pick_up_power_tile")
elif item_id >= 7 and item_id <= 10:
SfxManager.play("pick_up_tiles")
@rpc("any_peer", "call_local", "reliable")
func sync_put_animation() -> void:
@@ -875,6 +880,7 @@ func drop_random_item():
# Drop it
playerboard[slot_index] = -1
rpc("sync_playerboard", playerboard)
SfxManager.play("tile_scatter")
# Sync grid item
var cell = Vector3i(drop_pos.x, 1, drop_pos.y)
@@ -906,6 +912,7 @@ func drop_all_tiles():
if dropped_count > 0:
rpc("sync_playerboard", playerboard)
rpc("trigger_screen_shake", "targeted")
SfxManager.play("tile_scatter")
NotificationManager.send_message(self , NotificationManager.MESSAGES.CRITICALLY_HIT, NotificationManager.MessageType.WARNING)
print("Player %s dropped %d tiles due to Super Push" % [name, dropped_count])
@@ -968,6 +975,7 @@ func on_stop_phase_violation():
if main:
main.rpc("sync_grid_item", cell.x, cell.y, cell.z, item_id)
SfxManager.rpc("play_rpc", "tile_scatter")
NotificationManager.send_message(self , "STOP VIOLATION! Tiles scattered!", NotificationManager.MessageType.WARNING)
func _find_multiple_drop_positions(count: int) -> Array:
@@ -2229,6 +2237,7 @@ func sync_grab_tekton(tekton_path: NodePath):
is_attack_mode = false
SfxManager.play("pick_up_tekton_roaming")
play_pickup_animation()
print("[Player %s] Grabbed Tekton %s" % [name, tekton.name])
func throw_tekton():
+10 -4
View File
@@ -82,7 +82,7 @@ func grab_item(grid_position: Vector2i) -> bool:
# Play pickup animation (synced across network)
if player.is_multiplayer_authority() and player.has_method("sync_pickup_animation"):
player.rpc("sync_pickup_animation")
player.rpc("sync_pickup_animation", item)
# === Optimistic Local Update (immediate visual feedback) ===
# Apply changes locally first, server will validate/sync
@@ -95,9 +95,7 @@ func grab_item(grid_position: Vector2i) -> bool:
if special_tiles_manager:
special_tiles_manager.add_powerup_from_item(item)
SfxManager.play("pick_up_power_tile")
# Animation for powerup?
# ...
# Animation and sound handled via sync_pickup_animation RPC above
# Skip adding to playerboard. Just consume.
else:
@@ -311,6 +309,10 @@ func bot_try_grab_item() -> bool:
player.playerboard[empty_slot] = item
# Play pickup animation for bot
if player.has_method("sync_pickup_animation"):
player.rpc("sync_pickup_animation", item)
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
main.rpc("sync_grid_item", current_cell.x, current_cell.y, current_cell.z, -1)
@@ -338,6 +340,10 @@ func bot_try_grab_item() -> bool:
if player.is_multiplayer_authority():
player.playerboard[empty_slot] = item
# Play pickup animation for bot
if player.has_method("sync_pickup_animation"):
player.rpc("sync_pickup_animation", item)
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
main.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)