Difference between revisions of "Event system"

From GiderosMobile
(first draft)
 
 
(9 intermediate revisions by 2 users not shown)
Line 6: Line 6:
  
 
== Introduction to events ==
 
== Introduction to events ==
 +
Events are the central mechanism to handle responses and they allow to create interactive applications.
  
Events are the central mechanism to handle responses and they allow to create interactive applications. All classes that dispatch events inherit from EventDispatcher. The target of an event is a listener function and an optional data value. When an event is dispatched, the registered function is called. If the optional data value is given, it is used as a first parameter while calling the listener function.
+
All classes that dispatch events inherit from EventDispatcher. The target of an event is a listener function and an optional data value.
<br/>
+
 
 +
When an event is dispatched, the registered function is called. If the optional data value is given, it is used as a first parameter while calling the listener function.
  
 
In Gideros, events can be divided into two categories:
 
In Gideros, events can be divided into two categories:
<br/>
 
 
* built-in events which are generated by the system (e.g. ENTER_FRAME event, touch events, timer events, etc.)
 
* built-in events which are generated by the system (e.g. ENTER_FRAME event, touch events, timer events, etc.)
* and custom events which can be generated by the user.
+
* custom events which can be generated by the user.
<br/>
 
  
 
According to their event type, built-in events can be broadcasted to multiple targets (e.g. ENTER_FRAME event, touch events, etc.) or can be dispatched to a single target (e.g. timer event).
 
According to their event type, built-in events can be broadcasted to multiple targets (e.g. ENTER_FRAME event, touch events, etc.) or can be dispatched to a single target (e.g. timer event).
  
 
== ENTER_FRAME Event ==
 
== ENTER_FRAME Event ==
 
+
The Gideros runtime dispatches the built-in '''Event.ENTER_FRAME''' event to Sprite instances before rendering the screen. Visual changes made by any Event.ENTER_FRAME listener function will be visible at next frame.
The Gideros runtime dispatches the built-in Event.ENTER_FRAME event to Sprite instances before rendering the screen. Visual changes made by anyEvent.ENTER_FRAME listener function will be visible at next frame.
 
<br/>
 
  
 
This first basic example shows a moving sprite one pixel to the right at each frame. In this example, onEnterFrame function increases the x-coordinate of a sprite object at each frame:
 
This first basic example shows a moving sprite one pixel to the right at each frame. In this example, onEnterFrame function increases the x-coordinate of a sprite object at each frame:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local sprite = Sprite.new()
 
local sprite = Sprite.new()
 
local function onEnterFrame(event)
 
local function onEnterFrame(event)
Line 32: Line 28:
 
end
 
end
 
sprite:addEventListener(Event.ENTER_FRAME, onEnterFrame)
 
sprite:addEventListener(Event.ENTER_FRAME, onEnterFrame)
</source>
+
</syntaxhighlight>
<br/>
 
  
 
The next example shows 3 independent sprites moving one pixel to the right at each frame. In this example, we use the optional data parameter to move independent sprites with one common listener function:
 
The next example shows 3 independent sprites moving one pixel to the right at each frame. In this example, we use the optional data parameter to move independent sprites with one common listener function:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local sprite1 = Sprite.new()
 
local sprite1 = Sprite.new()
 
local sprite2 = Sprite.new()
 
local sprite2 = Sprite.new()
Line 48: Line 41:
 
sprite2:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite2)
 
sprite2:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite2)
 
sprite3:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite3)
 
sprite3:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite3)
</source>
+
</syntaxhighlight>
<br/>
 
  
 
The last example shows subclassing of the Sprite class and registering Event.ENTER_FRAME:
 
The last example shows subclassing of the Sprite class and registering Event.ENTER_FRAME:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
MySprite = gideros.class(Sprite)
 
MySprite = gideros.class(Sprite)
 
function MySprite:init()
 
function MySprite:init()
Line 62: Line 52:
 
   self:setX(self:getX() + 1)
 
   self:setX(self:getX() + 1)
 
end
 
end
</source>
+
</syntaxhighlight>
<br/>
 
  
'''Note:''' Event.ENTER_FRAME event is dispatched to all Sprite instances no matter these instances are on the scene tree or not.
+
'''Note''': Event.ENTER_FRAME event is dispatched to all Sprite instances no matter if these instances are on the scene tree or not.
'''Note:''' When the ENTER_FRAME event dispatches, the event object contains time and deltaTime. Consider the following example:
 
