Randomly generate objects whist preventing overlaps

I am trying to solve what I thought would be a straightforward problem, however it has got me stumped.

I’m trying to create a simple game with ten objects which are set on the screen randomly, easy enough, but how do you check to see if each object isn’t overlapping one another and if so move it to a position that is free(or run the check again).

Also these ten objects are “static” objects so collision tests don’t seem to work.

I have looked high and low for hit tests etc which some of them point in the right direction but then I end up with a for loop which tests a table of objects for one object pair but not all… so I’m a bit stuck

Has anyone got any ideas on a simple(or hard) non-dynamic overlapping object test on randomly generated objects (end mouthful)? [import]uid: 33866 topic_id: 8038 reply_id: 308038[/import]

If it helps anyone help me, here is my mangled code so far, it doesn’t work but is going sort of in the right direction:

[lua]-- NEW make platforms ---------------------------------------------------------------
local platforms = {}

for i = 1, 10 do
platforms[i] = display.newImageRect( “platform.png”, 75, 15)
platforms[i].x = math.random(-250, 650)
platforms[i].y = math.random(180, 380)
platforms[i].isVisible = true
platforms[i].name = “platform”
platforms[i].IsGround = true
physics.addBody( platforms[i], “static”, { density=1, friction=0.3, bounce=0.2 } )
this2:insert(platforms[i])

end
stopCheck = false
function hitTestObjects(obj1, obj2)
local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin
local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax
local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin
local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax
return (left or right) and (up or down)
end

local function checkPlatforms()
for i = 1, 10 do

local firstPlatform = platforms[i]
for j=1,#platforms do

local secondPlatform = platforms[j]
if stopCheck == false then
if hitTestObjects(firstPlatform, secondPlatform) == true then
–firstPlatform.x = math.random(-250, 650)
–firstPlatform.y = math.random(180, 380)
firstPlatform:removeSelf()

print(“moved one”)
checkPlatforms()
else
stopCheck = true
Runtime:removeEventListener( “enterFrame”, checkPlatforms )
end
end
end
end
end

if stopCheck == false then
Runtime:addEventListener( “enterFrame”, checkPlatforms )
else
Runtime:removeEventListener( “enterFrame”, checkPlatforms )
end[/lua] [import]uid: 33866 topic_id: 8038 reply_id: 28630[/import]

One idea: When setting the scene up, you could add 10 circles as bodies to the screen and just let them fall to rest. Each circle would have to be bigger than the objects you are trying to place on the screen. After just a couple of frames (to give the circles time to stop over lapping - play with this) just remove each one, replacing it with the objects you actually want on the screen.

Let us know how it goes.

m [import]uid: 8271 topic_id: 8038 reply_id: 28748[/import]

@horacebury: this is a very clever fix :slight_smile: not tried it yet but I think it should do the trick.

In the mean time i’ve sort of fixed the issue buy just laying things out in Gumbo and cheating… no one will ever know… doh…

Thanks for your help! [import]uid: 33866 topic_id: 8038 reply_id: 28822[/import]

I wrote a function to check for overlap:
http://developer.anscamobile.com/code/flashs-hittestobject-emulated-using-contentbounds [import]uid: 12108 topic_id: 8038 reply_id: 28943[/import]

When using the physics engine and regular collision event, you can keep a list on each object of the objects they are colliding with and simply do a lookup when you need to. Just add an object on the ‘began’ phase and remove it on the ‘ended’ phase. Won’t solve this problem - because you want the layout prior to render - but if you let the physics run for a couple of frames before showing it on screen, it’d do the same thing. [import]uid: 8271 topic_id: 8038 reply_id: 28950[/import]