Newbie question about event.target

I want to assign an event listener to an object, whereby I get the details of the object via the event.target code.

As a test, I have a ball graphic with the following code:

  
ball:addEventListener ("touch", onPressBall )  
  
And my listener code is as follows:  
  
local onPressBall = function ( event )  
  
 event.target:addEventListener ("touch", onReleaseBall )  
  
end  
  

I am getting an “assertion failed!” error so assume my syntax is not correct. Any help much appreciated.

Essentially I want to detect when the user presses on the ball and then when they release the ball.

Thanks

Paul [import]uid: 7863 topic_id: 2219 reply_id: 302219[/import]

Try this:

[code]

local function onPressBall(event)

event.target:addEventListener (“touch”, onReleaseBall )

end

ball:addEventListener (“touch”, onPressBall )
[/code] [import]uid: 7356 topic_id: 2219 reply_id: 6714[/import]

Thanks Magenda but unfortunately I am still getting an error. Here is my exact code.

  
local ball1 = display.newImage("ball1\_30.png", 10,50)  
  
local function onPressBall ( event )  
  
 print (event.target)  
  
  
  
  
 event.target:addEventListener ("touch", onReleaseBall )  
  
  
  
end  
local function onReleaseBall ( event )  
  
  
 print (event.target)  
  
  
end  
  

My error in the terminal is

**The file sandbox for this project is located at the following folder:

table: 0x3ae400
Runtime error
assertion failed!
stack traceback:
[C]: ?
[C]: in function ‘assert’
?: in function ‘getOrCreateTable’
?: in function ‘addEventListener’**
[import]uid: 7863 topic_id: 2219 reply_id: 6716[/import]

Thanks Magenda, I need the code to work for more than one ball which is why I was hoping I could add an event listener to the particular ball being pressed.

Frustrating as I cannot find any info on this which may be just me being pants at searching. [import]uid: 7863 topic_id: 2219 reply_id: 6718[/import]

I am not on a Mac now to test it (and I am also a Lua newbie) but try something like this…

system.activate( "multitouch" ) --cannot try now if this is actually needed  
  
local ball = display.newImage("ball1\_30.png", 10,50)  
   
local function onTap ( event )   
 print (event.name)   
 if "began"==event.phase then   
 print("Ball has been touched")  
 elseif "moved"==event.phase then  
 print("Ball is being moved")  
 elseif "ended"==event.phase then  
 print("Ball has been left in peace")   
 end  
end  
  
ball1:addEventListener ("touch", onTap )  

See event.phase for more info on touch phases.

[import]uid: 7356 topic_id: 2219 reply_id: 6717[/import]

Maybe you also need to add:

system.activate( "multitouch" )

…on the first line

(I have edited the code above… see it again plz) [import]uid: 7356 topic_id: 2219 reply_id: 6720[/import]

Thank you so much Magenda for helping me with this.

I tried the event.target.name and it gave me a value of “nil”

Anyway I found another thread here http://developer.anscamobile.com/forum/2010/03/07/dynamically-generate-event-listeners and it seems I need to give each ball a property that I can access via event.target.property

So I have done the following:

  
ball1.ballId = 1  
  
local function onPressBall ( event )  
  
 print (event.target.ballId)  
  
 if event.target.ballId == 1 then  
  
 ball1:addEventListener ("touch", onReleaseBall )  
  
 elseif event.target.ballId == 2 then  
  
 ball2:addEventListener ("touch", onReleaseBall )  
  
 end  
end  
  

I will need to search to see if it is possible to optimise the code to remove the if statement

ie something like

[code]

ball…event.target.ballId:addEventListener (“touch”, onReleaseBall )

[/code] [import]uid: 7863 topic_id: 2219 reply_id: 6721[/import]

What about this?

local ball1 = display.newImage("ball1\_30.png", 50,100) -- ball 1  
local ball2 = display.newImage("ball1\_30.png", 100,100) -- ball 2  
local ball3 = display.newImage("ball1\_30.png", 200,100) -- ball 3  
   
local function onTap ( event )   
  
 if "began"==event.phase then   
 print(event.target.name + " has been pressed")  
 elseif "moved"==event.phase then  
 print(event.target.name + " is being touched")  
 elseif "ended"==event.phase then  
 print(event.target.name + " has been left in peace")   
 end  
end  
   
ball1:addEventListener ("touch", onTap )  
ball2:addEventListener ("touch", onTap )  
ball3:addEventListener ("touch", onTap )  

[import]uid: 7356 topic_id: 2219 reply_id: 6719[/import]

Don’t forget to implement the onReleaseBall handler function above your onPressBall handler.
I’ll try to optimize this code when getting home in some minutes… [import]uid: 7356 topic_id: 2219 reply_id: 6722[/import]

Thanks Magenda and apologies for not picking up on your code using the phase functionality. I will have a look at that.

In the meantime, I have had to amend my code as follows to get it to work. I would be very grateful for any advice on how to optimize this code as this is my first game using Corona.

  
local ball1 = display.newImage("ball1\_30.png", 50, 100)  
local ball2 = display.newImage("ball1\_30.png", 100, 100)  
  