<br/>
 
  
<source lang="lua">
+
'''Note''': when the ENTER_FRAME event dispatches, the event object contains time and deltaTime. Consider the following example:
 +
<syntaxhighlight lang="lua">
 
local function onEnterFrame(event)
 
local function onEnterFrame(event)
 
print(event.time, event.deltaTime)
 
print(event.time, event.deltaTime)
 
end
 
end
 
stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
 
stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
</source>
+
</syntaxhighlight>
  
 
== Mouse and touch events ==
 
== Mouse and touch events ==
 
 
Gideros runtime dispatches mouse and touch events when the the user’s finger touches the screen. Mouse events are mainly used in single-touch whereas touch events are used in multi-touch applications.
 
Gideros runtime dispatches mouse and touch events when the the user’s finger touches the screen. Mouse events are mainly used in single-touch whereas touch events are used in multi-touch applications.
<br/>
 
  
 
The mouse and touch events are dispatched to Sprite instances which are on the scene tree. If a Sprite instance is not on the scene tree, this instance doesn’t receive mouse and touch events.
 
The mouse and touch events are dispatched to Sprite instances which are on the scene tree. If a Sprite instance is not on the scene tree, this instance doesn’t receive mouse and touch events.
<br/>
 
  
'''Note:''' Even if touch or mouse doesn’t hit the Sprite instance, the instance receives mouse/touch events.
+
'''Note''': even if touch or mouse doesn’t hit the Sprite instance, the instance receives mouse/touch events.
<br/>
+
 
 +
The order of dispatch is determined by the hierarchy of the scene tree. The Sprite instance that is drawn last (top-most sprite) receives the event first. The next sprite at the bottom of the top-most sprite receives the event second and so on. For example, assume that we have an sprite hierarchy like this:
  
The order of dispatch is determined by the hierachy of the scene tree. The Sprite instance that is drawn last (top-most sprite) receives the event first. The next sprite at the bottom of the top-most sprite receives the event second and so on. For example, assume that we have an sprite hierachy like this:
 
<br/>
 
 
[[File:Sprite_hierarchy.png]]
 
[[File:Sprite_hierarchy.png]]
<br/>
 
  
 
which is constructed by the code below:
 
which is constructed by the code below:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local A = Sprite.new()
 
local A = Sprite.new()
 
local B = Sprite.new()
 
local B = Sprite.new()
Line 107: Line 88:
 
B:addChild(E)
 
B:addChild(E)
 
C:addChild(F)
 
C:addChild(F)
</source>
+
</syntaxhighlight>
<br/>
 
  
In this hiearchy, the drawing order is A, B, C, D, E, F while mouse/touch event receive order is F, E, D, C, B, A.
+
In this hierarchy, the drawing order is A, B, C, D, E, F while mouse/touch event receive order is F, E, D, C, B, A.
  
 
== Stopping an event dispatch ==
 
== Stopping an event dispatch ==
 +
It is possible to stop the propagation of mouse and touch events. To stop an event dispatch, invoke the Event:stopPropagation() function on the Eventobject passed to the listener function.
  
It is possible to stop the propagation of mouse and touch events. To stop an event dispatch, invoke the Event:stopPropagation() function on the Eventobject passed to the listener function. In this example below, MOUSE_DOWN event is dispatched only to F, E, D and C:
+
In the example below, MOUSE_DOWN event is dispatched only to F, E, D and C:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local A = Sprite.new()
 
local A = Sprite.new()
 
local B = Sprite.new()
 
local B = Sprite.new()
Line 133: Line 112:
 
B:addChild(E)
 
B:addChild(E)
 
C:addChild(F)
 
C:addChild(F)
</source>
+
</syntaxhighlight>
<br/>
 
  
'''Note:''' stopPropagation is only for mouse and touch events. Because only for them there is a definite dispatching order (the display object on top receives the event first).
+
'''Note''': stopPropagation is only for mouse and touch events. Because only for them there is a definite dispatching order (the display object on top receives the event first).
  
 
== Timer events ==
 
== Timer events ==
 +
The Timer class is used for executing code at specified time intervals. Each Timer object dispatches Event.TIMER event at specified frequency.
  
The Timer class is used for executing code at specified time intervals. Each Timer object dispatches Event.TIMER event at specified frequency.
 
 
The steps to use Timer class are as follows:
 
