How do you change spawn parameters to a list of specific coordinates?

Hello everyone. I’ve been working with this tutorial on object spawning.

I got it working with some help from this forum. Now I’m wondering if there are other ways to set up the spawn parameters.The tutorial just has it set up as:
local spawnParams = {

xMin = 20,

xMax = 300,

yMin = 20,

yMax = 460,

spawnTime = 200,

spawnOnTimer = 12,

spawnInitial = 4

}

I’m trying to do it differently. Rather than randomly spawning anywhere between these dimensions, I want them to randomly appear in any of 105 specified coordinates. I already have the X’s and Y’s picked out like I did bellow.

I am trying to make the objects fit inside of grid cells but they keep falling between cells.

Any help is appreciated.

local gx = {}

    gx1 = _CX - 120

    gx2 = _CX - 80

    gx3 = _CX - 40

    gx4 = _CX - 0

    gx5 = _CX + 40

    gx6 = _CX + 80

    gx7 = _CX + 120

local gy = {}

    gy1 = _CY - 280

    gy2 = _CY - 240  

    gy3 = _CY - 200

    gy4 = _CY - 160

    gy5 = _CY - 120

    gy6 = _CY - 80

    gy7 = _CY - 40  

    gy8 = _CY    

    gy9 = _CY + 40

    gy10 = _CY + 80

    gy11 = _CY + 120

    gy12 = _CY + 160

    gy13 = _CY + 200

    gy14 = _CY + 240

    gy15 = _CY + 280

Hi @daubin, I noticed in the code you just making bunch of different variable instead of putting them into easily accessible array (see Corona University Using Tables with Corona SDK - YouTube) i.e

local gx = {}
gx[1] = _CX - 120

gx[2] = _CX - 80

--etc

When everything is in an array you can use the math.random function to easy pick from the cords

local howManyXs =7
local howManyYs = 15
local randomXIndex = math.random(1, howManyXs)
local randomYIndex = math.random(1, howManyYs)
--Cords
print("My Random X is "..gx[randomXIndex])
print("My Random Y is "..gy[randomYIndex])

I’ll also suggest a “next step” to Scott’s example. I hope I’m not treading on your toes Scott, as I totally understand why you’ve simplified it to make the immediate problem easier to understand.

Once you have your head wrapped around that issue, these suggestions will save having to edit the code so much when making changes to your grid structure.

  1. Rather than hardcoding howManyXs and howManyYs, read the number of entries that are in the gx and gy tables:
local howManyXs = #gx
local howManyYs = #gy

