Is it possible to make two randomly generated objects not spawn on top of each other?

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

Hello, in my game I have two collectibles that spawn for the player to obtain. A coin, which is worth 10 score, and 1 cash, and a gem, which is worth 50 score and 10 cash. The coin spawns when the game begins, and whenever the player grabs it, it respawns immediately at a random location. The gem on the other hand is “rare” how I did this was set it up to a timer with a minimum of 5 seconds and a maximum of 30 seconds, and will spawn when timer timesout, also at a random location. However, what seems to be happening more often than I would like it to, is that the gem will spawn on top of the coin, or vice versa, and they trigger each other; My cash goes up by 11, and my score goes up by 60, and then they both disappear. (The coin respawns immediately after). They are both hooked up to this part of my script for random generation:

func _spawn_coin():

var coin_spawn_position = Vector2(randi()%500+31, randi()%550+31)

while coin_spawn_position == $Player.position:

	_spawn_coin()
	
$CoinPosition.position = coin_spawn_position

$Coin._spawn($CoinPosition.position)

The gem spawn function is the exact same but replace the word coin with gem everywhere it is shown here. My question is, is it possible to prevent the two collectibles from spawning on top of one another? Or at least if they do, not to trigger each other? (There is an indent for func I had to make it look that way because it wasn’t showing up in the script text for my question.)

:bust_in_silhouette: Reply From: Lopy

To prevent them from activating one another, you can set their collision masks. You cant set the collision layers of the Player to be the top left square, and the collision layer of your Areas to be empty, with a mask on the top left square.

Since you only have a few items, when placing a new one, you can manually check if the spot is free. Just keep an array of placed items to check that no other is close to your chosen spot, and repeat selection the until a spot is found.

To display indents properly, you can put a “.” at the start of the line :
. indented

aha wow I don’t know how I didn’t think of that considering I had to do a lot of mask and layer work to have some mobs interact with each other, and some not interact with each other. I guess I was thinking that the fact they were stationary areas had something to do with it which I’m now realizing doesn’t make sense. Thank you!

Spafnar | 2021-01-01 22:16