The steps to use Timer class are as follows:
<br/>
 
  
 
1- Create a new Timer object with specified frequency and specified total number of Event.TIMER events to be triggered. For example, the following code sets the frequency to 1000 miliseconds and sets the count to 5:
 
1- Create a new Timer object with specified frequency and specified total number of Event.TIMER events to be triggered. For example, the following code sets the frequency to 1000 miliseconds and sets the count to 5:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local timer = Timer.new(1000, 5)
 
local timer = Timer.new(1000, 5)
</source>
+
</syntaxhighlight>
<br/>
 
  
 
2- Register to the Event.TIMER event with a listener function:
 
2- Register to the Event.TIMER event with a listener function:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local function onTimer(event)
 
local function onTimer(event)
 
-- will be executed 5 times at 1000 milliseconds intervals
 
-- will be executed 5 times at 1000 milliseconds intervals
 
end
 
end
 
timer:addEventListener(Event.TIMER, onTimer)
 
timer:addEventListener(Event.TIMER, onTimer)
</source>
+
</syntaxhighlight>
<br/>
 
 
 
3- Start the timer.
 
<br/>
 
  
<source lang="lua">
+
3- Start the timer:
 +
<syntaxhighlight lang="lua">
 
timer:start()
 
timer:start()
</source>
+
</syntaxhighlight>
<br/>
 
  
 
4- To stop the timer, you can use Timer:stop() function:
 
4- To stop the timer, you can use Timer:stop() function:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
timer:stop()
 
timer:stop()
</source>
+
</syntaxhighlight>
<br/>
 
  
 
Event.TIMER_COMPLETE event is triggered after finishing the specified number of timer events.
 
Event.TIMER_COMPLETE event is triggered after finishing the specified number of timer events.
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
local function onTimerComplete(event)
 
local function onTimerComplete(event)
 
-- will be executed after the specified  
 
-- will be executed after the specified  
Line 188: Line 151:
 
end
 
end
 
timer:addEventListener(Event.TIMER_COMPLETE, onTimerComplete)
 
timer:addEventListener(Event.TIMER_COMPLETE, onTimerComplete)
</source>
+
</syntaxhighlight>
<br/>
 
  
 
Also, it is possible to pause and resume all the timers in your application. It is very useful when you are implementing a pause/resume functionality in your game:
 
Also, it is possible to pause and resume all the timers in your application. It is very useful when you are implementing a pause/resume functionality in your game:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
-- pause all timers.  
 
-- pause all timers.  
 
-- if all timers are alredy paused, does nothing.
 
-- if all timers are alredy paused, does nothing.
 
Timer.pauseAllTimers()       
 
Timer.pauseAllTimers()       
 
-- resume all timers. if all timers  
 
-- resume all timers. if all timers  
-- are alredy running, does nothing.
+
-- are already running, does nothing.
 
Timer.resumeAllTimers()
 
Timer.resumeAllTimers()
</source>
+
</syntaxhighlight>
  
 
== ADDED_TO_STAGE and REMOVED_FROM_STAGE Events ==
 
== ADDED_TO_STAGE and REMOVED_FROM_STAGE Events ==
 +
If a sprite is added to the scene tree, the sprite instance and all of its descendants receive Event.ADDED_TO_STAGE event. Similarly, if a sprite is removed from the scene tree, the sprite instance and all of its descendants receive Event.REMOVED_FROM_STAGE event.
  
If a sprite is added to the scene tree, the sprite instance and all of it’s descendants receive Event.ADDED_TO_STAGE event. Similarly, if a sprite is removed from the scene tree, the sprite instance and all of it’s descendants receive Event.REMOVED_FROM_STAGE event. These events are used to detect when a Sprite instance is added to, or removed from, the scene tree. For example, by the help of these events, it is possible to register Event.ENTER_FRAME event only for the sprites that are on the scene tree:
+
These events are used to detect when a Sprite instance is added to, or removed from, the scene tree. For example, by the help of these events, it is possible to register Event.ENTER_FRAME event only for the sprites that are on the scene tree:
<br/>
+
<syntaxhighlight lang="lua">
 
 
<source lang="lua">
 
 
MySprite = gideros.class(Sprite)
 
MySprite = gideros.class(Sprite)
 
function MySprite:init()
 
function MySprite:init()
Line 223: Line 182:
 
-- enter frame logic
 
