refresher on cross calling a function

I have a very simple problem that I am not understanding. In this mini game I just want to be able to touch touch 8 bees and they all play the same animations. The problem I am having is that bee is local and it needs to be global or needs to be crossed called… I viewed the scopes for functions tutorial but I am not sure if I am going about it right… Can someone point me in the right direction?

Here is my code :slight_smile:

[lua]display.setStatusBar( display.HiddenStatusBar ) – HIDE STATUS BAR

local i = 1

local loqsprite = require(‘loq_sprite’)

local screenW = display.contentWidth
local screenH = display.contentHeight

local BG = display.newImageRect(“background.png”, 1024, 768)
BG.x = screenW/2; BG.y = screenH/2

local bee = nil

local t1 = {

{x=180,y=300},
{x=280,y=300},
{x=380,y=300},
{x=480,y=300},
{x=580,y=300},
{x=680,y=300},
{x=780,y=300},
{x=880,y=300}

}

local function spawnBees ()
for i = 1,8 do
local bfactory = loqsprite.newFactory(“bee”)
bee = bfactory:newSpriteGroup()
bee.x = t1[i].x; bee.y = t1[i].y
bee:prepare(“aniBee Bee”)
end
end
listener = function( event )

local phase = event.phase

if ( phase == “ended” ) then

bee:play(“aniBee Bee”)

end
end

bee:addEventListener( “touch”, listener ) [/lua]

Thanks for any help! [import]uid: 51459 topic_id: 16350 reply_id: 316350[/import]

This should help - http://blog.anscamobile.com/2011/09/tutorial-modular-classes-in-corona/ [import]uid: 5833 topic_id: 16350 reply_id: 60932[/import]

Thanks @GrahamRanson [import]uid: 51459 topic_id: 16350 reply_id: 60935[/import]

I got the bees to show up but the touch event doesn’t work… :frowning:

[lua]display.setStatusBar( display.HiddenStatusBar ) – HIDE STATUS BAR

local i = 1

local loqsprite = require(‘loq_sprite’)

local screenW = display.contentWidth
local screenH = display.contentHeight

local BG = display.newImageRect(“background.png”, 1024, 768)
BG.x = screenW/2; BG.y = screenH/2
local t1 = {

{x=180,y=300},
{x=280,y=300},
{x=380,y=300},
{x=480,y=300},
{x=580,y=300},
{x=680,y=300},
{x=780,y=300},
{x=880,y=300}

}
local function spawnBees ()
local bee = nil
for i = 1,8 do
local bfactory = loqsprite.newFactory(“bee”)
bee = bfactory:newSpriteGroup()
bee.x = t1[i].x; bee.y = t1[i].y
bee:prepare(“aniBee Bee”)
end
end
local function onTouch(event)
if “ended” == event.phase then
–bee:play(“aniBee Bee”)
print(“touched bee”)
end

bee:addEventListener(“touch”,onTouch)
return bee
end
local xTemp = spawnBees ()[/lua] [import]uid: 51459 topic_id: 16350 reply_id: 60939[/import]

You’re adding the touch event listener within the touch event handler :slight_smile: [import]uid: 5833 topic_id: 16350 reply_id: 60942[/import]

I don’t know what you ment by that GrahamRanson ?:slight_smile:

Is this what you mean… If it is it, doesn’t do any thing either…

[lua]display.setStatusBar( display.HiddenStatusBar ) – HIDE STATUS BAR

local i = 1

local loqsprite = require(‘loq_sprite’)

local screenW = display.contentWidth
local screenH = display.contentHeight

local BG = display.newImageRect(“background.png”, 1024, 768)
BG.x = screenW/2; BG.y = screenH/2
local t1 = {

{x=180,y=300},
{x=280,y=300},
{x=380,y=300},
{x=480,y=300},
{x=580,y=300},
{x=680,y=300},
{x=780,y=300},
{x=880,y=300}

}

local function onTouch(event)
if “ended” == event.phase then
–bee:play(“aniBee Bee”)
print(“touched bee”)
end
end

local function spawnBees ()
local bee = nil
for i = 1,8 do
local bfactory = loqsprite.newFactory(“bee”)
bee = bfactory:newSpriteGroup()
bee.x = t1[i].x; bee.y = t1[i].y
bee:prepare(“aniBee Bee”)
end
bee:addEventListener(“touch”,onTouch)
return bee
end

local xTemp = spawnBees ()[/lua] [import]uid: 51459 topic_id: 16350 reply_id: 60951[/import]

In your spawnBees function you only add the event listener to the last bee created as it is added outside of the loop, give this a try:

  
local function spawnBees ()  
 local bee = nil  
 for i = 1,8 do  
 local bfactory = loqsprite.newFactory("bee")  
 bee = bfactory:newSpriteGroup()  
 bee.x = t1[i].x; bee.y = t1[i].y  
 bee:prepare("aniBee Bee")  
 bee:addEventListener("touch",onTouch)  
 end  
  
 return bee  
end  
  

