How to make an area2D apears on random position in the screen?

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

Shouldn’t be too dificult but i’m a noob in scripts…

:bust_in_silhouette: Reply From: jgodfrey

As here…

https://forum.godotengine.org/59426/way-make-area2d-apears-and-disapears-randomly-on-the-screen

…I’m happy to give you some pointers, but I’m not interested in just writing your code for you…

For this one, you’ll need to know the screen size for starters. You can get that like this:

var screenSize = get_viewport().get_visible_rect().size

That returns a Vector2, so you can then access the X and Y screen dims with:

screenSize.x and screenSize.y

Now, really all you need to do is pick a random X value between 0 and screenSize.x and a random Y value between 0 and screenSize.y.

So, something like this:

 var rng = RandomNumberGenerator.new()
 var rndX = rng.randi_range(0, screenSize.x)
 var rndY = rng.randi_range(0, screenSize.y)

And, finally, just set the position of the area2D to the new, random position

$Area2D.position = Vector2(rndX, rndY)

(Again, all code typed directly into this answer, so beware of typos…)

Cheers! I’m learnin to code lil by lil, with effective practice ;).

Syl | 2020-01-23 23:04

Sry. Look, tinkered somethin like that:

    extends Node2D

func _ready():
   
   var screenSize = get_viewport().get_visible_rect().size
   var rng = RandomNumberGenerator.new()
   var rng2 = RandomNumberGenerator.new()
   var rng3 = RandomNumberGenerator.new()
   var rng4 = RandomNumberGenerator.new()
   var rndX = rng.randi_range(0, screenSize.x)
   var rndY = rng.randi_range(0, screenSize.y)
   var rndX2 = rng2.randi_range(0, screenSize.x)
   var rndY2 = rng2.randi_range(0, screenSize.y)
   var rndX3 = rng3.randi_range(0, screenSize.x)
   var rndY3 = rng3.randi_range(0, screenSize.y)
   var rndX4 = rng.randi_range(0, screenSize.x)
   var rndY4 = rng.randi_range(0, screenSize.y)
   
   $Area2D.position = Vector2(rndX, rndY)
   $Area2D2.position = Vector2(rndX2, rndY2)
   $Area2D3.position = Vector2(rndX3, rndY3)
   $Area2D.position = Vector2(rndX4, rndY4)

func _on_Timer_timeout():
   
   var rng = RandomNumberGenerator.new()
   var nextToggleSeconds = rng.randi_range(5, 15) 
   
   $Area2D.visible = !$Area2D.visible # switch visibility
   $Area2D2.visible = !$Area2D2.visible
   $Area2D3.visible = !$Area2D3.visible
   $Area2D3.visible = !$Area2D4.visible
   $Timer.start(nextToggleSeconds)

For my 4 Area2D, but they all apears at the same position, and don’t change it, though the time change seems to work…

Syl | 2020-01-24 02:03

First, you don’t want multiple RandomNumberGenerator instances. In fact, that’s most likely the problem here as I assume each instance of the RNG is using the same random seed - which would make each of them produce the same set of “random” numbers…

Try making a single RNG, then randomize it, and use it for everything. So, this:

var rng = RandomNumberGenerator.new()
rng.randomize()
var rndX = rng.randi_range(0, screenSize.x)
# The rest of your random points, all using the single *rng*

Really, depending on your use-case, you can likely get by with a single, global instance of an RNG for the entire game.

jgodfrey | 2020-01-24 02:12

Ok, that works, but why multiple rng got the same seed and result, and a single one gives diferences? And how to restart the random positioning of them all, in some kind of random loop, that could be configured to continue till a change of scene?

I think i’ll have to make a global singleton for my player, could i include it there?

Syl | 2020-01-24 07:35