-- enter frame logic
 
end
 
end
</source>
+
</syntaxhighlight>
<br/>
 
  
 
== Custom events ==
 
== Custom events ==
 
+
To dispatch a new custom user defined event, create the event with '''Event.new()''' function and dispatch it with '''EventDispatcher:dispatchEvent()'''. Example:
To dispatch a new custom user defined event, create the event with Event.new() function and dispatch it with EventDispatcher:dispatchEvent(). Example:
+
<syntaxhighlight lang="lua">
 
 
 
ClassA = gideros.class(EventDispatcher)
 
ClassA = gideros.class(EventDispatcher)
 
ClassB = gideros.class(EventDispatcher)
 
ClassB = gideros.class(EventDispatcher)
 
function ClassA:funcA(event)
 
function ClassA:funcA(event)
  print("funcA", self, event:getType(), event:getTarget())
+
print("funcA", self, event:getType(), event:getTarget())
 
end
 
end
 
local a = ClassA.new()
 
local a = ClassA.new()
Line 239: Line 196:
 
b:addEventListener("myevent", a.funcA, a)
 
b:addEventListener("myevent", a.funcA, a)
 
-- when b dispatches an "myevent" event,
 
-- when b dispatches an "myevent" event,
    -- a.funcA will be called with 'a'
+
-- a.funcA will be called with 'a'as first parameter
    -- as first parameter
 
 
b:dispatchEvent(Event.new("myevent"))
 
b:dispatchEvent(Event.new("myevent"))
 
-- will print "funcA"
 
-- will print "funcA"
 +
</syntaxhighlight>
  
 
== List of all built-in events ==
 
== List of all built-in events ==
 
 
The following tables show a list of all built-in events in Gideros SDK, with a brief explanation of what they are for.
 
The following tables show a list of all built-in events in Gideros SDK, with a brief explanation of what they are for.
  
 
=== Frame & stage events ===
 
=== Frame & stage events ===
 
+
{| class="wikitable" style="width: 70%;"
ENTER_FRAME
+
|-
Dispatched to all Sprite instances before rendering the screen.
+
| ENTER_FRAME
 +
|| Dispatched to all Sprite instances before rendering the screen.
 
     • event.frameCount: The total number of frames that have passed since the start of the application
 
     • event.frameCount: The total number of frames that have passed since the start of the application
 
     • event.time: Time in seconds since the start of the application
 
     • event.time: Time in seconds since the start of the application
 
     • event.deltaTime: The time in seconds between the last frame and the current frame
 
     • event.deltaTime: The time in seconds between the last frame and the current frame
ADDED_TO_STAGE
+
|-
Dispatched when target Sprite instance is added to the stage.
+
| ADDED_TO_STAGE || Dispatched when target Sprite instance is added to the stage.
REMOVED_FROM_STAGE
+
|-
Dispatched when target Sprite instance is removed from the stage.
+
| REMOVED_FROM_STAGE || Dispatched when target Sprite instance is removed from the stage.
 +
|}
  
 
=== Mouse events ===
 
=== Mouse events ===
 
+
{| class="wikitable" style="width: 70%;"
MOUSE_DOWN
+
|-
Dispatched to all Sprite instances on the scene tree when user presses the mouse button or starts the first touch.
+
| MOUSE_DOWN
 +
|| Dispatched to all Sprite instances on the scene tree when user presses the mouse button or starts the first touch.
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
MOUSE_MOVE
+
|-
Dispatched to all Sprite instances on the scene tree when user moves the mouse or moves the first touch.
+
| MOUSE_MOVE
 +
|| Dispatched to all Sprite instances on the scene tree when user moves the mouse or moves the first touch.
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
MOUSE_UP
+
|-
Dispatched to all Sprite instances on the scene tree when user releases the mouse button or ends the first touch.
+
| MOUSE_UP
 +
|| Dispatched to all Sprite instances on the scene tree when user releases the mouse button or ends the first touch.
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.x: The x-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
 
     • event.y: The y-coordinate of the mouse or touch
 +
|}
  
 
=== Touch events ===
 
=== Touch events ===
 