You also only return the last bee spawned, if you want to access them later for instance when cleaning up your game you will want to store them in a table. [import]uid: 5833 topic_id: 16350 reply_id: 60964[/import]

Cool thanks GrahamRanson!! That makes a lot more sense now!! Thanks a bunch!

I SEE THE LIGHT! [import]uid: 51459 topic_id: 16350 reply_id: 60971[/import]

No problem, glad it helped. [import]uid: 5833 topic_id: 16350 reply_id: 60974[/import]

it helped all right! [import]uid: 51459 topic_id: 16350 reply_id: 60979[/import]

There are other scope problems…

   
local function spawnBees ()  
 local bee = nil  
 for i = 1,8 do  
 local bfactory = loqsprite.newFactory("bee")  
 bee = bfactory:newSpriteGroup()  
 bee.x = t1[i].x; bee.y = t1[i].y  
 bee:prepare("aniBee Bee")  
 end  
end  
   
   
local function onTouch(event)  
 if "ended" == event.phase then   
 --bee:play("aniBee Bee")  
 print("touched bee")   
 end  
   
 bee:addEventListener("touch",onTouch)  
 return bee  
end  

Ask yourself: “Where am I defining “bee”?”

In function spawnBees() you are defining "beeL to be local to spawnBees. When you are in that for loop, you’re assigning your sprite instance to the “bee” that only exists inside that function. Of course you are looping several times and overwriting the previous local bee’s you’ve created since your not storing them in an array.

In your onTouch function, you reference “bee” again, but you have not previously declared bee either in this function or the lua chunk that holds that function so that “bee” is a global variable that is never initialized and you’re adding eventListeners too.

I think I need to write a scoping tutorial. This comes up a lot.
[import]uid: 19626 topic_id: 16350 reply_id: 61006[/import]

So how do you suggest I fix this Rob? Do you want to use my example in your tutorial? [import]uid: 51459 topic_id: 16350 reply_id: 61019[/import]

create a table/array to hold all your bees near the top of your lua file not inside any function:

[lua]local bees = {}[/lua]

In your spawn function, do something like this:
[lua]local function spawnBees()
local i
for i = 1, 8 do
bees[i] = your code to create an individual bee
bees[i]:addEventListener(“touch”, onTouch)
end
end[/lua]
Your onTouch handler will need to be defined above spawnBees.

This is a very very common pattern for doing this type of function.
[import]uid: 19626 topic_id: 16350 reply_id: 61024[/import]

Thanks for the help Rob! I am a another small issue though… :frowning:

I want to click on each bee to play its animation… What going on is when I click on any of them only 1 bee plays the animation… How can I have more control over which bee I am clicking… Can you show me a how to make a print statement showing me which bee I have clicked?

Heres my updated code…

[lua]display.setStatusBar( display.HiddenStatusBar ) – HIDE STATUS BAR

local i = 1

local bees = {}

local loqsprite = require(‘loq_sprite’)

local screenW = display.contentWidth
local screenH = display.contentHeight
local BG = display.newImageRect(“background.png”, 1024, 768)
BG.x = screenW/2; BG.y = screenH/2

local t1 = {

{x=180,y=300},
{x=280,y=300},
{x=380,y=300},
{x=480,y=300},
{x=580,y=300},
{x=680,y=300},
{x=780,y=300},
{x=880,y=300}

}
local function onTouch(event)
if “ended” == event.phase then
bees[i]:play(“aniBee Bee”)
end
end

local function spawnBees ()
local i
for i = 1,8 do
local bfactory = loqsprite.newFactory(“bee”)
bees[i] = bfactory:newSpriteGroup()
bees[i].x = t1[i].x; bees[i].y = t1[i].y
bees[i]:prepare(“aniBee Bee”)
bees[i]:addEventListener(“touch”,onTouch)
end

return bee
end

local xTemp = spawnBees ()[/lua]

Thanks for any suggestions!
[import]uid: 51459 topic_id: 16350 reply_id: 61088[/import]

I see one real problem and one potential problem:
[lua]local function onTouch(event)
if “ended” == event.phase then
bees[i]:play(“aniBee Bee”)
end
end[/lua]

What value is ‘i’ at this point?
Which bee was clicked on? Was it bee[i]?

The object “event” passed to onTouch has a member called “target”. That object is the actual be that was touched. Changing this function to something like:

[lua]local function onTouch(event)
if “ended” == event.phase then
event.target:play(“aniBee Bee”)
end
end[/lua]

will likely solve your problem.

The other issue is that

[lua]local bfactory = loqsprite.newFactory(“bee”)[/lua]

only exists inside of that for loop. You are creating 8 “bfactory” objects, and overwriting the pointer to them (Memory leak). I don’t know how loqsprite works, but I suspect you only want one copy of that object and it probably should stay accessable until you dispose of it later. I would consider moving that line outside of any function.
[import]uid: 19626 topic_id: 16350 reply_id: 61111[/import]

Thanks Rob everything works!!

Your the man!! [import]uid: 51459 topic_id: 16350 reply_id: 61130[/import]