Spawn objects on different coordinates

Hello,

i have a little trouble with spawning objects on a different coordinates, if i just use math.random for determine their positions, object will overlap each other at some point

how can i not let this happen, so every object will be spawned with at least some distance between then?
any help is appreciated [import]uid: 16142 topic_id: 17860 reply_id: 317860[/import]

There are many attempts
You could spawn those objects as physical objects with isSensor, give them a collision handler and when colliding, removing.
I don’t know if those objects would actually flash…

Another method would be to make random coordinates and then loop through every object and check if it’s at least some pixels away.

Here’s some pseudoCode:

[code]
llocal mySpawnedObjects = {}

local function distance(ax,ay,bx,by)
return (math.sqrt(math.pow(bx-ax,2)+math.pow(by-ay,2)))
end

local function spawnObject()
local rX = math.random(0,display.contentWidth)
local rY = math.random(0,display.contentHeight)

for i=0,#mySpawnedObjects,1 do
if (#mySpawnedObjects == 0) then
– First Object, spawn anywhere
local myObject = display.newRect(rX,rY,10,10)
table.insert(mySpawnedObjects,myObject)
else
– Min Distance - 100 pixels
– we need to do i+1 since lua tables start with the index of 1
local distance = math.round(distance(rX,rY,mySpawnedObjects[i+1].x,mySpawnedObjects[i+1].y))
print(distance)
if (distance >= 100) then
– create Object and place it into the array
local myObject = display.newRect(rX,rY,10,10)
table.insert(mySpawnedObjects,myObject)
else
print(“too close, can’t spawn”)
end
end
end
end

local spawnTimer = timer.performWithDelay(500,spawnObject,0)

[code]

Can’t test it right now, but will test it later. [import]uid: 13097 topic_id: 17860 reply_id: 68173[/import]

sorry, objects still overlapping with your code [import]uid: 16142 topic_id: 17860 reply_id: 68174[/import]

Had a stupid mistake :wink:
Try this one!

local mySpawnedObjects = {}  
  
local function distance(ax,ay,bx,by)  
 return (math.sqrt(math.pow((bx-ax),2)+math.pow((by-ay),2)))  
end  
  
--local maxObjects = 20  
  
local function spawnObject()  
 local rX = math.random(0,display.contentWidth)  
 local rY = math.random(0,display.contentHeight)  
 local isFarEnough = true  
 print("===============================")  
 if (#mySpawnedObjects == 0) then  
 -- First Object, spawn anywhere  
 local myObject = display.newCircle(rX,rY,20)  
 table.insert(mySpawnedObjects,myObject)  
 else  
 for i=#mySpawnedObjects,1,-1 do  
 -- Min Distance - 100 pixels  
 -- we need to do i+1 since lua tables start with the index of 1  
 local distance = math.round(distance(rX,rY,mySpawnedObjects[i].x,mySpawnedObjects[i].y))  
 print("= " ..distance .." =")  
 if (distance \< 40) then  
 isFarEnough = false  
 end  
 end  
 if (isFarEnough) then  
 -- create Object and place it into the array  
 local myObject = display.newCircle(rX,rY,20)  
 table.insert(mySpawnedObjects,myObject)  
 end  
 end  
end  
   
local spawnTimer = timer.performWithDelay(100,spawnObject,0)  

It will check if each of the already created squares is at least 100 pixels away from the new one. Of course you could also make a recursive function which would call itself as long as it can place a new image (or just make an endless timer and check for the length of the objectArray)

Hopefully it could help you!

There are other approaches aswell

Edit: Changed to use circles for better understanding! :wink: [import]uid: 13097 topic_id: 17860 reply_id: 68175[/import]

it works perfectly, thanks xxxfanta, you’re great [import]uid: 16142 topic_id: 17860 reply_id: 68341[/import]

You’re welcome! :slight_smile: [import]uid: 13097 topic_id: 17860 reply_id: 68343[/import]

i have a trouble with your code
when i’m trying to remove objects and then spawn them again i get this error:
attempt to perform arithmetic on local “bx” (a nil value)

what’s i’m supposed to do? is there a best way to remove objects so this problem would not occur? [import]uid: 16142 topic_id: 17860 reply_id: 68363[/import]

Make sure to cancel the timer first!

timer:cancel(spawnTimer)

And don’t forget removing objects “reversed”
i.e.:

for i=#mySpawnedObjects,1,-1 do mySpawnedObjects[i]:removeSelf(); mySpawnedObjects[i] = nil; end [import]uid: 13097 topic_id: 17860 reply_id: 68367[/import]

glad for help, but alrady solved my problems)

by the way, why use reversed loop? is there any practical difference to simple loop? [import]uid: 16142 topic_id: 17860 reply_id: 68370[/import]

Sure.
When you remove the objects from 1 to #mySpawnedObjects, you’ll get an error at half the way.
Why? Because those indices don’t exist anymore!

If you have a table with t[1], t[2], … t[5] and remove the first one, everyone will move in their position (since LUA tables don’t want to have “holes”).
Therefor after deleting 3 of those, he can’t find t[4], since there are only t[1] and t[2] left.

Hope that makes sense [import]uid: 13097 topic_id: 17860 reply_id: 68373[/import]

that makes sense, thanks
though for removing all things at once i find its ok to use simple loop [import]uid: 16142 topic_id: 17860 reply_id: 68380[/import]

Well you still should use a reversed one, otherwise you will run into errors! (since you can’t delete everything at once) [import]uid: 13097 topic_id: 17860 reply_id: 68382[/import]

hey again, i have a slight problem with your code one more time
so i’m spawning objects with your method and then i’m trying to remove items on collision
but the problem is: when things spawning with timer and i remove one or few of them then they stop spawn and terminal gives me error about distance function
can you tell me why is this happening? [import]uid: 16142 topic_id: 17860 reply_id: 70169[/import]