@Diego
Re: First examples and Listeners
You can attach a listener to anything, but I probably typoed part of my code. Let me explain how listeners work and the different varieties you will see.
Tables vs. Other Objects
Please be aware, that all ‘objects’ in Corona are Lua Tables. i.e. display.newImageRect() returns an object which is a Lua Table + extra code attached for Corona. However, it behaves and is treated just like a table.
Function Listener vs. Table Listener
I found these terms very confusing when I first started working with Corona. However, at the end of the day, the thing to remember is that function listeners are standalone functions, not associated with an object. They can be local or global. On the other hand, table listeners are functions/methods associated with some object (a table).
Runtime vs Object Events
To further confuse things, you have Runtime and Object originated events. The prior are generally system events (GPS, orientation, etc.) but also includes the global touch event. The latter are specific to objects and include touch, collision, preCollision, etc.
Now, let me show you some syntax rules and terms to help you understand how things work in Corona.
Example #1 - Runtime Function Listener
local function theListener( event ) print(event.x,event.y) end Runtime:addEventListener( "touch", theListener ) -- Read the above as, -- -- Send the Runtime event "touch" to the function 'theListener' for processing. -- The function 'theListener' will be passed a single table containing the event information.
Example #2 - Runtime Table Listener
local function theListener( self, event ) -- Self is the object this function is attached to. print(event.x,event.y) end local someObject = display.newCircle( 100, 100, 10 ) someObject.touch = theListener -- Notice how name of method field matches the name of the event. Runtime:addEventListener( "touch", someObject ) -- Read the above as, -- -- Send the Runtime event "touch" to the method 'touch' attached to the object 'someObject'. -- The method 'touch' references the local function 'theListener' and will -- automatically be passed a reference to 'someObject' (as argument self), and the event table -- (as argument event.)
Example #3 -Object Function Listener
local function theListener( event ) print(event.x,event.y) end local someObject = display.newCircle( 100, 100, 10 ) someObject:addEventListener( "touch", theListener ) -- Read the above as, -- -- Send the object event "touch" to the local function 'theListener'. -- Automatically passed an event table (as argument event.) -- -- Note: event.target will be a reference to the touched object which is 'someObject'. --
Example #4 -Object Table Listener
local function theListener( self, event ) -- Self is the object this function is attached to. print(event.x,event.y) end local someObject = display.newCircle( 100, 100, 10 ) someObject.touch = theListener -- Notice how name of method field matches the name of the event. someObject:addEventListener( "touch", someObject ) -- Second argument is optional in this case -- and implied if left blank. -- Read the above as, -- -- Send the object event "touch" to the method 'touch' attached to the object 'someObject'. -- The method 'touch' references the local function 'theListener' and will -- automatically be passed a reference to 'someObject' (as argument self), and the event table -- (as argument event.) --
Example #5 -Object Table Listener - Using a Proxy Object (Very Rare)
local function theListener( self, event ) -- self is the 'proxy object' -- event.target is the object we touched. print(event.x,event.y) end local someObject = display.newCircle( 100, 100, 10 ) local someObject2 = display.newCircle( 200, 200, 10 ) -- Create a 'proxy' object to process the touch events for my two objects local proxyObject = {} proxyObject.touch = theListener someObject:addEventListener( "touch", proxyObject ) someObject2:addEventListener( "touch", proxyObject ) -- Read the above as, -- -- Send the object event "touch" to the method 'touch'attached to the proxy object 'proxyObject'. -- -- The method 'touch' which refers to the local function 'theListener' and will -- automatically be passed a reference to 'proxyObject' (as argument self), -- To get a reference to the touched object, look at the field event.target, -- in the event table (argument event).
Benefits and Drawbacks Of Variations
- Benefits
- Example 1 - Catches touch events anywhere. Processes after all object touches in that touch location. Cannot be blocked by another listener returning true.
- Example 2 - Wonderful for enterFrame and other system events that you want to funnel to specific objects.
- Example 3 - Centralizes processing to one function (personally I don’t like this however). Saves memory.
- Example 4 - Also saves memory if you maintain proper scope when defining the listener. Has added benefit of clearly providing a reference to the touched object. Lastly, it self-cleans when you delete the object. i.e. You don’t need to call removeEventListener()
- Example 5 - Useful for advanced techniques like creating behavior libraries, etc.
- Drawbacks
- Example 1 - You must clean this up yourself. i.e. Must later call removeEventListener()
- Example 2 - You must clean this up yourself. i.e. Must later call removeEventListener()
- Example 3 - You must clean this up yourself. i.e. Must later call removeEventListener()
- Example 4 - If done wrong, this wastes a lot of space. i.e. If you define a new function for every object, you use up the memory for that function in addition to the object. So, scope is key.
- Example 5 - Confusing to grok and error prone on the cleanup.