Hi!
Below is my Godot 4 code that addresses the problem of enemies spawning inside the player. The code is safe from infinite loops and reliably returns the x and y positions where an enemy should spawn. The spawn radius dynamically adjusts based on the player's scale, and you can set both minimum and maximum distances for the enemy's spawn position.
Feel free to discuss if you have better solutions or improvements. This code was used in my game Evolution Conquer, and the full open-source code can be found on my GitHub: evolution-conquer-source-code.
Required Nodes:
Area2D: The script should be attached to an Area2D node.
SpawnRadious: A child node of type Area2D, with a CircleShape2D to define the spawn radius.
You will need to implement your own enemy generation logic. Additionally, it’s advisable to handle cases where the enemy spawns outside the game boundaries, such as by ensuring the enemy moves back towards the playable area.
extends Area2D
# spawn_radius & spawn_center values here are only
# placeholders, they will change from collision shape radious
# and player position
var spawn_radius = 1000
var spawn_center = Vector2(0, 0)
# spawn_radious < x < spawn_radious_limitation
# x - position where enemy will apear
@export var spawn_radious_limitation = 2000
var parent
var spawn_radious_node
var spawn_radious_node_shape
func _ready():
parent = get_parent() as Node2D
spawn_radious_node = get_node("SpawnRadious")
spawn_radious_node_shape = spawn_radious_node.shape as CircleShape2D
spawn_radius = spawn_radious_node_shape.radius * parent.scale.x
func get_spawn_position():
# sometimes is a trouble with getting parent in _ready() funcion
if parent == null:
parent = get_parent() as Node2D
spawn_radious_node = get_node("SpawnRadious")
spawn_radious_node_shape = spawn_radious_node.shape as CircleShape2D
spawn_radius = spawn_radious_node_shape.radius * parent.scale.x
# getting player position
var spawn_center = parent.position
print("spawn center: ", spawn_center)
print("spawn radious: ", spawn_radius)
# calculation enemy position
var angle = randf_range(0, PI * 2)
var distance = randf_range(spawn_radius, spawn_radius + spawn_radious_limitation)
var position_x = spawn_center.x + cos(angle) * distance
var position_y = spawn_center.y + sin(angle) * distance
var spawn_position = Vector2(position_x, position_y)
print("spawn_position: ", spawn_position)
return spawn_position
Top comments (0)