Corona Reference: Events
Any interactive app must include some events. There are two major types of event: runtime and local. Runtime events are triggered in response to changes outside the app, such as a change in screen orientation, an incoming phone call, a change in GPS coordinates, etc. Local events are triggered by the user touching a display object on screen, a timer, a physics collision, etc.
The most common event we'll be using are tap and touch events. These events allow the user to interact with the app by touching display objects on screen. A listener must be attached to these objects. When the listener detects an event, a function (often called a handler) is called, resulting in a response to the touch.
Tap and Touch Events
Tap Events
A tap event occurs when the user taps the screen. The event does not trigger any action until the user releases the point. To add a tap event listener to a display object, use the format
OBJECT:addEventListener( "tap", handler_name )
The handler is generally defined prior to the object listening for the event, as follows:
local function handler_name( event )
-- action
end
OBJECT:addEventListener( "tap", handler_name )
A tap event is the simplest hit event to deal with in Corona, but it does not carry as much information as other events we can listen for. The length of the tap, for instance, is irrelevant. Pressing an object with a tap listener will not cause the handler to fire until the press ends.
Touch Events
Touch events are similar to a tap event, in that they occur when the user touches a display object. However, touch events are more flexible, as they have more attributes and can pass more information to the handler. The event handler can trigger one action when the touch begins, and another when it ends. This way, we can use a touch event to track the length of the touch, track motion, and more.
Adding a touch event listener to a display object is very similar to adding a tap event:
OBJECT:addEventListener( "touch", touch_handler )
where "object" is the name of the object you will be touching, and "touch_handler" is the name of the function that will fire when this object is touched.
The following read-only properties are useful within touch handlers (note that these properties apply only to "touch" events, not "tap"):
event.phase
This property is a string which indicates which phase the touch event is currently in. There are four values this string can take:
"began"
is the initial phase of a touch event, when a touch is first detected.
"moved"
indicates that the user’s finger has moved on the screen without releasing the object.
"cancelled"
indicates the touch is no longer being tracked. This may occur when the user’s finger remains on the screen, but has slid off the object.
"ended"
indicates the user has removed their finger from the screen.
event.xStart and
event.yStart
These properties give the x and y coordinate of the beginning of the touch. When tracking motion, it's often helpful to compare these values to the
event.x
and
event.y
properties, which give the current location of the touch.
Tap and Touch Properties
The following read-only properties are commonly used within tap and touch handlers:
event.target
In a tap or touch handler, event.target
refers to the object that received the touch. This is particularly useful when multiple objects share the same event handler. Instead of referring to the object by name in the handler, we can refer to the object that is currently being tapped.
event.x and event.y
These properties give the x and y coordinate of the tap or touch. These values update throughout a touch event, tracking the latest location of the touch.
event.numTaps
This property of a tap event can be used to detect a single or double tap, and has a value of either 1 or 2.
Tap and Touch Examples
Counting Taps
In this example, we’ll create a text object in the center of the screen. The text will have an event listener, and will change according to the number of times it has been tapped. To accomplish this, we’ll need to create a counter which will increase by 1 each time a tap occurs. As usual, we’ll declare all variables (including the counter, the text, and the function itself) in the first line of code. We’ll also print the number of taps to the terminal.
local myText, changeText, counter
counter = 0
function changeText( event )
counter = counter + 1
myText.text = "I’ve been tapped ".. counter .. " times"
print( counter.." taps")
return true
end
myText = display.newText( "I’ve been tapped 0 times", display.contentCenterX, display.contentCenterY, Arial, 40 )
myText:setFillColor( 1, 1, 1 )
myText:addEventListener( "tap", changeText )
As the counter changes, we can update the text using some useful features of the Lua string library. To concatenate strings, we use the .. symbol. This tells Lua to paste two strings together. In this case, we paste three strings - the first one is simply "I’ve been tapped", the second is the counter value, and the last is " times". Lua will automatically convert this value to a string when it appears in a concatenation, so we don’t have to create another string. Notice that spaces will not be put in automatically between strings being pasted together, so we’ve included those in the strings themselves.
Touch Phases
We’ll draw a square will turn blue when we first touch it, and green when we release.
local myRectangle, changeRectangle
function changeRectangle( event )
if ( event.phase == "began" ) then
myRectangle:setFillColor( 0, 0, 1 )
elseif ( event.phase == "ended" ) then
myRectangle:setFillColor( 0, 1, 0 )
end
return true
end
myRectangle = display.newRect( 200, 300, 50, 50 )
myRectangle:setFillColor( 1, 0, 0 )
myRectangle:addEventListener( "touch", changeRectangle )
This is meant to be a minimal example; you'll probably want your handler to include actions for when the event is "cancelled" as well.
Single vs Double Taps
This time, we’ll draw a rectangle called "myRectangle" on screen, and set it to listen for a tap event. When such an event is detected, we’ll change the color of the rectangle using a function called "changeRectangle".
local myRectangle, changeRectangle
function changeRectangle( event )
if event.numTaps == 1 then
myRectangle:setFillColor( 0, 0, 1 )
else
myRectangle:setFillColor( 0, 1, 0 )
end
return true
end
myRectangle = display.newRect( 200, 300, 50, 50 )
myRectangle:setFillColor( 1, 0, 0 )
myRectangle:addEventListener( "tap", changeRectangle )
When tapped a single time, the rectangle will turn blue. When double tapped (two quick taps in succession), the rectangle will turn green.
Color Picker
The following example is a simple application of a touch event. A single rectangle, the size of the content area, is created and centered on screen. It listens for a touch event. When an event is detected, the initial instructions are made transparent. As the user moves their finger around on screen, the color of the rectangle is changed according to the user’s current touch position. The red value is fixed, but blue is adjusted on a scale from 0 to 1 as the touch moves from left to right, and green is adjusted on a scale from 0 to 1 as the touch moves from top to bottom. Finally, when the touch event ends, the RGB color values are rounded up to the nearest integer and displayed on screen.
local instructions, bigRectangle, colorChanger
local w = display.contentWidth
local h = display.contentHeight
function colorChanger( event )
local blueinc = 1/w -- Percentage of blue per pixel; blue will change with x coordinate
local greeninc = 1/h -- Percentage of green per pixel; green will change with y coordinate
if ( event.phase == "began" ) then
instructions.alpha = 0 -- Hide text
elseif ( event.phase == "moved" ) then
bigRectangle:setFillColor(0.3, event.x*blueinc, event.y*greeninc)
elseif ( event.phase == "ended" or event.phase == "cancelled" ) then
local newred = math.ceil( 0.3*255 ) -- Round up RGB values
local newblue = math.ceil( event.x*blueinc * 255 )
local newgreen = math.ceil( event.y*greeninc * 255 )
instructions.text = "RGB Color is ("..newred..", "..newgreen..", "..newblue..")"
instructions.alpha = 1
end
return true
end
bigRectangle = display.newRect( w/2, h/2, w, h )
bigRectangle:setFillColor( 1, 1, 1 )
bigRectangle:addEventListener( "touch", colorChanger )
instructions = display.newText( "Drag your finger around the screen", w/2, h/2, Arial, 20 )
instructions:setFillColor( 0, 0, 0 )
Multiple Listeners
We’ve seen how to use a single event handler for multiple objects. We may also have occasion to use multiple handlers for the same object, and even the same type of hit event. We’ll create a rectangle that will have two event listeners, one awaiting a tap and another awaiting a touch. Touching the rectangle will cause it to turn green until the touch ends, when it turns red. Tapping the rectangle returns it to white.
local myBlock, tapHandler, touchHandler
function tapHandler( event )
event.target:setFillColor( 1, 1, 1 )
return true
end
function touchHandler( event )
if event.phase == "began" then
event.target:setFillColor( 0, 1, 0 )
elseif event.phase == "ended" then
event.target:setFillColor( 1, 0, 0 )
end
return
end
myBlock = display.newRect( display.contentWidth/2, display.contentHeight/2, 60, 60 )
myBlock:addEventListener( "touch", touchHandler )
myBlock:addEventListener( "tap", tapHandler )
Return True
The event handlers in the previous examples ended with the phrase return true
. This is not always necessary (and in some cases may not be wanted), but helps avoid some unintentional events from being fired. This command allows you to layer display objects, each with their own event listeners, and prevent these events from interfering with each other.
Consider two rectangles that are overlapping, each with their own event listener. If the user taps the top rectangle, it’s event handler will go into action. But if that handler does not include the return true
command, the tap will continue to propagate through to the rectangle below, whose event handler will then fire. In other cases, you may accidentally assign the same event listener to an object more than once. This is generally not a problem, as long as the handler includes return true
.
It is a good idea to be in the habit of using return true in your event handlers, unless you have a specific need to avoid it.
Dragging Objects
Many apps require the user to drag an object from one location on the screen to another. We’ve seen an example of how to move an object using an event handler, but the object went to a predefined (or random) location. To create a draggable object, we’ll tell it to listen for a touch event that triggers a dragging function. Conveniently, we only need to define this function once, even if we have multiple objects that will require dragging. This is because we’ll taking advantage of the
event.target
property - whichever object triggers the function will be the one that moves.
If you're just looking to create a function that does the job of moving an object on the screen, you can use
function dragObject( event )
if event.phase == "began" then
self = event.target
self.markX = self.x
self.markY = self.y
elseif event.phase == "moved" then
self.x = event.x - event.xStart + self.markX
self.y = event.y - event.yStart + self.markY
end
return true
end
We’ll walk through what’s going on here. As in the previous handlers for touch events, we have multiple phases of the touch event to deal with. In the first phase, which begins as soon as the user touches the object, we begin by defining a variable called "self" to represent the object begin touched. If more than one object uses this same event handler, whichever one is currently being touched is now called "self" within the function. Next, we record the initial location of the object with the markX and markY properties. These are not Corona defined properties, but rather names we made up. You’re free to use any other property name you like, though these are the ones traditionally used among Corona developers. We set the value self.markX to be the current x coordinate of the object’s anchor point at first touch, and similarly, self.markY is the current y coordinate.
This function will now take advantage of the "moved" event phase. As the user continues to hold the object and move their finger around the screen, the location of "self" is changed by calculating how much the user’s finger has moved, then adding the original position of the object. The x and y coordinates are handled separately. Finally, we return true to make sure we’re not dragging other objects around inadvertently.
Example
The following code produces a circle that can be dragged around the screen:
function dragObject( event )
if event.phase == "began" then
self = event.target
self.markX = self.x
self.markY = self.y
elseif event.phase == "moved" then
self.x = event.x - event.xStart + self.markX
self.y = event.y - event.yStart + self.markY
end
return true
end
local myCircle = display.newCircle( 100, 100, 75)
myCircle:setFillColor( 1, 1, 1 )
myCircle:addEventListener( "touch", dragObject )
Multitouch Events
Both iOS and Android devices are able to detect multitouch events. If you’ve ever pinched your fingers together on screen to make an image smaller, or played a game that required touching the screen in more than one location, then you’ve made use of this feature.
Warning
While Corona is able to produce apps capable of detecting multitouch events, the simulator is NOT. Running such an app in the simulator will produce this warning, and you will not be able to test your multitouch functions without an actual device.
Before we can create an object that listens for a multitouch event, we’ll need to tell the system to activate this feature. We can do this by including the line
system.activate("multitouch")
at the beginning of our main.lua file. It doesn’t really matter where we place it, as long as it appears before adding an event listener. Activating multitouch means that any touch listener has multiple touches in its event variable, each one being given a distinct id. While this generally won’t affect our code, we will see the event.id value appearing on occasion, such as in the improved dragging function below.
A Better Dragging Function
To resolve the problems caused by a second touch on the screen, we’ll need to make sure that the function focuses only on the touch that triggered the function. This isn’t to say other touches will be ignored - a second touch might be simultaneously triggering another function. In fact, two different objects could be using this same function at the same time. But any other touches that do not apply to the current event target shouldn’t affect the object, and preventing such a scenario from happening requires only minor modification to our code:
function dragObject( event )
if event.phase == "began" then
self = event.target -- abbreviation for event.target
display.getCurrentStage():setFocus( self, event.id ) -- focus on this object
self.isFocus = true -- an attribute we've defined for the object self
self.markX = self.x -- record starting x and y values
self.markY = self.y
elseif self.isFocus then
if event.phase == "moved" then
self.x = event.x - event.xStart + self.markX -- move object to new touch position
self.y = event.y - event.yStart + self.markY
elseif event.phase == "ended" or event.phase == "cancelled" then
display.getCurrentStage():setFocus( self, nil ) -- remove focus
self.isFocus = false
end
end
return true
end
Now, we still have an if-then statement, and the first part of it says what to do if the touch has just begun. We again define self = event.target, and then use the setFocus function of Corona to set this object as the current thing we’re focusing on, so no other objects will be affected and no other touches will be used in our calculations. We’ll then create another property called isFocus (again, our naming and not an official Corona property) and set it to true.
As the user continues the touch, we’re no longer jumping right to the "moved" phase. Instead, we’ll move to the second part of the overall if-then statement, since it is defined to run whenever we’re no longer in the "beginning" phase of the touch and whenever isFocus is set to true. Since both of these requirements are met, we go to an inner if-then statement to see what to do next. As the user moves their finger (the one we’re focusing on) we’re in the "moved" phase of the touch, and we’ll move the object just as we did earlier. As soon as the touch is ended, we go to the "ended" or "cancelled" phase. We didn’t include this in the shorter dragging function, and it doesn’t appear to add much here. But this is where we release the focus of our object and the touch, and set the property isFocus to false to prevent any more motion from occurring.
Pinch-to-Zoom
Many apps will make use of multitouch gestures to scale, drag, and zoom objects. Unfortunately, only dragging can be tested in the simulator. However, if you'd like to apply a pinch-to-zoom function to an object, you can use the code below:
function pinchtozoom( event )
local phase = event.phase
local eventTime = event.time
local previousTouches = self.previousTouches
if not self.xScaleStart then
self.xScaleStart, self.yScaleStart = self.xScale, self.yScale
end
local numTotalTouches = 1
if previousTouches then
numTotalTouches = numTotalTouches + self.numPreviousTouches
if previousTouches[event.id] then
numTotalTouches = numTotalTouches - 1
end
end
if "began" == phase then
if not self.isFocus then
display.getCurrentStage():setFocus( self )
self.isFocus = true
self.x0 = event.x - self.x
self.y0 = event.y - self.y
previousTouches = {}
self.previousTouches = previousTouches
self.numPreviousTouches = 0
self.firstTouch = event
elseif not self.distance then
local dx,dy
local cx,cy
if previousTouches and numTotalTouches >= 2 then
dx,dy = calculateDelta( previousTouches, event )
cx,cy = calculateCenter( previousTouches, event )
end
if dx and dy then
local d = math.sqrt( dx*dx + dy*dy )
if d > 0 then
self.distance = d
self.xScaleOriginal = self.xScale
self.yScaleOriginal = self.yScale
self.x0 = cx - self.x
self.y0 = cy - self.y
end
end
end
if not previousTouches[event.id] then
self.numPreviousTouches = self.numPreviousTouches + 1
end
previousTouches[event.id] = event
elseif self.isFocus then
if "moved" == phase then
if self.distance then
local dx,dy
local cx,cy
if previousTouches and numTotalTouches == 2 then
dx,dy = calculateDelta( previousTouches, event )
cx,cy = calculateCenter( previousTouches, event )
end
if dx and dy then
local newDistance = math.sqrt( dx*dx + dy*dy )
local scale = newDistance / self.distance
if scale > 0 then
self.xScale = self.xScaleOriginal * scale
self.yScale = self.yScaleOriginal * scale
self.x = cx - ( self.x0 * scale )
self.y = cy - ( self.y0 * scale )
end
end
else
if event.id == self.firstTouch.id then
self.x = event.x - self.x0
self.y = event.y - self.y0
end
end
if event.id == self.firstTouch.id then
self.firstTouch = event
end
if not previousTouches[event.id] then
self.numPreviousTouches = self.numPreviousTouches + 1
end
previousTouches[event.id] = event
elseif "ended" == phase or "cancelled" == phase then
local dx = math.abs( event.xStart - event.x )
local dy = math.abs( event.yStart - event.y )
if eventTime - previousTouches[event.id].time < 150 and dx < 10 and dy < 10 then
if not self.tapTime then
self.tapTime = eventTime
self.tapDelay = timer.performWithDelay( 300, function() self.tapTime = nil end )
elseif eventTime - self.tapTime < 300 then
timer.cancel( self.tapDelay )
self.tapTime = nil
if self.xScale == self.xScaleStart and self.yScale == self.yScaleStart then
transition.to( self, { time=300, transition=easing.inOutQuad, xScale=self.xScale*2, yScale=self.yScale*2, x=event.x - self.x0*2, y=event.y - self.y0*2 } )
else
local factor = self.xScaleStart / self.xScale
transition.to( self, { time=300, transition=easing.inOutQuad, xScale=self.xScaleStart, yScale=self.yScaleStart, x=event.x - self.x0*factor, y=event.y - self.y0*factor } )
end
end
end
if previousTouches[event.id] then
self.numPreviousTouches = self.numPreviousTouches - 1
previousTouches[event.id] = nil
end
if self.numPreviousTouches == 1 then
self.distance = nil
local id,touch = next( previousTouches )
self.x0 = touch.x - self.x
self.y0 = touch.y - self.y
self.firstTouch = touch
elseif self.numPreviousTouches == 0 then
display.getCurrentStage():setFocus( nil )
self.isFocus = false
self.distance = nil
self.xScaleOriginal = nil
self.yScaleOriginal = nil
self.previousTouches = nil
self.numPreviousTouches = nil
end
end
end
return true
end
That's a lot of code! To use it, add a touch event listener to your object that calls the
pinchtozoom handler.
Runtime Events
So far, all of the event listeners and handlers we’ve seen have applied to display objects. But we can also assign handlers to all registered listeners using global Runtime events. The idea of registered listeners becomes especially important when dealing with Android devices, when we have to request special permission to access many of these listeners. Apple devices running iOS accept these events, and permission is considered during the app review process.
Before we begin defining Runtime events, we’ll consider some examples. You’ve probably used an app that changed orientation when you turned your phone or tablet. Perhaps you’ve used a "shake to shuffle" feature in a music app, or found your location with GPS. Maybe you’ve played a game where objects moved simply by tilting the device. All of these scenarios, and more, used Runtime events.
Many of these events, such as enterFrame, will not have much meaning until we have seen a little more (in this case, we’ll need to learn how to create apps with multiple scenes). However, we’ll now look at a comprehensive list of types of Runtime events and how to use them.
When assigning an event listener to a display object, we have to specify what type of event to listen for - a "touch" or a "tap". For Runtime events, we’ll use the basic format
Runtime:addEventListener( event_type, handler_name )
where "event_type" is a string equal to either
enterFrame
,
orientation
,
accelerometer
,
system
,
location
,
heading
, or
memoryWarning
, and "handler_name" is the name of the function that will fire when the device detects a change to one of these event types.
Tap Events
A tap listener can be added to the entire screen using
Runtime:addEventListener( "tap", handler_name )
This is a convenient way of adding a tap listener without having to bind it to a display object, but use caution when other listeners are involved.
enterFrame Events
The basic format for a Runtime event listening for en enterFrame event would be
Runtime:addEventListener( "enterFrame", handler_name )
We’ll see how this is used when building multi-scene apps later.
Orientation Events
The basic format for a Runtime event listening for a change in orientation would be
Runtime:addEventListener( "orientation", handler_name )
where "handler_name" is the name of the function that handles what to do when such a change is detected. Note that detecting an orientation change will not automatically make any changes to your app - you’ll need to handle those manually.
There are only two orientation event properties:
event.type
- a string indicating the new orientation. This may be either "portrait", "land-
scapeLeft", "portraitUpsideDown", "landscapeRight", "faceUp", or "faceDown". The last
two may not be available on all devices.
event.delta
- reports the difference between the ending and starting orientation angle. This will have a value of 0 if the different orientations lie in different planes (for instance, the phone was flat on a table in portrait mode, and lifted up to stand on its side in landscape mode).
Example: Detecting Orientation
In this example, we’ll change the color background based on the current orientation of the device. To try the example in the simulator, choose Rotate Right or Rotate Left from the Hardware menu.
local w = display.contentWidth
local h = display.contentHeight
local bg = display.newRect( w/2, h/2, w, h )
bg:setFillColor( 0, 1, 0 )
local function changeColor( event )
if event.type == "portrait" then
bg:setFillColor( 0, 1, 0 )
elseif event.type == "portraitUpsideDown" then
bg:setFillColor( 0, 0, 1 )
elseif event.type == "landscapeLeft" then
bg:setFillColor( 1, 0, 1 )
elseif event.type == "landscapeRight" then
bg:setFillColor( 1, 0, 0 )
end
end
Runtime:addEventListener( "orientation", changeColor )
If you want objects to move with the orientation changes, you'll need to reposition the objects manually in such a handler. This is not an easy task!
Accelerometer Events
In this case, we’ll assign the "accelerometer" event to Runtime using the format
Runtime:addEventListener( "accelerometer", handler_name )
where
handler_name is the name of the function. When the accelerometer detects motion, it will send information about the event to the handler function, which will decide what to do. We can use the same handler for multiple types of events.
The accelerometer (a piece of hardware included in most mobile devices) can report the following:
event.xGravity
- provides the acceleration due to gravity as the device is tilted relative to the x-axis (from left to right). This value is relative to portrait orientation, regardless of the default or current orientation of your app. If using a landscape orientation, you’ll need to compensate for this. Includes smoothing to improve user experience.
event.yGravity
- as above, but relative to the y-axis (from front to back).
event.zGravity
- as above, but relative to the z-axis (up and down).
event.xInstant
- provides the change in acceleration due to gravity as the device is tilted
relative to the x-axis. This can be used to detect a "jerking" motion.
event.yInstant
- as above, but relative to the y-axis.
event.zInstant
- as above, but relative to the z-axis.
event.xRaw
, event.yRaw
, and event.zRaw
- same basic functionality as event.xGravity
,
event.yGravity
, and event.zGravity
, respectively, but does not include any smoothing.Objects that are moved with these readings may appear jittery.
event.isShake
- a true or false value. Returns true if the accelerometer has detected the
user shaking the device. This event isn’t used to often, and for some good reasons. Many people don’t feel entirely comfortable shaking their expensive mobile devices intentionally, for one. Also, many accelerometers are not sensitive enough to detect shaking unless it is relatively severe. But there are some applications for it, and it’s a simple Runtime event to begin with.
Example: Magic 8 Ball
We’ll create a simple Magic 8 Ball app that changes an on screen message with each shake. We’ll first create a text object that displays the message, and a table containing ten possible fortunes to display. In the handler, when a shake is detected, a random number between 1 and 10 is chosen. The message with that id in the message table will then be displayed.
local w = display.contentWidth
local h = display.contentHeight
local mt = display.newText( "Ask me a yes or no question", w/2, h/2, Arial, 30)
local fortunes = {
"Details are hazy - try again later",
"Absolutely. Try again!",
"Definitely not. Try again!",
"Yes. Try again!",
"No. Try again!",
"Probably. Try again!",
"Probably not. Try again!",
"I’d rather not say. Try again!",
"Maybe someday. Try again!",
"Could be. Try again!"
}
local function magic8( event )
if event.isShake then
local randommessage = math.random( 1, 10 )
mt.text = fortunes[randommessage]
end
end
Runtime:addEventListener( "accelerometer", magic8 )
To test your app in the simulator, select Shake from the Hardware menu.
System Events
System changes that need to be addressed by the app can be handled using a system event listener:
Runtime:addEventListener( "system", handler_name )
You mostly likely will not need to use these, and instead allow your config and build files to handle these system events. But, Corona does give you the option of creating your own function to a change to the value
event.type
- a string representing the kind of system event to look for. This could be
"applicationStart"
, in which case we’d define a function that handles the launching of the application itself. Another possibility is
"applicationExit"
, which allows us to define a function for when the user quits the app. Finally, there’s
"applicationSuspend"
and
"applicationResume"
, which allow you to design a function that handles an interruption to your app, such as a phone call, and one that handles what to do when the interruption is over.
Memory Warnings (iOS Only)
Runtime:addEventListener( "memoryWarning", handler_name )
allows you to build a function that fires when the iOS low memory warning is exposed. This is a warning that the app will be shut down in 5 seconds. If this warning is received, you’ll want to free as much memory as possible to prevent your app from being shut down.
GPS Events
For devices with a GPS, you can set up a listener with format
Runtime:addEventListener( "location", handler_name )
that passes the following properties to the handler function:
event.xGravity
- provides the acceleration due to gravity as the device is tilted relative to the x-axis (from left to right). This value is relative to portrait orientation, regardless of the default or current orientation of your app. If using a landscape orientation, you’ll need to compensate for this. Includes smoothing to improve user experience.
event.latitude
and event.longitude
- give the latitude and longitude of the device, in degrees.
event.altitude
- gives the altitude, in meters.
event.accuracy
- gives the accuracy of the location, in meters.
event.speed
- gives the instantaneous speed of the device, in meters per second.
event.direction
- gives the direction the device is travelling in, in degrees clockwise from
true North.
event.time
- gives the timestamp of the location event.
Heading Events (Requires Compass)
For devices with a compass, you can set up a listener with format
Runtime:addEventListener( "heading", handler_name )
that passes the following properties to the handler function:
event.geographic
- gives a heading, in degrees, relative to the geographic North Pole (true
North).
event.magnetic
- gives a heading, in degrees, relative to the magnetic North Pole.