How can I handling enemies spawning on top of each other

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

I want to manage than the enemies don’t spawn on top of each other how iIwould do that ? here is my code :

extends Node

func _ready():
    var rand = RandomNumberGenerator.new()
    var enemyscene = load("res://Scenes/VirusBlue.tscn")
    
    var screen_size = get_viewport().get_visible_rect().size
    
    for i in range (0,10):
        var enemy = enemyscene.instance()
        rand.randomize()
        var x = rand.randf_range(0, screen_size.x)
        rand.randomize()
        var y = rand.randf_range(0, screen_size.y)
        enemy.position.y = y
        enemy.position.x = x
        add_child(enemy)
:bust_in_silhouette: Reply From: jgodfrey

There are at least 2 typical ways of doing this.

  1. Pick a random location. If it’s “too close” to other locations, pick again.
  2. Sprinkle a set of “fixed” (known valid) spawn locations over your area. Then, randomly pick one of those locations each time you spawn. When a location is chosen, mark it as “used” so you won’t pick it again.

Here’s an example of #1. In this case, it just keeps track of the spawn locations and ensures that each new location is some “minimum distance” from all other spawn locations. You could potentially do something similar with some “physics overlaps” checks. Or, you could put the enemies in a common group, and then spin through the group and compare the new location to the items in the group instead of storing the spawn locations in a separate array…

One note of caution here. This code is just an example and isn’t production ready, as it just loops until it finds a valid location. If there is not valid location, it’ll loop forever…

extends Node2D

onready var screen_size = get_viewport().get_visible_rect().size
var spawnLocs = Array()
var minDist = 100 # minimum distance between spawned sprites...
var rand = RandomNumberGenerator.new()

func _ready():

	rand.randomize()
	var enemyscene = load("res://sprite.tscn")

	for i in range (0,10):
		var nextLoc = getNextSpawnLoc()
		var enemy = enemyscene.instance()
		enemy.position = nextLoc
		add_child(enemy)

func getNextSpawnLoc():
	while true:
		var x = rand.randf_range(0, screen_size.x)
		var y = rand.randf_range(0, screen_size.y)
		var newLoc = Vector2(x,y)
		var tooClose = false
		for loc in spawnLocs:
			if newLoc.distance_to(loc) < minDist:
				tooClose = true;
				break;
		if !tooClose:
			spawnLocs.append(newLoc)
			return newLoc