Creating circles in custom functions

I have begun learning to program Corona by looking at the code of my developer.  I am coming along nicely but still lots to learn.

Anyway,

I have this function

function scene:create( event )

    local sceneGroup = self.view

    local mycircle = display.newCircle(50,50, 25)
    local text = display.newText(“ABCDE”,50,50,Helvetica, 14)
    text:setTextColor(0,0,1,255)
    mycircle.id = “ABCDE”
    sceneGroup:insert(mycircle)
    sceneGroup:insert(text)

end

and I understand it.  However, if I want to do something like this…

function scene:create( event )

 level1(arg1, arg2, arg3)

 level2(arg1, arg2, arg3)


   

end

function level1(one, two, three)

    local mycircle = display.newCircle(50,50, 25)
    local text = display.newText(“ABCDE”,50,50,Helvetica, 14)
    text:setTextColor(0,0,1,255)
    mycircle.id = “ABCDE”

    --sceneGroup:insert(mycircle)
    --sceneGroup:insert(text)

end

I don’t know how to do it, since I no longer have the scene group.

Or am I going to have to create another Lua file and let that scene:create(event)  create the circles?

I already thought of that and I can do it that way, just wondering if that is the best or only way to do it?

Note: I will be creating lots of circles.

Other questions if you don’t mind.  When you randomly create the circles, how do you make sure you don’t create one on top of another?  I mean I can manually calculate where to put them, but if I want to just randomly do it.  Also, can I create them ABOVE the device and let gravity let them fall into the screen?

Thank you in advance for any help you can provide me.

Hi.

You can just add another argument to your function, like

level1(self.view, arg1, arg2, arg3)

and then change the signature accordingly:

function level1 (group, one, two, three)

I seem to remember a fairly recent topic on your other question about keeping the elements separated, though maybe I’m mistaken. Anyhow, one way to do it would be something like the approach to shuffling a deck of cards and doling out the choices, where you start out with all the elements and then remove them one by one randomly until it’s empty, say:

local NumberOfColumns = 50 local NumberOfRows = 10 local NumberOfCircles = 100 -- NumberOfCircles \<= NumberOfColumns \* NumberOfRows local Spots local function InitLevel () Spots = {} for i = 1, NumberOfColumns \* NumberOfRows do Spots[i] = i end end -- Roughly where the circles spawn, vertically local YOffset = 300 -- Some position above the screen -- Size of a circle's box (for simplicity, here width = height) local Dim = math.ceil(display.contentWidth / NumberOfColumns) local function GetPosition () local n = #Spots -- Grab a random index. local i = math.random(n) local index = Spots[i] -- The index is considered to be used, so clear it. We don't care about order, -- so just overwrite it by moving the last element into its place. Spots[i] = Spots[n] Spots[n] = nil -- Convert the index into a column and row... local col = (index - 1) % NumberOfColumns local row = (index - col) / NumberOfColumns -- ...turn those into a position... local x, y = (col + .5) \* Dim, row \* Dim + YOffset -- ...and add a little offset (not too big, so neighbors don't penetrate) to -- break up the grid structure. local xoff = 2 \* math.random() + 1 -- Convert range from [0, 1] to [-1, +1] local yoff = 2 \* math.random() + 1 return math.floor(x + xoff \* .3 \* Dim), math.floor(y + yoff \* .3 \* Dim) end -- Other stuff -- local function level1 (group, one, two, three) InitLevel() for i = 1, NumberOfCircles do local circ = display.newCircle(group, 0, 0, 20) circ.x, circ.y = GetPosition() -- More stuff end end

(Untested!   :))

Putting them above is just a matter of choosing a nice YOffset.

Thanks!  That worked great with the group!

The other part was similar to a math solution I was talking about - forcing them into certain positions.  So, I guess we have to do it that way. Oh well.  Thanks!

If you need some separation, and all the balls come into existence at once, a jittered lattice like I showed, or a Poisson distribution, would be the way to go… but the latter is NOT cheap if you “will be creating lots of circles”, unless you invest some time in fancy algorithms.

You did mention gravity… another option would be to create some “floors” above the screen and activate / deactivate their physics objects to drop in balls on demand (perhaps once they’ve come to a rest).

Hi.

You can just add another argument to your function, like

level1(self.view, arg1, arg2, arg3)

and then change the signature accordingly:

function level1 (group, one, two, three)

I seem to remember a fairly recent topic on your other question about keeping the elements separated, though maybe I’m mistaken. Anyhow, one way to do it would be something like the approach to shuffling a deck of cards and doling out the choices, where you start out with all the elements and then remove them one by one randomly until it’s empty, say:

local NumberOfColumns = 50 local NumberOfRows = 10 local NumberOfCircles = 100 -- NumberOfCircles \<= NumberOfColumns \* NumberOfRows local Spots local function InitLevel () Spots = {} for i = 1, NumberOfColumns \* NumberOfRows do Spots[i] = i end end -- Roughly where the circles spawn, vertically local YOffset = 300 -- Some position above the screen -- Size of a circle's box (for simplicity, here width = height) local Dim = math.ceil(display.contentWidth / NumberOfColumns) local function GetPosition () local n = #Spots -- Grab a random index. local i = math.random(n) local index = Spots[i] -- The index is considered to be used, so clear it. We don't care about order, -- so just overwrite it by moving the last element into its place. Spots[i] = Spots[n] Spots[n] = nil -- Convert the index into a column and row... local col = (index - 1) % NumberOfColumns local row = (index - col) / NumberOfColumns -- ...turn those into a position... local x, y = (col + .5) \* Dim, row \* Dim + YOffset -- ...and add a little offset (not too big, so neighbors don't penetrate) to -- break up the grid structure. local xoff = 2 \* math.random() + 1 -- Convert range from [0, 1] to [-1, +1] local yoff = 2 \* math.random() + 1 return math.floor(x + xoff \* .3 \* Dim), math.floor(y + yoff \* .3 \* Dim) end -- Other stuff -- local function level1 (group, one, two, three) InitLevel() for i = 1, NumberOfCircles do local circ = display.newCircle(group, 0, 0, 20) circ.x, circ.y = GetPosition() -- More stuff end end

(Untested!   :))

Putting them above is just a matter of choosing a nice YOffset.

Thanks!  That worked great with the group!

The other part was similar to a math solution I was talking about - forcing them into certain positions.  So, I guess we have to do it that way. Oh well.  Thanks!

If you need some separation, and all the balls come into existence at once, a jittered lattice like I showed, or a Poisson distribution, would be the way to go… but the latter is NOT cheap if you “will be creating lots of circles”, unless you invest some time in fancy algorithms.

You did mention gravity… another option would be to create some “floors” above the screen and activate / deactivate their physics objects to drop in balls on demand (perhaps once they’ve come to a rest).