+
{| class="wikitable" style="width: 70%;"
TOUCHES_BEGIN
+
|-
Dispatched to all Sprite instances on the scene tree when one or more fingers touch down.
+
| TOUCHES_BEGIN
 +
|| Dispatched to all Sprite instances on the scene tree when one or more fingers touch down.
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_MOVE
+
|-
Dispatched to all Sprite instances on the scene tree when one or more fingers move.
+
| TOUCHES_MOVE
 +
|| Dispatched to all Sprite instances on the scene tree when one or more fingers move.
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_END
+
|-
Dispatched to all Sprite instances on the scene tree when one or more fingers are raised.
+
| TOUCHES_END
 +
|| Dispatched to all Sprite instances on the scene tree when one or more fingers are raised.
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_CANCEL
+
|-
Dispatched to all Sprite instances on the scene tree when a system event (such as a low-memory warning) cancels a touch event.
+
| TOUCHES_CANCEL
 +
|| Dispatched to all Sprite instances on the scene tree when a system event (such as a low-memory warning) cancels a touch event.
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.touches: Array of current touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
 
     • event.allTouches: Array of all touches where each element contains x, y and id
 +
|}
  
 
=== Application events ===
 
=== Application events ===
 
+
{| class="wikitable" style="width: 70%;"
APPLICATION_START
+
|-
Dispatched to all event listeners (broadcast event) right after the application is launched and all Lua codes are executed.
+
| APPLICATION_START || Dispatched to all event listeners (broadcast event) right after the application is launched and all Lua codes are executed.
APPLICATION_EXIT
+
|-
Dispatched to all event listeners (broadcast event) when the application is about to exit. If an application is forced to be terminated (e.g. by double tapping the home button and kill the application), this event may not be dispatched. If you want to save your game state before exiting, save your state also on APPLICATION_SUSPEND event.
+
| APPLICATION_EXIT || Dispatched to all event listeners (broadcast event) when the application is about to exit. If an application is forced to be terminated (e.g. by double tapping the home button and kill the application), this event may not be dispatched. If you want to save your game state before exiting, save your state also on APPLICATION_SUSPEND event.
APPLICATION_SUSPEND
+
|-
Dispatched to all event listeners (broadcast event) when the application goes to background. When an application goes to background, ENTER_FRAME and TIMER events are not dispatched until the application is resumed from background.
+
| APPLICATION_SUSPEND || Dispatched to all event listeners (broadcast event) when the application goes to background. When an application goes to background, ENTER_FRAME and TIMER events are not dispatched until the application is resumed from background.
APPLICATION_RESUME
+
|-
Dispatched to all event listeners (broadcast event) when the application is resumed from background.
+
| APPLICATION_RESUME || Dispatched to all event listeners (broadcast event) when the application is resumed from background.
 +
|}
  
 
=== Sound & Timer events ===
 
=== Sound & Timer events ===
 
+
{| class="wikitable" style="width: 70%;"
SOUND_COMPLETE
+
|-
Dispatched when a sound has finished playing.
+
| SOUND_COMPLETE || Dispatched when a sound has finished playing.
TIMER
+
|-
Dispatched whenever a Timer object reaches an interval specified according to the delay property.
+
| TIMER || Dispatched whenever a Timer object reaches an interval specified according to the delay property.
TIMER_COMPLETE
+
|-
Dispatched whenever a Timer object has completed the number of requests specified according to the repeatCount property.
+
| TIMER_COMPLETE || Dispatched whenever a Timer object has completed the number of requests specified according to the repeatCount property.
 +
|}
  
 
=== UrlLoader events ===
 
=== UrlLoader events ===
 
+
{| class="wikitable" style="width: 70%;"
COMPLETE
+
|-
Dispatched after all data is received and placed in the data property of the UrlLoader object.
+
| COMPLETE || Dispatched after all data is received and placed in the data property of the UrlLoader object.
ERROR
+
|-
Dispatched when UrlLoader fails and terminates the download.
+
| ERROR || Dispatched when UrlLoader fails and terminates the download.
PROGRESS
+
|-
Dispatched by UrlLoader as the notification of how far the download has progressed.
+
| PROGRESS
 +
|| Dispatched by UrlLoader as the notification of how far the download has progressed.
 
     • event.bytesLoaded: The number of bytes loaded
 
     • event.bytesLoaded: The number of bytes loaded
 
     • event.bytesTotal: The total number of bytes that will be loaded
 
     • event.bytesTotal: The total number of bytes that will be loaded
 +
|}
  
 
=== Physics events ===
 
=== Physics events ===
 
