how to add and event listener to an object in for i loop

hello…

I have a for i loop.

many objects (30)

how can I add an event listener to each of them

if I want each of them do a different action

when you touch them

I have this

    function tt( event )         if ( event.phase == "began" ) then             if ball[1] == 1 then                    bg.alpha = .2                else                    bg.xScale = 3                end         end         return true     end          for i = 1, many do         ball[i] = display.newSprite( crazyBallImage, sequenceCrazyBall )         sceneGroup:insert(ball[i])         ball[i].x = display.contentCenterX         ball[i].y = display.contentCenterY         ball[i].xScale = .5         ball[i].yScale = .5         ball[i].setSequence = "bb"         ball[i]:play()         ball[i]:addEventListener( "touch", tt )     end

is a simple function but I can not make it to work

thanks for your help

victor

If you want to add different listeners to different objects then you’ll have to make multiple functions that make those objects.

–SonicX278

No you don’t, not if they only perform slight variations on a basic function.

The reason the code doesn’t work is this line:

if ball[1] == 1 then

ball[1] does not equal 1, it is a display object created here:

ball[i] = display.newSprite( crazyBallImage, sequenceCrazyBall )

I assume what you are trying to do is check “if the object I’m touching is ball 1 then change the bg alpha to 0.2”?  

In this case, what you should do is give each “ball” an extra property when you create it:

for i = 1, many do ball[i] = display.newSprite( crazyBallImage, sequenceCrazyBall ) sceneGroup:insert(ball[i]) ball[i].x = display.contentCenterX ball[i].y = display.contentCenterY ball[i].xScale = .5 ball[i].yScale = .5 ball[i].setSequence = "bb" ball[i]:play() ball[i]:addEventListener( "touch", tt ) ball[i].myNumber = i --this is the new property end

Then in the touch function, check what the value of the “myNumber” property is for the object being touched:

function tt( event ) if ( event.phase == "began" ) then if event.target.myNumber == 1 then bg.alpha = .2 else bg.xScale = 3 end end return true end

Note that I am using “event.target” in the touch function. event.target refers to the object that triggered the touch function.

local function onTouch( self, event ) print( self.num, event.phase ) end for i = 1, 10 do local tmp = display.newCircle( 15 \* i, 10, 10 ) tmp.num = i tmp.touch = onTouch tmp:addEventListener( "touch" ) end

Thanks Alan… your code works!!!

and Roaminggamer … I got your code and it prints on terminal the numbers I touch

both of you thanks…

one little thing more…

I have this function

    function tt( event )         if ( event.phase == "began" ) then             if event.target.myNumber == 1 then                    ball[1].alpha = .2                elseif event.target.myNumber == 2 then                    ball[2].xScale = 3                elseif event.target.myNumber == 3 then                    ball[3].yScale = 2                elseif event.target.myNumber == 4 then                    ball[4].alpha = 0                else                    bg.xScale = 3                end         end         return true     end

And it works great, the circle I touch it works

but i only have 4 circles…

what if I have 50 circles I think there is a better way to do this

50 times

            if event.target.myNumber == 1 then
                   ball[1].alpha = .2
               elseif event.target.myNumber == 2 then
                   etc etc…

thanks

If you need the 50 circles to do different things, then yes you would need to do:

 if event.target.myNumber == 1 then ball[1].alpha = .2 elseif event.target.myNumber == 2 then etc etc....

If each circle is going to do the same thing, then you can just change the function to do this:

event.target.alpha = .2

Or if you need a group of the circles to do one thing, and others to do something else, then you just need to come up with some logic that defines what you need them to do:

–every group of ten items behaves the same

if event.target.myNumber \< 10 then ball[1].alpha = .2 elseif event.target.myNumber \< 20 then etc etc....

or

--this would make circles 1, 2, 3, 4 behave differently --circles 5, 6, 7, 8 would behave the same as 1, 2, 3, 4 and so on. if event.target.myNumber % 4 == 0 then event.target.alpha = .1 elseif event.target.myNumber % 4 == 1 then event.target.alpha = .2 elseif event.target.myNumber % 4 == 2 then event.target.alpha = .3 elseif event.target.myNumber % 4 == 3 then event.target.alpha = .4

@Alan QuizTix gives a good answer.

let’s assume that since you’ve written the example with each object doing something UNIQUE on touch, that that is in fact your requirement.  (otherwise, as Alan stated, the answer is trivially easy, fe:  event.target.alpha=0.2)

there are several ways you might avoid using a massive if statement.  (the caveat being that you’ll need something else potentially “equally massive” to make those decisions)  you could define a method on each of your objects to handle the logic “inside” of a shared touch handler, then call that, fe:  event.target:uniqueTouchLogic()

or, if the behaviors aren’t ENTIRELY unique (maybe just SOMEWHAT unique, like Alan’s groups of 10 example) then you could define whatever handful of logic functions you need, then create a “dispatch” table for each of your 50 objects, fe:

