Add and update name convention
Some checks failed
Some checks failed
This commit is contained in:
143
scenes/game/gameplays/Match3SaveManager.gd
Normal file
143
scenes/game/gameplays/Match3SaveManager.gd
Normal file
@@ -0,0 +1,143 @@
|
||||
class_name Match3SaveManager
|
||||
extends RefCounted
|
||||
|
||||
## Save/Load manager for Match3 gameplay state
|
||||
##
|
||||
## Handles serialization and deserialization of Match3 game state.
|
||||
## Converts game objects to data structures for storage and restoration.
|
||||
##
|
||||
## Usage:
|
||||
## # Save current state
|
||||
## var grid_data = Match3SaveManager.serialize_grid_state(game_grid, grid_size)
|
||||
##
|
||||
## # Restore previous state
|
||||
## var success = Match3SaveManager.deserialize_grid_state(grid_data, game_grid, grid_size)
|
||||
|
||||
|
||||
static func serialize_grid_state(grid: Array, grid_size: Vector2i) -> Array:
|
||||
## Convert the current game grid to a serializable 2D array of tile types.
|
||||
##
|
||||
## Extracts the tile_type property from each tile node and creates a 2D array
|
||||
## that can be saved to disk. Invalid or missing tiles are represented as -1.
|
||||
##
|
||||
## Args:
|
||||
## grid: The current game grid (2D array of tile nodes)
|
||||
## grid_size: Dimensions of the grid to serialize
|
||||
##
|
||||
## Returns:
|
||||
## Array: 2D array where each element is either a tile type (int) or -1 for empty
|
||||
var serialized_grid = []
|
||||
var valid_tiles = 0
|
||||
var null_tiles = 0
|
||||
|
||||
for y in range(grid_size.y):
|
||||
var row = []
|
||||
for x in range(grid_size.x):
|
||||
if y < grid.size() and x < grid[y].size() and grid[y][x]:
|
||||
row.append(grid[y][x].tile_type)
|
||||
valid_tiles += 1
|
||||
else:
|
||||
row.append(-1) # Invalid/empty tile
|
||||
null_tiles += 1
|
||||
serialized_grid.append(row)
|
||||
|
||||
DebugManager.log_info(
|
||||
(
|
||||
"Serialized grid state: %dx%d grid, %d valid tiles, %d null tiles"
|
||||
% [grid_size.x, grid_size.y, valid_tiles, null_tiles]
|
||||
),
|
||||
"Match3"
|
||||
)
|
||||
return serialized_grid
|
||||
|
||||
|
||||
static func get_active_gem_types_from_grid(grid: Array, tile_types: int) -> Array:
|
||||
# Get active gem types from the first available tile
|
||||
if grid.size() > 0 and grid[0].size() > 0 and grid[0][0]:
|
||||
return grid[0][0].active_gem_types.duplicate()
|
||||
|
||||
# Fallback to default
|
||||
var default_types = []
|
||||
for i in range(tile_types):
|
||||
default_types.append(i)
|
||||
return default_types
|
||||
|
||||
|
||||
static func save_game_state(grid: Array, grid_size: Vector2i, tile_types: int):
|
||||
# Save complete game state
|
||||
var grid_layout = serialize_grid_state(grid, grid_size)
|
||||
var active_gems = get_active_gem_types_from_grid(grid, tile_types)
|
||||
|
||||
DebugManager.log_info(
|
||||
(
|
||||
"Saving match3 state: size(%d,%d), %d tile types, %d active gems"
|
||||
% [grid_size.x, grid_size.y, tile_types, active_gems.size()]
|
||||
),
|
||||
"Match3"
|
||||
)
|
||||
|
||||
SaveManager.save_grid_state(grid_size, tile_types, active_gems, grid_layout)
|
||||
|
||||
|
||||
static func restore_grid_from_layout(
|
||||
match3_node: Node2D,
|
||||
grid_layout: Array,
|
||||
active_gems: Array[int],
|
||||
grid_size: Vector2i,
|
||||
tile_scene: PackedScene,
|
||||
grid_offset: Vector2,
|
||||
tile_size: float,
|
||||
tile_types: int
|
||||
) -> Array[Array]:
|
||||
# Clear ALL existing tile children
|
||||
var all_tile_children = []
|
||||
for child in match3_node.get_children():
|
||||
if child.has_method("get_script") and child.get_script():
|
||||
var script_path = child.get_script().resource_path
|
||||
if script_path == "res://scenes/game/gameplays/tile.gd":
|
||||
all_tile_children.append(child)
|
||||
|
||||
# Remove all found tile children
|
||||
for child in all_tile_children:
|
||||
child.queue_free()
|
||||
|
||||
# Wait for nodes to be freed
|
||||
await match3_node.get_tree().process_frame
|
||||
|
||||
# Create new grid
|
||||
var new_grid: Array[Array] = []
|
||||
for y in range(grid_size.y):
|
||||
new_grid.append(Array([]))
|
||||
for x in range(grid_size.x):
|
||||
var tile = tile_scene.instantiate()
|
||||
var tile_position = grid_offset + Vector2(x, y) * tile_size
|
||||
tile.position = tile_position
|
||||
tile.grid_position = Vector2i(x, y)
|
||||
|
||||
match3_node.add_child(tile)
|
||||
|
||||
# Configure Area2D
|
||||
tile.monitoring = true
|
||||
tile.monitorable = true
|
||||
tile.input_pickable = true
|
||||
|
||||
tile.set_tile_size(tile_size)
|
||||
tile.set_active_gem_types(active_gems)
|
||||
|
||||
# Set the saved tile type
|
||||
var saved_tile_type = grid_layout[y][x]
|
||||
if saved_tile_type >= 0 and saved_tile_type < tile_types:
|
||||
tile.tile_type = saved_tile_type
|
||||
else:
|
||||
tile.tile_type = randi() % tile_types
|
||||
|
||||
# Connect tile signals
|
||||
if tile.has_signal("tile_selected") and match3_node.has_method("_on_tile_selected"):
|
||||
tile.tile_selected.connect(match3_node._on_tile_selected)
|
||||
if tile.has_signal("tile_hovered") and match3_node.has_method("_on_tile_hovered"):
|
||||
tile.tile_hovered.connect(match3_node._on_tile_hovered)
|
||||
tile.tile_unhovered.connect(match3_node._on_tile_unhovered)
|
||||
|
||||
new_grid[y].append(tile)
|
||||
|
||||
return new_grid
|
||||
Reference in New Issue
Block a user