My game is a puzzles game, one of the puzzles i am trying to add is the word search puzzle, a grid with n * n tiles with each tile having a letter, the player has to find the words by swiping in straight horizontally, vertically, or diagonally lines.
How did i create my grid
Since i have a dynamic number of words each round i made it programmatically, i have a GridContainer element and when the level is generated i generate array of arrays with each row’s letters then i fill the container with it.
Problem
I am having trouble implementing the swiping mechanism, specifically how to restrict the user on doing straight lines (Video link) one of the many issues is if the swipe long enough some of the characters in the path are not registered in the swipe.
How can i implement this puzzle correctly? Thank you guys for any help.
below is my whole process from touch input start to end, apologies for the long code.
func _on_matrix_grid_gui_input(event: InputEvent) -> void:
if event is InputEventScreenTouch:
if event.pressed:
handle_touch_start(event.position)
else:
handle_touch_end()
if event is InputEventScreenDrag:
handle_touch_drag(event.position)
func handle_touch_start(touch_position: Vector2):
# clear pre-set values
touched_nodes.clear()
line.clear_points()
line.position = matrix_grid.position
line.add_point(touch_position)
line.add_point(touch_position)
drag_start_node = select_node_at(touch_position)
drag_start_position = touch_position
func handle_touch_drag(touch_position: Vector2):
# Check if the drag is outside the grid
if not get_grid_global_rect(matrix_grid).has_point(touch_position):
return
if drag_start_node and line.points.size() > 1:
# Update the drag line visually
line.set_point_position(line.points.size() - 1, touch_position)
# empty the list of tracked nodes
remove_tracked_nodes()
# Calculate a straight line from drag_start_position to touch_position
var num_points = 10 # Adjust this number to control the granularity of the line
for i in range(num_points + 1):
var t = i / float(num_points)
var point = drag_start_position.lerp(touch_position, t)
select_node_at(point)
func handle_touch_end():
if touched_nodes.size() > 1:
# Validate the user's path as a straight line
if not validate_path_is_straight(touched_nodes):
print("Invalid swipe! Not a straight line.")
# Reset highlights to clear any feedback
remove_tracked_nodes()
line.clear_points()
return
# Check if the selected word is valid
check_words_chosen()
# Clear drag-related data
touched_nodes.clear()
line.clear_points()
func validate_path_is_straight(nodes: Array) -> bool:
if nodes.size() < 2:
return false # Not enough nodes to form a path
# Determine the direction of the swipe based on the first two nodes
var first_pos = get_node_grid_position(nodes[0])
var second_pos = get_node_grid_position(nodes[1])
var direction = second_pos - first_pos
# Normalize the direction to ensure consistency
if direction.x != 0:
direction.x /= abs(direction.x)
if direction.y != 0:
direction.y /= abs(direction.y)
# Check that all nodes follow the same direction
for i in range(nodes.size() - 1):
var current_pos = get_node_grid_position(nodes[i])
var next_pos = get_node_grid_position(nodes[i + 1])
var diff = next_pos - current_pos
# Normalize the difference to match the direction vector
if diff.x != 0:
diff.x /= abs(diff.x)
if diff.y != 0:
diff.y /= abs(diff.y)
if diff != direction:
return false # Path is not straight
return true
func select_node_at(touch_position: Vector2) -> Label:
# Iterate through all children of the grid container
for child in matrix_grid.get_children():
if child is Label:
# Get the global bounding rectangle of the child
var rect = get_label_global_rect(child)
if rect.has_point(touch_position): # Check if the touch is within this label's rect
if child not in touched_nodes:
highlight_label(child)
return child
return null
func get_label_global_rect(label: Label) -> Rect2:
# Calculate the global rectangle of the label
var rect = label.get_rect()
return Rect2(label.position, rect.size)
func get_grid_global_rect(grid: GridContainer) -> Rect2:
# Calculate the global rectangle of the label
var rect = grid.get_rect()
return Rect2(Vector2(), rect.size)
func highlight_label(label_node: Label):
touched_nodes.append(label_node)
# Add a visual effect to the selected label (e.g., change font color)
label_node.add_theme_color_override("font_color", Color(1, 0, 1)) # Purple
func check_words_chosen():
...
func get_node_grid_position(label: Label) -> Vector2:
# Determine the grid position of the label within the grid container
var index = matrix_grid.get_children().find(label)
var cols = matrix_grid.columns # Assuming GridContainer
@warning_ignore("integer_division")
return Vector2(index % cols, index / cols)
func remove_tracked_nodes():
for node in touched_nodes:
node.add_theme_color_override("font_color", Color(1, 1, 1))
touched_nodes.clear()