add basic match3 logic

use proper logging everywhere
add gamepad and keyboard control on match3 gameplay
This commit is contained in:
2025-09-24 16:58:08 +04:00
parent e76297b3f3
commit bbf512b675
14 changed files with 466 additions and 63 deletions

View File

@@ -1,7 +1,12 @@
extends Node2D
signal tile_selected(tile: Node2D)
@export var tile_type: int = 0 : set = _set_tile_type
var grid_position: Vector2i
var is_selected: bool = false : set = _set_selected
var is_highlighted: bool = false : set = _set_highlighted
var original_scale: Vector2 = Vector2.ONE # Store the original scale for the board
@onready var sprite: Sprite2D = $Sprite2D
@@ -28,7 +33,6 @@ var active_gem_types = [] # Will be set from current_gem_pool
func _set_tile_type(value: int) -> void:
tile_type = value
print("Debug: _set_tile_type called with value ", value, ", active_gem_types.size() = ", active_gem_types.size())
# Fixed: Add sprite null check to prevent crashes during initialization
if not sprite:
return
@@ -38,7 +42,7 @@ func _set_tile_type(value: int) -> void:
# print("Debug: Set texture_index ", texture_index, " for tile_type ", value)
_scale_sprite_to_fit()
else:
push_error("Invalid tile type: " + str(value) + ". Available types: 0-" + str(active_gem_types.size() - 1))
DebugManager.log_error("Invalid tile type: " + str(value) + ". Available types: 0-" + str(active_gem_types.size() - 1), "Match3")
func _scale_sprite_to_fit() -> void:
# Fixed: Add additional null checks
@@ -46,7 +50,9 @@ func _scale_sprite_to_fit() -> void:
var texture_size = sprite.texture.get_size()
var max_dimension = max(texture_size.x, texture_size.y)
var scale_factor = TILE_SIZE / max_dimension
sprite.scale = Vector2(scale_factor, scale_factor)
original_scale = Vector2(scale_factor, scale_factor)
sprite.scale = original_scale
DebugManager.log_debug("Set original scale to %s for tile (%d,%d)" % [original_scale, grid_position.x, grid_position.y], "Match3")
# Gem pool management functions
static func set_active_gem_pool(gem_indices: Array) -> void:
@@ -108,9 +114,78 @@ func _remove_gem_type(gem_index: int) -> void:
tile_type = 0
_set_tile_type(tile_type)
func _set_selected(value: bool) -> void:
var old_value = is_selected
is_selected = value
DebugManager.log_debug("Tile (%d,%d) selection changed: %s -> %s" % [grid_position.x, grid_position.y, old_value, value], "Match3")
_update_visual_feedback()
func _set_highlighted(value: bool) -> void:
var old_value = is_highlighted
is_highlighted = value
DebugManager.log_debug("Tile (%d,%d) highlight changed: %s -> %s" % [grid_position.x, grid_position.y, old_value, value], "Match3")
_update_visual_feedback()
func _update_visual_feedback() -> void:
if not sprite:
return
# Determine target values based on priority: selected > highlighted > normal
var target_modulate: Color
var target_scale: Vector2
var scale_multiplier: float
if is_selected:
# Selected: bright and 20% larger than original board size
target_modulate = Color(1.2, 1.2, 1.2, 1.0)
scale_multiplier = 1.2
DebugManager.log_debug("SELECTING tile (%d,%d): target scale %.2fx, current scale %s" % [grid_position.x, grid_position.y, scale_multiplier, sprite.scale], "Match3")
elif is_highlighted:
# Highlighted: subtle glow and 10% larger than original board size
target_modulate = Color(1.1, 1.1, 1.1, 1.0)
scale_multiplier = 1.1
DebugManager.log_debug("HIGHLIGHTING tile (%d,%d): target scale %.2fx, current scale %s" % [grid_position.x, grid_position.y, scale_multiplier, sprite.scale], "Match3")
else:
# Normal state: white and original board size
target_modulate = Color.WHITE
scale_multiplier = 1.0
DebugManager.log_debug("NORMALIZING tile (%d,%d): target scale %.2fx, current scale %s" % [grid_position.x, grid_position.y, scale_multiplier, sprite.scale], "Match3")
# Calculate target scale relative to original board scale
target_scale = original_scale * scale_multiplier
# Apply modulate immediately
sprite.modulate = target_modulate
# Only animate scale if it's actually changing
if sprite.scale != target_scale:
DebugManager.log_debug("Animating scale from %s to %s for tile (%d,%d)" % [sprite.scale, target_scale, grid_position.x, grid_position.y], "Match3")
var tween = create_tween()
tween.tween_property(sprite, "scale", target_scale, 0.15)
# Add completion callback for debugging
tween.tween_callback(_on_scale_animation_completed.bind(target_scale))
else:
DebugManager.log_debug("No scale change needed for tile (%d,%d)" % [grid_position.x, grid_position.y], "Match3")
func _on_scale_animation_completed(expected_scale: Vector2) -> void:
DebugManager.log_debug("Scale animation completed for tile (%d,%d): expected %s, actual %s" % [grid_position.x, grid_position.y, expected_scale, sprite.scale], "Match3")
func force_reset_visual_state() -> void:
# Force reset all visual states - debug function
is_selected = false
is_highlighted = false
if sprite:
sprite.modulate = Color.WHITE
sprite.scale = original_scale # Reset to original board scale, not 1.0
DebugManager.log_debug("Forced visual reset on tile (%d,%d) to original scale %s" % [grid_position.x, grid_position.y, original_scale], "Match3")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
add_to_group("tiles") # Add to group for gem pool management
# Initialize with current static gem pool
active_gem_types = current_gem_pool.duplicate()
_set_tile_type(tile_type)