How to generate random spawn point at edge of screen only?

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

Which edge? Top, bottom, left, right, some combination, or any?

jgodfrey | 2020-02-07 22:55

Any, I think I just had an idea too. Might be bonkers though :wink:

first generate randon number 1-4.

1 = top edge
2 = right edge
3 = bott… etc

if top edge then y=0, x= random (0, xmax)
if bottom edge then y = ymax, x= random (0, xmax)

and vice versa for left and right?

GodotBadger | 2020-02-07 23:01

Yep, something along those lines should work fine. You could potentially combine top/bottom and left/right for the random part to clean it up a bit, but you’ve got the idea…

jgodfrey | 2020-02-07 23:12

:bust_in_silhouette: Reply From: Magso

If it’s only the edges store an array of Vector2s and pick a random index. The array would have to be updated constantly if the window is resizeable.

var screen_edges : Array = []

func _ready():
    screen_edges.append(Vector2.ZERO)
    screen_edges.append(Vector2(get_viewport().size.x,0))
    screen_edges.append(Vector2(0,get_viewport().size.y))
    screen_edges.append(get_viewport().size)
    
    //Spawn at random point using screen_edges[rand_range(0,screen_edges.size())]

does that just pick a random edge? how would you pick a random point on that edge? I can have a go but don’t think it will be as neat as your thinking :slight_smile:

GodotBadger | 2020-02-07 23:21

Yeah, looks like that’ll spawn in one of the 4 screen corners

jgodfrey | 2020-02-07 23:44

oh yeah, I see that now. I did it like this

func randomize_spawn_point():
var s = 0
var spawn_point

randomize()
s = int(round(rand_range(0.51, 4.49)))

if s == 1: # top edge
	spawn_point = Vector2(rand_range(0, get_viewport_rect().size.x),0)
if s == 3: # bottom edge
	spawn_point = Vector2(rand_range(0, get_viewport_rect().size.x), get_viewport_rect().size.y)
if s == 2: # right edge
	spawn_point = Vector2(get_viewport_rect().size.x, rand_range(0, get_viewport_rect().size.y))
if s == 4: # left edge
	spawn_point = Vector2(0, rand_range(0, get_viewport_rect().size.y))

return spawn_point

GodotBadger | 2020-02-07 23:45

It was the corners, for some reason I thought that’s what GodotBadger meant by edges.

Magso | 2020-02-08 00:28

Thanks for the help anyway, I still learned something :slight_smile:

GodotBadger | 2020-02-08 00:29

I also learned something XD You might want to post your script as best answer as well.

Magso | 2020-02-08 00:34

You don’t have to call randomize() each time you generate a random number. It just sets the seed used for the random number generation, so it’s enough to call it once in _ready(). Also there is randi_range(), so instead of writing

s = int(round(rand_range(0.51, 4.49)))

you can simply use

s = randi_range(1, 4)

njamster | 2020-02-08 15:07

That doesn’t work for me, it gives an error, even though I can see it in the documentation. Says "The method “randi_range” isn’t declared in the current class???

GodotBadger | 2020-02-09 01:50

There are a number of ways of picking a random number within a specified range. Many of them are discussed in this thread:

https://forum.godotengine.org/2539/how-would-i-go-about-picking-a-random-number

Regarding the above randi_range(min, max), that’s documented here:

RandomNumberGenerator — Godot Engine (latest) documentation in English

As documented, it’s a method of RandomNumberGenerator object. To use it, you need an instance of that object. So, something like this:

var rng = RandomNumberGenerator.new()
var ranInt = rng.randi_range(1, 4)

jgodfrey | 2020-02-09 02:48

Are you using an older version of Godot 3? https://godot-es-docs.readthedocs.io/en/latest/classes/class_randomnumbergenerator.html

Magso | 2020-02-09 10:08

Sorry, my bad. As jgodfrey correctly pointed out, this method is only available on an instance of RandomNumberGenerator. Outside of this it won’t work. However, you could still use this:

var random_int = randi() % 4 + 1

The %-sign represents the modulo-operator.

Alternatively you could also use ẁrapi:

var random_int = wrapi(randi(), 1, 4)

njamster | 2020-02-09 11:44

:bust_in_silhouette: Reply From: njamster

This is covered in the “Your first game”-section of the documentation.