That way if you add another 10 rows to gy, you don’t have to remember to go back and change howManyYs (the # symbol in Lua is used to get the number of entries in a table for you).

Since all of your columns/rows increment in steps of 40, you can use a ‘loop’ to quickly populate a table. This will also let you change the number of rows or columns quickly, or change the spacing between rows/columns if you need to

local gx = {}
local gy = {}

local stepSize = 40

local numberOfRows = 7
local numberOfColumns = 15

--the start positions for X and Y values
local xPosition = _CX-120
local yPosition = _CY-280

--this will cause the code inside the loop to repeat from the start number to the end number
--in this case from 1 to 7
for loopCount = 1, numberOfRows do

    --this will set the values of gx[1] to gx[7] to the current value of 'xPosition' as it repeats
    gx[loopCount] = xPosition

    --and this will increase the value of xPosition by stepSize each time this loop repeats
    xPosition = xPosition + stepSize
end


--this will do the same as above, but repeat from 1 to 15 and will set the values for gy
for loopCount = 1, numberOfColumns do
    gy[loopCount] = yPosition
    yPosition = yPosition + stepSize
end

Using the above you can change stepSize to immediately change the gap between each cell, rather than having to edit every single line of +40, +80, +120 etc.
You can also change the numberOfColumns and numberOfRows variables to change the number of rows and columns.

Again, Scott’s suggestion fixes your problem - but I think the code you are implementing is the perfect time to look into loops and how they can be used with tables. Both loops and tables are a pretty critical part of almost every single project so getting an early start on them will prevent lots of headaches later on.

1 Like

Hey sorry guys I’m still having some trouble. I kind of get it but I don’t know what to set as my spawn parameters within the spawning function. I’m trying to enter these tables into the code but they are spawning in weird spots. This what I have, sorry if it’s a bit of a mess.

--Layout
local relayout = require("relayout")

local _W, _H, _CX, _CY = relayout._W, relayout._H, relayout._CX, relayout._CY

--Variables

local physics = require( "physics" )
physics.start()

--grid

local gx = {}
    gx[1] = _CX - 120 
    gx[2] = _CX - 80 
    gx[3] = _CX - 40
    gx[4] = _CX - 0
    gx[5] = _CX + 40 
    gx[6] = _CX + 80 
    gx[7] = _CX + 120 

local gy = {}
    gy[1] = _CY - 280
    gy[2] = _CY - 240  
    gy[3] = _CY - 200
    gy[4] = _CY - 160
    gy[5] = _CY - 120 
    gy[6] = _CY - 80
    gy[7] = _CY - 40  
    gy[8] = _CY    
    gy[9] = _CY + 40
    gy[10] = _CY + 80
    gy[11] = _CY + 120 
    gy[12] = _CY + 160 
    gy[13] = _CY + 200 
    gy[14] = _CY + 240 
    gy[15] = _CY + 280 

local howManyXs = #gx
local howManyYs = #gy
local randomXIndex = math.random(1, howManyXs)
local randomYIndex = math.random(1, howManyYs)
--Cords
--print("My Random X is "..gx[randomXIndex])
--print("My Random Y is "..gy[randomYIndex])


local stepSize = 40

local numberOfRows = 7
local numberOfColumns = 15

--the start positions for X and Y values
local xPosition = _CX-120
local yPosition = _CY-280

--this will cause the code inside the loop to repeat from the start number to the end number
--in this case from 1 to 7
for loopCount = 1, numberOfRows do

    --this will set the values of gx[1] to gx[7] to the current value of 'xPosition' as it repeats
    gx[loopCount] = xPosition

    --and this will increase the value of xPosition by stepSize each time this loop repeats
    xPosition = xPosition + stepSize
end


local board = display.newImageRect( "grid.png", 280, 600 )
board.x = _CX
board.y = _CY

--squares

--local water = display.newRect (_CX, _CY, 39, 39)
--water:setFillColor (0.53, 0.81, 0.94 )
--water.velocity = 0
--water.gravity = 0.1
--physics.addBody (water, "dynamic", { density=1, bounce=0.0 }) 


--local dirt = display.newRect (_CX, _CY + 280 , 39, 39)
--dirt:setFillColor (0.39, 0.26, 0.12)
--physics.addBody (dirt, "dynamic", { density=1, bounce=0.0 }) 

--
--collision

local function checkCollision(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 

--boundaries

local floor = display.newRect (_CX, _CY + 319, _W * 3, 39)
floor:setFillColor (0, 0, 0 )
physics.addBody ( floor, "static", {bounce=0.0, friction=0.3 } )

local leftWall = display.newRect (_CX - 159, _CY, 39, _H)
leftWall:setFillColor (0, 0, 0 )
physics.addBody ( leftWall, "static", {bounce=0.0, friction=0.3 } )

local rightWall = display.newRect (_CX + 159, _CY, 39, _H)
rightWall:setFillColor (0, 0, 0 )
physics.addBody ( rightWall, "static", {bounce=0.0, friction=0.3 } )

local ceiling = display.newRect (_CX, _CY - 319, _W * 3, 39)
ceiling:setFillColor (0, 0, 0 )
physics.addBody ( ceiling, "static", {bounce=0.0, friction=0.3 } )

--spawning

local spawnTimer
local spawnedItem = {}
local spawnedObjects = {}
-- Seed the random number generator
math.randomseed( os.time() )





local spawnParams = {}
    xMin = gx[1]
    xMax = gx[7]
    yMin = gy [1]
    yMax = gy[15]
    spawnTime = 200
    spawnOnTimer = 103
   spawnInitial = 30


-- Spawn an item
local function spawnItem( bounds )
 
    -- Create an item
    local item = display.newRect (_CX, _CY, 39, 39)
    physics.addBody (item, "dynamic", { density=1, bounce=0 })
    item.isFixedRotation = true

 
    -- Position item randomly within set bounds
    item.x = math.random( bounds.xMin, bounds.xMax )
    item.y = math.random( bounds.yMin, bounds.yMax ) 
 
    -- Add item to "spawnedObjects" table for tracking purposes
    spawnedObjects[#spawnedObjects+1] = item
end

local function spawnController( action, params )
 
    -- Cancel timer on "start" or "stop", if it exists
    if ( spawnTimer and ( action == "start" or action == "stop" ) ) then
        timer.cancel( spawnTimer )
    end
 
    -- Start spawning
    if ( action == "start" ) then
 
        -- Gather/set spawning bounds
        local spawnBounds = {}
        spawnBounds.xMin = randomXIndex
        spawnBounds.xMax = randomXIndex
        spawnBounds.yMin = randomYIndex
        spawnBounds.yMax = randomYIndex
 
        
        
 
        -- Gather/set other spawning params
        local spawnTime = params.spawnTime or 1000
        local spawnOnTimer = params.spawnOnTimer or 50
        local spawnInitial = params.spawnInitial or 0
 
        -- If "spawnInitial" is greater than 0, spawn that many item(s) instantly
        if ( spawnInitial > 0 ) then
            for n = 1,spawnInitial do
                spawnItem( spawnBounds )
            end
        end
 
        -- Start repeating timer to spawn items
        if ( spawnOnTimer > 0 ) then
            spawnTimer = timer.performWithDelay( spawnTime,
               function() spawnItem( spawnBounds ); end,
            spawnOnTimer )
        end
 
    -- Pause spawning
    elseif ( action == "pause" ) then
        timer.pause( spawnTimer )
 
    -- Resume spawning
    elseif ( action == "resume" ) then
        timer.resume( spawnTimer )
    end
end

spawnController( "start", spawnParams )

--
--update

-- local function update()

 --   water.velocity = water.velocity - water.gravity
   -- water.y = water.y - water.velocity
--end




--Runtime:addEventListener ("enterFrame", update)
 

Something in your code looks suspicious:

spawnController( "start", spawnParams )

but spawnParams seems to be empty because:

local spawnParams = {}
    xMin = gx[1]
    xMax = gx[7]
    yMin = gy [1]
    yMax = gy[15]
    spawnTime = 200
    spawnOnTimer = 103
   spawnInitial = 30

shouldn’t this last part be:

local spawnParams = {}
    spawnParams.xMin = gx[1]
    spawnParams.xMax = gx[7]
    spawnParams. yMin = gy [1]
    spawnParams.yMax = gy[15]
    spawnParams.spawnTime = 200
    spawnParams.spawnOnTimer = 103
    spawnParams.spawnInitial = 30

Or alternatively:

local spawnParams = {
    xMin = gx[1],
    xMax = gx[7],
    yMin = gy [1],
    yMax = gy[15],
    spawnTime = 200,
    spawnOnTimer = 103,
    spawnInitial = 30,
}