Godot Version
4.4.1
Question
I am very new to programming and game dev. I am trying to create enemies that spawn randomly on the screen. However with my current code, they only spawn randomly at the bottom side of the screen.
Here is my code
func _on_timer_timeout() -> void:
print("Timer timed out")
##Enemy Spawning Stuff
var enemy_preload = preload("res://enemy_scene.tscn")
var enemy = enemy_preload.instantiate()
var random = RandomNumberGenerator.new()
random.randomize()
#Gets the size of the screen
var screen_size = get_viewport_rect().size
#Sets variable for max height and width
var screen_height = screen_size.y
var screen_width = screen_size.x
#Randomly chooses a range from 0 to max height or width
var rand_height = random.randi_range(0, screen_height)
var rand_width = random.randi_range(0, screen_width)
enemy.position = Vector2(rand_height, rand_width)
add_child(enemy)
Any help would be appreciated!
Does enemy_scene.tscn
have an attached script, and if so, does it do anything to position
?
position
has float
components, so you probably want randf_range()
rather than randi_range()
.
I assume this is a 2D scene?
Have you tried printing out screen_height
and rand_height
to see what you’re getting?
Yes, the enemy_scene.tscn
does have a script, but it does not do anything to position
, it only moves the enemy to the center of the screen.
I tried changing it from randi to randf but it hasn’t changed much besides the rand_height have decimal places.
Printing out screen_height
I get 720, which is what I have the height set to in the project settings.
Printing out rand_height
i get a random number from 0 to 720.
Edit:
Here is the print of the max height and width, the randomly chosen height and width, and then the enemy.position
Timer timed out
Max Height 720.0
Max Width 1280.0
Random Height 568.387329101563
Random Width 81.4947891235352
(568.3873, 81.49479)
The property position
set the nodes position relative to the parent node.
So if the parent nodes position is 100,100 and you set the child nodes position to 20,20, the child nodes global_position
will be 120,120.
This might be impacting your enemy placement.
Since you state you are new to programming I recommend removing random positioning until you have it working at a set position.
I recommend abandoning the RanomNumberGenerator
class and using the global scope random functions coupled with a seed value.
func _on_timer_timeout() -> void:
print("Timer timed out")
##Enemy Spawning Stuff
var enemy_preload = preload("res://enemy_scene.tscn")
var enemy = enemy_preload.instantiate()
#Gets the size of the screen
var screen_size = get_viewport_rect().size
#Sets variable for max height and width
var screen_height = screen_size.y
var screen_width = screen_size.x
seed(1)
# use randf_range if you actually need floating point position values
var rand_height = randi_range(0, screen_height)
var rand_width = randi_range(0, screen_width)
enemy.position = Vector2(rand_height, rand_width)
add_child(enemy)
The seed()
function will ensure that you get the same set of random numbers every time you run the function using the same value for seed.
This is essential for debugging. Once you have it running correctly you can edit the code to employ actual random numbers.
1 Like
The spawn location needed to be offset on both sides to get them to spawn above the center of the screen. Thank you for the help!
I switched
var rand_height = randi_range(0, screen_height)
var rand_width = randi_range(0, screen_width)
With
var rand_height = randi_range(-850, screen_height + 1500)
var rand_width = randi_range(-1500, screen_width + 850)
The offsets still need to be tweaked but this is what got it to work.