• Godot Help
  • Puzzle game: need to add connecting pipes into array

I'm making a puzzle game, where you connect water pipes into loops and they queue_free() when they're in a loop.

Clicking a pipe rotates it by 90 degrees, as shown in the above picture's green arrows. The main scene contains the pipe Area2D scenes ( pipestraight, pipebend, pipetshape, and a pipecross). The pipes all have empty and full (of water) Sprite2Ds that trigger when each pipe's end touches the next pipe's Area2D and its respective CollisionPolygon2D.

The idea: the bigger the loop of full pipes, the loop queue_free()s and the more points you get.

My problem is having Godot understand that I have a loop. I know I need to use arrays somehow to combine them into a loop, but I'm not sure how.

I have everything on lockdown until the _on_area_entered_ function. Below is my code:

extends Area2D

@onready var empty: Sprite2D = $Empty
@onready var full: Sprite2D = $Full
@onready var connected_pipes = []

func _ready() -> void:
	area_entered.connect(_on_area_entered)
	area_exited.connect(_on_area_exited)
	
func _process(_delta: float) -> void:
	if has_overlapping_areas():
		fill_pipe()
	else:
		empty_pipe()
	
func _input(event):
	if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
		print(connected_pipes)
		if empty.get_rect().has_point(to_local(event.position)):
			rotate_pipe()

func rotate_pipe():
	rotation_degrees += 90

func _on_area_entered(area: Area2D) -> void:
	if area not in connected_pipes:
		var adjacent_pipes = get_overlapping_areas()
		if area not in connected_pipes:
			connected_pipes.append(area)
		for adjacent_pipe in adjacent_pipes:
			if adjacent_pipe not in connected_pipes:
				connected_pipes.append(adjacent_pipes)


func _on_area_exited(area: Area2D) -> void:
		if area in connected_pipes:
			connected_pipes.erase(area)

func fill_pipe():
		empty.hide()
		full.show()
		
func empty_pipe():
		empty.show()
		full.hide()

Any help is appreciated!

Is a pipetshape or pipecross considered to be in a loop if one of its ends is not connected to another pipe?

You could check for a loop by traversing the pipe, starting at any point, continuing through connected pipes, and checking whether you reach the starting point before reaching an open pipe end. With the pipetshapes and pipecrosses, you would need to traverse in two dimensions, i.e. left-right and up-down.

Don't assume that an Array is the right solution. A Dictionary or some other representation might be better.

I would try to construct a solution using a "pencil and paper" method, considering various cases, and then figure out how to do the same thing in GDScript.

You might be able to represent each combination of pipes and connected pipes as a state. Connecting two pipes would transition to another state, and some of the states would be loops.

  • dib replied to this.

    DaveTheCoder I appreciate your response. When you say traverse, what do you mean? Draw a line through the horizontal and bend, and two lines through the T shape and cross? Then check if all lines in a loop connect to another line?

    I meant traverse in the literal sense. I thought the pipes were represented in some way that made that possible. But if the pipes are simply images, that's probably not practical.