Files
skelly/scenes/game/gameplays/Match3InputHandler.gd
Vladimir nett00n Budylnikov 35ee2f9a5e
Some checks failed
Continuous Integration / Code Formatting (push) Successful in 33s
Continuous Integration / Code Quality Check (push) Successful in 28s
Continuous Integration / Test Execution (push) Failing after 16s
Continuous Integration / CI Summary (push) Failing after 3s
format
2025-10-01 15:35:34 +04:00

88 lines
2.9 KiB
GDScript

class_name Match3InputHandler
extends RefCounted
## Mouse input handler for Match3 gameplay
##
## Static methods for handling mouse interactions in Match3 games.
## Converts between world coordinates and grid positions, performs hit detection on tiles.
##
## Usage:
## var tile = Match3InputHandler.find_tile_at_position(grid, grid_size, mouse_pos)
## var grid_pos = Match3InputHandler.get_grid_position_from_world(node, world_pos, offset, size)
static func find_tile_at_position(
grid: Array, grid_size: Vector2i, world_pos: Vector2
) -> Node2D:
## Find the tile that contains the world position.
##
## Iterates through all tiles and checks if the world position falls within
## any tile's sprite boundaries.
##
## Args:
## grid: 2D array of tile nodes arranged in [y][x] format
## grid_size: Dimensions of the grid (width x height)
## world_pos: World coordinates to test
##
## Returns:
## The first tile node that contains the position, or null if no tile found
for y in range(grid_size.y):
for x in range(grid_size.x):
if y < grid.size() and x < grid[y].size():
var tile = grid[y][x]
if tile and tile.has_node("Sprite2D"):
var sprite = tile.get_node("Sprite2D")
if sprite and sprite.texture:
var sprite_bounds = get_sprite_world_bounds(
tile, sprite
)
if is_point_inside_rect(world_pos, sprite_bounds):
return tile
return null
static func get_sprite_world_bounds(tile: Node2D, sprite: Sprite2D) -> Rect2:
## Calculate the world space bounding rectangle of a sprite.
##
## Args:
## tile: The tile node containing the sprite
## sprite: The Sprite2D node to calculate bounds for
##
## Returns:
## Rect2 representing the sprite's bounds in world coordinates
var texture_size = sprite.texture.get_size()
var actual_size = texture_size * sprite.scale
var half_size = actual_size * 0.5
var top_left = tile.position - half_size
return Rect2(top_left, actual_size)
static func is_point_inside_rect(point: Vector2, rect: Rect2) -> bool:
# Check if a point is inside a rectangle
return (
point.x >= rect.position.x
and point.x <= rect.position.x + rect.size.x
and point.y >= rect.position.y
and point.y <= rect.position.y + rect.size.y
)
static func get_grid_position_from_world(
node: Node2D, world_pos: Vector2, grid_offset: Vector2, tile_size: float
) -> Vector2i:
## Convert world coordinates to grid array indices.
##
## Args:
## node: Reference node for coordinate space conversion
## world_pos: Position in world coordinates to convert
## grid_offset: Offset of the grid's origin from the node's position
## tile_size: Size of each tile in world units
##
## Returns:
## Vector2i containing the grid coordinates (x, y) for array indexing
var local_pos = node.to_local(world_pos)
var relative_pos = local_pos - grid_offset
var grid_x = int(relative_pos.x / tile_size)
var grid_y = int(relative_pos.y / tile_size)
return Vector2i(grid_x, grid_y)