+
{| class="wikitable" style="width: 70%;"
BEGIN_CONTACT
+
|-
Dispatched by b2.World when two fixtures begin to overlap. This is dispatched for sensors and non-sensors. This event can only occur inside the time step.
+
| BEGIN_CONTACT
 +
|| Dispatched by b2.World when two fixtures begin to overlap. This is dispatched for sensors and non-sensors. This event can only occur inside the time step.
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
END_CONTACT
+
|-
Dispatched by b2.World when two fixtures cease to overlap. This is dispatched for sensors and non-sensors. This may be dispatched when a body is destroyed, so this event can occur outside the time step.
+
| END_CONTACT
 +
|| Dispatched by b2.World when two fixtures cease to overlap. This is dispatched for sensors and non-sensors. This may be dispatched when a body is destroyed, so this event can occur outside the time step.
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
PRE_SOLVE
+
|-
Dispatched by b2.World after collision detection, but before collision resolution.
+
| PRE_SOLVE
 +
|| Dispatched by b2.World after collision detection, but before collision resolution.
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
POST_SOLVE
+
|-
Dispatched by b2.World after collision resolution.
+
| POST_SOLVE
 +
|| Dispatched by b2.World after collision resolution.
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureA: The first fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
 
     • event.fixtureB: The second fixture in this contact
<br/>
+
|}
<br/>
+
 
 +
 
 +
'''PREV.''': [[Playing Sound and Music]]<br/>
 +
'''NEXT''': [[File system]]
 +
 
 +
 
 +
{{GIDEROS IMPORTANT LINKS}}

Latest revision as of 22:21, 18 November 2023

The Ultimate Guide to Gideros Studio

Event system

Introduction to events

Events are the central mechanism to handle responses and they allow to create interactive applications.

All classes that dispatch events inherit from EventDispatcher. The target of an event is a listener function and an optional data value.

When an event is dispatched, the registered function is called. If the optional data value is given, it is used as a first parameter while calling the listener function.

In Gideros, events can be divided into two categories:

  • built-in events which are generated by the system (e.g. ENTER_FRAME event, touch events, timer events, etc.)
  • custom events which can be generated by the user.

According to their event type, built-in events can be broadcasted to multiple targets (e.g. ENTER_FRAME event, touch events, etc.) or can be dispatched to a single target (e.g. timer event).

ENTER_FRAME Event

The Gideros runtime dispatches the built-in Event.ENTER_FRAME event to Sprite instances before rendering the screen. Visual changes made by any Event.ENTER_FRAME listener function will be visible at next frame.

This first basic example shows a moving sprite one pixel to the right at each frame. In this example, onEnterFrame function increases the x-coordinate of a sprite object at each frame:

local sprite = Sprite.new()
local function onEnterFrame(event)
   sprite:setX(sprite:getX() + 1)
end
sprite:addEventListener(Event.ENTER_FRAME, onEnterFrame)

The next example shows 3 independent sprites moving one pixel to the right at each frame. In this example, we use the optional data parameter to move independent sprites with one common listener function:

local sprite1 = Sprite.new()
local sprite2 = Sprite.new()
local sprite3 = Sprite.new()
local function onEnterFrame(self, event)
   self:setX(self:getX() + 1)
end
sprite1:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite1)
sprite2:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite2)
sprite3:addEventListener(Event.ENTER_FRAME, onEnterFrame, sprite3)

The last example shows subclassing of the Sprite class and registering Event.ENTER_FRAME:

MySprite = gideros.class(Sprite)
function MySprite:init()
   self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
function MySprite:onEnterFrame(event)
   self:setX(self:getX() + 1)
end

Note: Event.ENTER_FRAME event is dispatched to all Sprite instances no matter if these instances are on the scene tree or not.

Note: when the ENTER_FRAME event dispatches, the event object contains time and deltaTime. Consider the following example:

local function onEnterFrame(event)
	print(event.time, event.deltaTime)
end
stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)

Mouse and touch events

Gideros runtime dispatches mouse and touch events when the the user’s finger touches the screen. Mouse events are mainly used in single-touch whereas touch events are used in multi-touch applications.

The mouse and touch events are dispatched to Sprite instances which are on the scene tree. If a Sprite instance is not on the scene tree, this instance doesn’t receive mouse and touch events.

Note: even if touch or mouse doesn’t hit the Sprite instance, the instance receives mouse/touch events.

