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)