local function logic1(object) object.alpha = 0.2 end local function logic2(object) object.xScale = 0.3 end local function logic3(object) object.yScale = 0.4 end local logicDispatchTable = { logic1, -- function to dispatch for object #1 logic2, -- function to dispatch for object #2 -- ... 50 total entries ... logic3, -- function to dispatch for object #50 } -- inside touch handler: logicDispatchTable[event.target.myNumber](event.target)

If you want to add different listeners to different objects then you’ll have to make multiple functions that make those objects.

–SonicX278

No you don’t, not if they only perform slight variations on a basic function.

The reason the code doesn’t work is this line:

if ball[1] == 1 then

ball[1] does not equal 1, it is a display object created here:

ball[i] = display.newSprite( crazyBallImage, sequenceCrazyBall )

I assume what you are trying to do is check “if the object I’m touching is ball 1 then change the bg alpha to 0.2”?  

In this case, what you should do is give each “ball” an extra property when you create it:

for i = 1, many do ball[i] = display.newSprite( crazyBallImage, sequenceCrazyBall ) sceneGroup:insert(ball[i]) ball[i].x = display.contentCenterX ball[i].y = display.contentCenterY ball[i].xScale = .5 ball[i].yScale = .5 ball[i].setSequence = "bb" ball[i]:play() ball[i]:addEventListener( "touch", tt ) ball[i].myNumber = i --this is the new property end

Then in the touch function, check what the value of the “myNumber” property is for the object being touched:

function tt( event ) if ( event.phase == "began" ) then if event.target.myNumber == 1 then bg.alpha = .2 else bg.xScale = 3 end end return true end

Note that I am using “event.target” in the touch function. event.target refers to the object that triggered the touch function.

local function onTouch( self, event ) print( self.num, event.phase ) end for i = 1, 10 do local tmp = display.newCircle( 15 \* i, 10, 10 ) tmp.num = i tmp.touch = onTouch tmp:addEventListener( "touch" ) end

Thanks Alan… your code works!!!

and Roaminggamer … I got your code and it prints on terminal the numbers I touch

both of you thanks…

one little thing more…

I have this function

&nbsp;&nbsp;&nbsp; function tt( event ) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( event.phase == "began" ) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.target.myNumber == 1 then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ball[1].alpha = .2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; elseif event.target.myNumber == 2 then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ball[2].xScale = 3 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;elseif event.target.myNumber == 3 then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ball[3].yScale = 2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; elseif event.target.myNumber == 4 then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ball[4].alpha = 0 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bg.xScale = 3 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return true &nbsp;&nbsp; &nbsp;end

And it works great, the circle I touch it works

but i only have 4 circles…

what if I have 50 circles I think there is a better way to do this

50 times

            if event.target.myNumber == 1 then
                   ball[1].alpha = .2
               elseif event.target.myNumber == 2 then
                   etc etc…

thanks

If you need the 50 circles to do different things, then yes you would need to do:

 if event.target.myNumber == 1 then ball[1].alpha = .2 elseif event.target.myNumber == 2 then etc etc....

If each circle is going to do the same thing, then you can just change the function to do this:

event.target.alpha = .2

Or if you need a group of the circles to do one thing, and others to do something else, then you just need to come up with some logic that defines what you need them to do:

–every group of ten items behaves the same

if event.target.myNumber \< 10 then ball[1].alpha = .2 elseif event.target.myNumber \< 20 then etc etc....

or

--this would make circles 1, 2, 3, 4 behave differently --circles 5, 6, 7, 8 would behave the same as 1, 2, 3, 4 and so on. if event.target.myNumber % 4 == 0 then event.target.alpha = .1 elseif event.target.myNumber % 4 == 1 then event.target.alpha = .2 elseif event.target.myNumber % 4 == 2 then event.target.alpha = .3 elseif event.target.myNumber % 4 == 3 then event.target.alpha = .4

@Alan QuizTix gives a good answer.

let’s assume that since you’ve written the example with each object doing something UNIQUE on touch, that that is in fact your requirement.  (otherwise, as Alan stated, the answer is trivially easy, fe:  event.target.alpha=0.2)

there are several ways you might avoid using a massive if statement.  (the caveat being that you’ll need something else potentially “equally massive” to make those decisions)  you could define a method on each of your objects to handle the logic “inside” of a shared touch handler, then call that, fe:  event.target:uniqueTouchLogic()

or, if the behaviors aren’t ENTIRELY unique (maybe just SOMEWHAT unique, like Alan’s groups of 10 example) then you could define whatever handful of logic functions you need, then create a “dispatch” table for each of your 50 objects, fe:

local function logic1(object) object.alpha = 0.2 end local function logic2(object) object.xScale = 0.3 end local function logic3(object) object.yScale = 0.4 end local logicDispatchTable = { logic1, -- function to dispatch for object #1 logic2, -- function to dispatch for object #2 -- ... 50 total entries ... logic3, -- function to dispatch for object #50 } -- inside touch handler: logicDispatchTable[event.target.myNumber](event.target)