The order of dispatch is determined by the hierarchy of the scene tree. The Sprite instance that is drawn last (top-most sprite) receives the event first. The next sprite at the bottom of the top-most sprite receives the event second and so on. For example, assume that we have an sprite hierarchy like this:

Sprite hierarchy.png

which is constructed by the code below:

local A = Sprite.new()
local B = Sprite.new()
local C = Sprite.new()
local D = Sprite.new()
local E = Sprite.new()
local F = Sprite.new()
A:addChild(B)
A:addChild(C)
B:addChild(D)
B:addChild(E)
C:addChild(F)

In this hierarchy, the drawing order is A, B, C, D, E, F while mouse/touch event receive order is F, E, D, C, B, A.

Stopping an event dispatch

It is possible to stop the propagation of mouse and touch events. To stop an event dispatch, invoke the Event:stopPropagation() function on the Eventobject passed to the listener function.

In the example below, MOUSE_DOWN event is dispatched only to F, E, D and C:

local A = Sprite.new()
local B = Sprite.new()
local C = Sprite.new()
local D = Sprite.new()
local E = Sprite.new()
local F = Sprite.new()
-- stop propagation at sprite C
C:addEventListener(Event.MOUSE_DOWN, function(event)
	event:stopPropagation()
end)
A:addChild(B)
A:addChild©
B:addChild(D)
B:addChild(E)
C:addChild(F)

Note: stopPropagation is only for mouse and touch events. Because only for them there is a definite dispatching order (the display object on top receives the event first).

Timer events

The Timer class is used for executing code at specified time intervals. Each Timer object dispatches Event.TIMER event at specified frequency.

The steps to use Timer class are as follows:

1- Create a new Timer object with specified frequency and specified total number of Event.TIMER events to be triggered. For example, the following code sets the frequency to 1000 miliseconds and sets the count to 5:

local timer = Timer.new(1000, 5)

2- Register to the Event.TIMER event with a listener function:

local function onTimer(event)
-- will be executed 5 times at 1000 milliseconds intervals
end
timer:addEventListener(Event.TIMER, onTimer)

3- Start the timer:

timer:start()

4- To stop the timer, you can use Timer:stop() function:

timer:stop()

Event.TIMER_COMPLETE event is triggered after finishing the specified number of timer events.

local function onTimerComplete(event)
-- will be executed after the specified 
-- number of timer events (5) are dispatched
end
timer:addEventListener(Event.TIMER_COMPLETE, onTimerComplete)

Also, it is possible to pause and resume all the timers in your application. It is very useful when you are implementing a pause/resume functionality in your game:

-- pause all timers. 
-- if all timers are alredy paused, does nothing.
Timer.pauseAllTimers()      
-- resume all timers. if all timers 
-- are already running, does nothing.
Timer.resumeAllTimers()

ADDED_TO_STAGE and REMOVED_FROM_STAGE Events

If a sprite is added to the scene tree, the sprite instance and all of its descendants receive Event.ADDED_TO_STAGE event. Similarly, if a sprite is removed from the scene tree, the sprite instance and all of its descendants receive Event.REMOVED_FROM_STAGE event.

These events are used to detect when a Sprite instance is added to, or removed from, the scene tree. For example, by the help of these events, it is possible to register Event.ENTER_FRAME event only for the sprites that are on the scene tree:

MySprite = gideros.class(Sprite)
function MySprite:init()
	self:addEventListener(Event.ADDED_TO_STAGE, self.onAddedToStage, self)
	self:addEventListener(Event.REMOVED_FROM_STAGE, self.onRemovedFromStage, self)
end
function MySprite:onAddedToStage(event)
	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
function MySprite:onRemovedFromStage(event)
	self:removeEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
function MySprite:onEnterFrame(event)
	-- enter frame logic
end

Custom events

To dispatch a new custom user defined event, create the event with Event.new() function and dispatch it with EventDispatcher:dispatchEvent(). Example:

ClassA = gideros.class(EventDispatcher)
ClassB = gideros.class(EventDispatcher)
function ClassA:funcA(event)
	print("funcA", self, event:getType(), event:getTarget())
end
local a = ClassA.new()
local b = ClassB.new()
b:addEventListener("myevent", a.funcA, a)
-- when b dispatches an "myevent" event,
-- a.funcA will be called with 'a'as first parameter
b:dispatchEvent(Event.new("myevent"))
-- will print "funcA"

List of all built-in events

