Aug 312011
 

Sensors – What are they and when should we use them in our apps?

Today, rather than giving you a sample project to download, I’m going to be writing some plug and play code you can simply copy and paste. (If you are still quite new to Corona/Lua I would suggest you write it out rather than copying and pasting as it will help you commit it to memory.)

Let’s begin!

Step 1) Create a new folder for our (portrait) app and open up main.lua

Step 2) Hide the status bar;

1
display.setStatusBar(display.HiddenStatusBar)

Step 3) Sensors rely on physics, so set yours up using the following;

1
2
3
require ( "physics" )
physics.start()
physics.setGravity( 0, 0 )

This will start physics and set the gravity at 0,0, which means we can use physics bodies and sensors but they wont get pulled down (or up, left or right,) by gravity.

Step 4) Place a white circle in the top left hand corner of the screen to play our application’s hero, then assign it the correct name and make it a simple dynamic physics body;

1
2
3
local hero = display.newCircle( 40, 40, 30 )
hero.name = "hero"
physics.addBody(hero, "dynamic")

Step 5) In order to test out our sensor (which we will create in a moment) we’re going to need to move the hero around. Create a function to drag the hero, like so;

1
2
3
4
5
local function moveHero (event)
hero.x = event.x
hero.y = event.y
end
hero:addEventListener("touch", moveHero)

Step 6) Create a new circle and turn it into our sensor;

1
2
3
local colorSensor = display.newCircle( 160, 240, 80 )
physics.addBody(colorSensor, {isSensor = true})
colorSensor.alpha = 0.2

You will notice I also set the alpha to 0.2. A sensor can be invisible and still register collision events, however when testing I like 0.2 as it makes it clear the sensor isn’t a regularly object and we can still easily see where it is.

Step 7) Using the sensor we are going to have the hero change color every time he reaches the center of the screen. Add this code to your file;

1
2
3
4
5
6
7
8
9
colorSensor:addEventListener("collision", colorSensor)
function colorSensor:collision (event)
if event.other.name == "hero" and event.phase == "began" then
red = math.random(0,255)
green = math.random(0,255)
blue = math.random(0,255)
hero:setFillColor(red, green, blue)
end
end

And voila!

To explain the last snippet of code a little more clearly, we are first telling the colorSensor to listen for a collision. We are then telling it that if the collision is with an object we’ve named “hero” and the phase is “began” to move forward. (We are doing this because in a game you could have many collisions with many different objects and it is important to know which is which.)

We use “began” because otherwise the hero would change color twice, once when entering the sensor area and once when leaving it. (This would almost always be unwanted in a game situation.)

Lastly, we set red, green and blue at different values each time the hero enters the sensor, then use these values to specify his new color.

Sensors can be used in many scenarios, for example when a hero reaches a certain position on the screen you may want to spawn an enemy. Perhaps you have a gun turret and need to know when the hero is close enough to shoot at, perhaps you want to have physics bodies registering collision without actually knocking each other around.

Sensors are hugely useful; just look at the simple pool example (Corona SDK sample code) to see them used in a real app. See? Useful!

Enjoy and have a wonderful week!

Peach Pellen :)

Like this post? Subscribe to the monthly newsletter!

 

  10 Responses to “Let’s Talk About Sensors”

  1. Yes thanks it makes sense to do that, but how can i trigger events to happen while inSensor == true? I tried a while loop which just crashes the simulator. Would it possible to take a quick look at my code, I’m trying to build upon a tutorial i built from a book

  2. Hello, I have a player and an enemy, the player is a sensor but my collisions only occur when the enemy hits the outside of the sensor, how can i carry the actions on when the enemy is inside the sensor radius?

    Thanks

    • There is a started phase and an ended phase so it fires when the enemy enters and leaves the sensor. You should have some kind of flag like enemy.inSensor = true when it enters, switch to false when it exits. Make sense? :)

  3. Yes, sound APIs have been updated and you should use the new ones. (See audio in APIs or look at Corona For Newbies part 2, which I updated earlier this week for new APIs.) :)

  4. Hi Peach, i used SDK build which is quite old (more than 6 months ago) where I insert a sound upon collision detection and the app went fine.

    But now i changed to the latest build, when the collision detection for the first time, it will play the sound file.
    But the following collision, the sound doesn’t play again.

    My code:

    display.setStatusBar(display.HiddenStatusBar)

    require ( “physics” )
    physics.start()
    physics.setGravity( 0, 0 )

    local knock = media.newEventSound( “knock.caf” )

    local hero = display.newCircle( 40, 40, 30 )
    hero.name = “hero”
    physics.addBody(hero, “dynamic”)

    local function moveHero (event)
    hero.x = event.x
    hero.y = event.y
    end
    hero:addEventListener(“touch”, moveHero)

    local colorSensor = display.newCircle( 160, 240, 80 )
    physics.addBody(colorSensor, {isSensor = true})
    colorSensor.alpha = 0.2

    colorSensor:addEventListener(“collision”, colorSensor)
    function colorSensor:collision (event)
    if event.other.name == “hero” and event.phase == “began” then
    red = math.random(0,255)
    green = math.random(0,255)
    blue = math.random(0,255)
    hero:setFillColor(red, green, blue)
    media.playEventSound( knock )
    end
    end

    any idea why the sound “knock” only play once? (Only the first collision detection)

  5. OK…now it works:-) it was my fault.i had a “typo”.

    Instead of colorSensor:addEventListener(“collision”, colorSensor) i had colorSensor:addEventListener(“collsion”, colorSensor).

    Anyway regarding to a blog post on the ansca website,the addEventListener function should be underneath the listener function.I’ve tried both but it doesn’t matter in this case ’cause it works in both ways.

    • Yes, best practice is to have it below the function – occasionally with collision I end up writing it first. (Bad habit but it works.)

      Glad to hear there was nothing wrong with my code – I was pretty sure it was running right. ;)

  6. Something’s wrong with your code.When i move the “hero” over the “sensor” nothing happens!

    I think the first error is that the “addEventListener” method should be underneath the “listener” function instead of above so that “he” can hear it,right ?

    I did it but that’s not the only problem ’cause it still doesn’t work…

  7. Hey Nick,

    I will, sometimes, go this route – not every time. There are times I can’t for logistical reasons.

    Still, glad you liked it – and yes, the iPad is cool, I don’t have an iPad2 but I don’t use mine that much as it is. (Mostly testing stuff out, really.)

    Peach :)

  8. Nice. Whenever I post code I always make it plug n play. I am happy you went this route. Do you plan on doing this style in the future?

    I’m writing this from my new ipad2 32 gb….actually I bought it for my wife , but I use
    It a lot ;)

    I’ll get ipad3 when it hits next year hehe.

    Ng

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.