Objects spawning on each other - Random level generation

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By C12rismaticBunny

Hello! I’m making a sidescroller game where you jump from one building to the other, but the walls are spawning too close to each other, going on top or behind each other as well.
I’d like them to spawn relatively far from each other, but I don’t know how to do that…
here is my code:


func Wall_reset():
	var Wall_instance = Wall.instance()
	Wall_instance.position = Vector2(rand_range(600,100), rand_range(-120,80))
	
	
	print(Wall_instance.position)
###spawning the wall scene:
	get_parent().call_deferred("add_child", Wall_instance)
	
	
func _on_OclusionResetter_body_entered(body): #area 2d Signal that activates when the obj is off camera.
	if body.name == "Walls":
		body.queue_free()
		Wall_reset()

Edited to fix code formatting.

jgodfrey | 2023-03-19 14:19

:bust_in_silhouette: Reply From: jgodfrey

There are a number of ways to do this - each with varying degrees of efficiency. Here are a few possibilities:

  • If you don’t have “too many” random points, a simple (but inefficient) method is to remember each point you drop and then run a distance check between each new candidate point and all accepted points. If the new candidate is too close to an existing point, generate a new one and test again. With a small’ish number of total points, this can work.

  • You could drive the placement via an artificial grid. Essentially, pick an unused cell that’s guaranteed to be “far enough” away from other points, then randomly pick a location inside that cell for your next point.

  • The Poisson Disc Sampling algorithm is an accepted, efficient method of accomplishing this specific task, though it’s not trivial to implement from scratch. Luckily, there is already an implementation available in the Godot Asset Library. Just search for the algorithm name in the library. Here’s the project’s github page: GitHub - udit/poisson-disc-sampling: Poisson Disc Sampling in GDScript for Godot

That’s cool, never heard of Poisson disc Sampling!

Another option is to make an Array of allowed points, then remove points as they are randomly selected from the array. In the editor, this could be done via a Node2D containing Marker2Ds.

aidave | 2023-03-19 21:44

Sorry to bother you again, but how can I get the position of the last object I dropped?

C12rismaticBunny | 2023-03-25 12:19

Not sure I understand the question but… I assume you’d just cache it in a local variable (or whatever is appropriate).

jgodfrey | 2023-03-25 21:11

As already pointed above, using poisson disc sampling is a good solution. In poisson disc, you have control over the minimum & maximum distances among the neighboring points, so you never get any sort of clumping. Robert Bridson proposed a better algorithm in his paper that you can explore, since it is relatively faster.