How to create non-overlapping objects?

0 favourites
  • 5 posts
From the Asset Store
Hand-painted tiles, objects, animated objects, and background to build a colorful Mayan civilization environment.
  • What is the best way to randomly create non-overlapping objects?

    When I write a create object action:

    Create object X on layer 0 at (int(random(100, 1720)), int(random(100, 880)))

    This creates object randomly on the layout. Let's say I have to create 10 instances of the same object randomly, the above event creates multiple instances overlapping with each other. What is the best way to tackle this?

    I tried to check with "is overlapping" condition after creating the instance, destroying if overlapping and then again randomly creating it. But this takes time to settle all 10 instances.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • howtoconstructdemos.com/spawn-objects-randomly-without-overlapping-2-capx

    This helps. However it does happen sometimes that the instances are created in one particular area and other area remains empty. Is there a way this can be tackled?

  • Perhaps the easiest solution for you would be putting a bunch of placeholder sprites, manually in the editor. And then you can spawn random objects on them.

  • One strategy is to just create a bunch of objects, then try repositioning them if any overlap, and finally just remove any overlapping sprites if repositioning doesn’t work. You can change the second repeat to have it try longer.

    Start of layout
    Repeat 100 times
    — create sprite at random(640), random(480)
    
    Start of layout
    Repeat 1000 times
    Sprite: overlaps sprite
    Pick random sprite instance
    — sprite: set position to random(640), random(480)
    
    Start of layout
    Sprite: overlaps sprite
    Pick random sprite instance
    — sprite: destroy

    But since you don’t like bunched up sprites or too much empty space you want more of a uniform spacing which is less random.

    One possible solution is to just move each pair of sprites away from each other if they get too close.

    So the logic is then: create a bunch of sprites, loop over each pair and push them apart, and finally clean up any overlapping sprites or any that were pushed off screen.

    Start of layout
    Repeat 100 times
    — create sprite at random(640), random(480)
    
    Var i0=0
    Var i1=0
    Var d=0
    Var a=0
    
    Start of layout
    For “i0” from 0 to sprite.count-2
    For “i1” from loopindex(“i0”)+1 to sprite.count-1
    — set i0 to loopindex(“i0”)
    — set i1 to loopindex(“i1”)
    — set d to distance(sprite(i0).x,sprite(i0).y,sprite(i1).x,sprite(i1).y)
    — set a to angle(sprite(i0).x,sprite(i0).y,sprite(i1).x,sprite(i1).y)
    — compare: d<100
    — — pick sprite instance i0
    — — — sprite move (100-d)/2 pixels at angle a
    — — pick sprite instance i1
    — — — sprite move -(100-d)/2 pixels at angle a
    
    Start of layout
    Sprite is offscreen
    — sprite: destroy
    
    Start of layout
    Sprite: overlaps sprite
    Pick random sprite instance
    — sprite: destroy

    It treats the objects as circles with a radius of 100 but you can change that. You can also add another repeat to the top of the second event to loop over the pairs multiple times to better ensure there is no overlaps.

    There are also other variations you can do. Such as using a family to reference other instances, or maybe utilizing the custom movement’s push out action to separate pairs. You could also just give the objects the physics behavior with no gravity and high damping. That would make the objects not overlap after a second or so.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)