0 votes

what i did was, i use staticbody2D to wrap my car item.
secondly i instance the car item in my main scene and finally i use position2D
to duplicate the car in different positions since the position will be generated randomly.

The Problem is the positions of my random car keep overlapping, meaning some are created on top of each other.

code for my staticbody2D car item

extends StaticBody2D

const carlist = ["car1","car2","car3","car4","car5","car7","car8"]
var pos
x=200
var pos_y=200

func ready():
randomize()
var current
car = carlist[randi() % carlist.size()]
getnode("carD").animation = currentcar
posx=randrange(600,1650)
posy=randrange(-600,-390)
position.x = posx
position.y = pos
y

what i want is the random position should not duplicate or over lap

Godot version Godot_3.4
in Engine by (17 points)

Instead of the car item setting its own position, you could move that code to whatever instances the car item. That way you could compare the random position to see if it's too close to another car item.

thanks man, But by what means do i give a minimum
distance to each random car. A code illustration will
be appreciated.

I'm not sure how you create the Car items now but if it's by GDScript, I would just position the items there.

# car item spawner
func spawn_car_items():
    var car_items = []
    # create 25 car items
    for i in range(25):
        var x = 0
        var y = 0
        var too_close = true
        while(too_close):
            x = randrange(600,1650)
            y = randrange(-600,-390)
            too_close = false
            for item in car_items:
                var other_pos = item.get_pos()
                var x_diff = abs(x - other_pos.x)
                var y_diff = abs(y - other_pos.y)
                if x_diff < 32 && y_diff < 32:
                    too_close = true
                    break
    var instance = CarItem.instance()
    instance.set_pos(Vector2(x, y))
    car_items.push_back(instance)

# car item
const carlist = ["car1","car2","car3","car4","car5","car7","car8"]

func ready():
    # ideally you just call randomize once in your game at the start
    # randomize()
    var currentcar = carlist[randi() % carlist.size()]
    getnode("carD").animation = currentcar

This code's not great but if you aren't running it too often, it should be okay. Another, probably easier, solution is to attach an Area2D and use its get_overlapping_areas method.

1 Answer

+1 vote

Interesting approach. Since You already used another node to populate screen with cars, You can use this node again. Use Area2d instead of Position2D, and make use of Areas collision detection. Give it collision shape resembling capacity of your car, before placing car check if it would collide, if not - place the car, if yes - go to next iteration.

There is also other option - You can make cars detect surroundings on ready(), and when they would find another car within some rect of global_positions -they would queue itself free

by (7,925 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.