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)