ball1.ballId = 1  
ball2.ballId = 2  
local function onReleaseBall ( event )  
  
 print ("release ball" .. event.target.ballId)  
  
end  
  
local function onPressBall ( event )  
  
 print ("press ball" .. event.target.ballId)  
  
 local ballPressedId = event.target.ballId  
  
  
  
 if event.target.ballId == 1 then  
  
 print ("ball 1 pressed")  
 ball1.removeEventListener( "touch", onPressBall )  
 ball1.addEventListener( "touch", onReleaseBall )  
  
 elseif event.target.ballId == 2 then  
  
 print ("ball 2 pressed")  
 ball2.removeEventListener( "touch", onPressBall )  
 ball2.addEventListener( "touch", onReleaseBall )  
 end  
  
end  
  
ball1:addEventListener( "touch", onPressBall )  
ball2:addEventListener( "touch", onPressBall )  
  

[import]uid: 7863 topic_id: 2219 reply_id: 6723[/import]

Magenda I have had a test of the phase functionality and it appears not to recognise when I remove the finger when it is not over the ball. What I need to do is detect when a ball is clicked then carry out a task until the user lifts their finger and the finger may not necessarily be over the ball when the finger is removed. Having said that, my release function is called as soon as I move my finger off the ball so that isn’t any good either:( [import]uid: 7863 topic_id: 2219 reply_id: 6726[/import]

With regards recognising when finger released the following code seemed promising but is giving me errors

  
if "began" == phase then  
  
 display.getCurrentStage().setFocus(ball1)  
  
 elseif "ended" == phase then  
  
 display.getCurrentStage().setFocus(nil)  
  
 end  

This actually crashes the Simulator with the following error in the terminal prior to this

ERROR: Argument(1) is not a StageObject
[import]uid: 7863 topic_id: 2219 reply_id: 6729[/import]

mediakitchen, when you lift your finger from the screen at a point outside the ball the listeners of the ball do not “listen” anything. So you need to involve information from Runtime listeners and combine it with the state of your balls to find out which ball had been pressed before the finger lift outside the ball.

Other than this, I can only think of implementing your handlers with an “enterframe” event, which of course would be kind of “lower level” handling.
Also, there is a “Joystick” sample by Matthew Pringle. Take a look if his approach helps you. [import]uid: 7356 topic_id: 2219 reply_id: 6735[/import]

Thanks Magenda

I came across this code to set the focus to a particular object and have managed to get the finger released outside the ball recognised with the following code

  
local stage = display.getCurrentStage()  
  
 if "began" == phase then  
  
 if event.target.ballId == 1 then  
  
 stage:setFocus(ball1)  
  
 elseif event.target.ballId == 2 then  
  
 stage:setFocus(ball2)  
  
 end  
  
  
 elseif "ended" == phase then  
  
 stage:setFocus(nil)  
  
 end  
  

Ideally I would like to remove the if statements for the stage:setFocus(ballX) but my attempts failed. I have posted separately asking about concatenation of strings to create an object reference.

Thanks for the joystick link - I hadn’t seen that yet.

You suggested using an enterFrame event - is that an alternative to using the listener? If so then is it more efficient. I was planning to use en enterFrame function for my main game loop but not sure what alternative to listeners there are apart from writing code to detect the position of the cursor and if it is over a ball.

Thanks

Paul

[import]uid: 7863 topic_id: 2219 reply_id: 6736[/import]

According to my understanding of how Corona/Lua works, listeners are simply an abstracted level of frame updates handling (which is itself the generic “enterframe” listener). So if there is no listener for what you need, you can always implement it by analyzing the information provided in each frame. And yes, in your situation you would check to see where the finger is at each frame and you would build a custom “touch” listener (basically a function called on “enterframe”).

Having said that, I am sure that somebody, more experienced in Lua, is going to join this conversation and give you some easier solution within the next hours ! :slight_smile: [import]uid: 7356 topic_id: 2219 reply_id: 6743[/import]

Well, the following works ok for me:

local ball1 = display.newImage("ball1\_30.png", 0,100) -- ball 1  
local ball2 = display.newImage("ball1\_30.png", 100,100) -- ball 2  
local ball3 = display.newImage("ball1\_30.png", 200,100) -- ball 3  
   
local function onTap ( event )   
  
 if "began"==event.phase then   
 print( "A ball has been pressed")  
 elseif "moved"==event.phase then  
 print( "A ball is being touched")  
 display.getCurrentStage():setFocus( event.target )  
  
 elseif "ended"==event.phase then  
 print( "A ball has been left in peace")  
 display.getCurrentStage():setFocus( nil )   
 end  
end  
   
ball1:addEventListener ("touch", onTap )  
ball2:addEventListener ("touch", onTap )  
ball3:addEventListener ("touch", onTap )  

But you intrigued me to find out how I could conveniently get the name of the specific ball without adding identifiers, if possible. Will see… [import]uid: 7356 topic_id: 2219 reply_id: 6744[/import]

Hey thanks Magenda - I will try your syntax.

That would be great if you can find a solution not requiring identifiers.

Thanks for all your help!!

Paul [import]uid: 7863 topic_id: 2219 reply_id: 6745[/import]