The following tables show a list of all built-in events in Gideros SDK, with a brief explanation of what they are for.

Frame & stage events

ENTER_FRAME Dispatched to all Sprite instances before rendering the screen.
   • event.frameCount: The total number of frames that have passed since the start of the application
   • event.time: Time in seconds since the start of the application
   • event.deltaTime: The time in seconds between the last frame and the current frame
ADDED_TO_STAGE Dispatched when target Sprite instance is added to the stage.
REMOVED_FROM_STAGE Dispatched when target Sprite instance is removed from the stage.

Mouse events

MOUSE_DOWN Dispatched to all Sprite instances on the scene tree when user presses the mouse button or starts the first touch.
   • event.x: The x-coordinate of the mouse or touch
   • event.y: The y-coordinate of the mouse or touch
MOUSE_MOVE Dispatched to all Sprite instances on the scene tree when user moves the mouse or moves the first touch.
   • event.x: The x-coordinate of the mouse or touch
   • event.y: The y-coordinate of the mouse or touch
MOUSE_UP Dispatched to all Sprite instances on the scene tree when user releases the mouse button or ends the first touch.
   • event.x: The x-coordinate of the mouse or touch
   • event.y: The y-coordinate of the mouse or touch

Touch events

TOUCHES_BEGIN Dispatched to all Sprite instances on the scene tree when one or more fingers touch down.
   • event.touches: Array of current touches where each element contains x, y and id
   • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_MOVE Dispatched to all Sprite instances on the scene tree when one or more fingers move.
   • event.touches: Array of current touches where each element contains x, y and id
   • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_END Dispatched to all Sprite instances on the scene tree when one or more fingers are raised.
   • event.touches: Array of current touches where each element contains x, y and id
   • event.allTouches: Array of all touches where each element contains x, y and id
TOUCHES_CANCEL Dispatched to all Sprite instances on the scene tree when a system event (such as a low-memory warning) cancels a touch event.
   • event.touches: Array of current touches where each element contains x, y and id
   • event.allTouches: Array of all touches where each element contains x, y and id

Application events

APPLICATION_START Dispatched to all event listeners (broadcast event) right after the application is launched and all Lua codes are executed.
APPLICATION_EXIT Dispatched to all event listeners (broadcast event) when the application is about to exit. If an application is forced to be terminated (e.g. by double tapping the home button and kill the application), this event may not be dispatched. If you want to save your game state before exiting, save your state also on APPLICATION_SUSPEND event.
APPLICATION_SUSPEND Dispatched to all event listeners (broadcast event) when the application goes to background. When an application goes to background, ENTER_FRAME and TIMER events are not dispatched until the application is resumed from background.
APPLICATION_RESUME Dispatched to all event listeners (broadcast event) when the application is resumed from background.

Sound & Timer events

SOUND_COMPLETE Dispatched when a sound has finished playing.
TIMER Dispatched whenever a Timer object reaches an interval specified according to the delay property.
TIMER_COMPLETE Dispatched whenever a Timer object has completed the number of requests specified according to the repeatCount property.

UrlLoader events

COMPLETE Dispatched after all data is received and placed in the data property of the UrlLoader object.
ERROR Dispatched when UrlLoader fails and terminates the download.
PROGRESS Dispatched by UrlLoader as the notification of how far the download has progressed.
   • event.bytesLoaded: The number of bytes loaded
   • event.bytesTotal: The total number of bytes that will be loaded

Physics events

BEGIN_CONTACT Dispatched by b2.World when two fixtures begin to overlap. This is dispatched for sensors and non-sensors. This event can only occur inside the time step.
   • event.fixtureA: The first fixture in this contact
   • event.fixtureB: The second fixture in this contact
END_CONTACT Dispatched by b2.World when two fixtures cease to overlap. This is dispatched for sensors and non-sensors. This may be dispatched when a body is destroyed, so this event can occur outside the time step.
   • event.fixtureA: The first fixture in this contact
   • event.fixtureB: The second fixture in this contact
PRE_SOLVE Dispatched by b2.World after collision detection, but before collision resolution.
   • event.fixtureA: The first fixture in this contact
   • event.fixtureB: The second fixture in this contact
POST_SOLVE Dispatched by b2.World after collision resolution.
   • event.fixtureA: The first fixture in this contact
   • event.fixtureB: The second fixture in this contact


PREV.: Playing Sound and Music
NEXT: File system