Refining Our Character Movement with Corona SDK

Update: Thanks to great comments the double jump for this post has been fixed.

If you’ve been following my other Corona SDK tutorial posts on www.thatssopanda.com (see the previous one here – http://thatssopanda.com/corona-sdk-tutorials/making-a-character-jump-in-corona-sdk/), you can see our little game start to take shape. So far, we’ve covered how to move our guy and make our guy jump using the Corona SDK platform. In today’s post, I want to slow down a bit and refine our guy’s movement. We have two objectives.

1) Don’t let our guy go off screen

2) Only allow one jump

Part 1) There are several ways to accomplish keeping your character on-screen and I feel the easiest way, especially for beginners, is to add two walls to the outside of the screen. We will add one wall 5 pixels to the left of the screen, or x = -5. And we will add a right wall 5 pixels to the right of the screen, or x = Screen Width + 5. Here’s the code.

-- Add Left Wall
local left_wall = display.newRect(-5,0,5,_H)
physics.addBody( left_wall, "static" )

-- Add Right Wall
local right_wall = display.newRect(_W+5,0,5,_H)
physics.addBody( right_wall, "static")

There are a ton of ways to implement keeping a character on screen, but this is one of the easiest ways.

Part 2) To allow only a single jump, we have to add a Runtime Collision Listener. This listener will let us know when our guy is in the air and when he’s touching the ground. It’s not perfect, but in our case, it will work. Here’s the code.

-- Make character jump
function up:touch(event)
if(event.phase == "began" and playerInAir == false) then
playerInAir = true
guy:setLinearVelocity( 0, -200 )
print(playerInAir)
end
end
up:addEventListener("touch",up)

-- Detect whether the player is in the air or not
function onCollision( event )
  if(event.phase == "began") then
    if(event.object1.myName == "grass" and event.object2.myName == "guy") then
      playerInAir = false;
    end
  end
end
Runtime:addEventListener( "collision", onCollision )

And that’s it for today’s post! If you would like to see more tutorials, please leave a comment. This helps keep me motivated to continue to bring high quality tutorials to your site. As always, you can download the full source below. As always, you can download the full source below.

Download Source Code


17 Comments
  1. Your jumping code can actually perform a double jump. If you click up arrow twice. Twice is the maximum though. The double jump is not a bad idea but is there a way to fix this?

    • Do you have any suggestions?

      • I am a newbie and i loved your tutorials. Maybe you can fix double jump by stopping program for accepting any more jump until collision with ground. Try and just remove Event Listener. Maybe it will work.

  2. maybe i can fix that. .if you want? hahaha. . but hey, this site looks promising.my first time here actually, and that’s so pandalicous 🙂

    • Sure, if you get a fix for this, I’ll post it and give you credit!

  3. Does anyone fix the double jump?
    I tried removeEventListener, but it has no effect.
    Could you share please..

  4. Hi, I just found a fix for the double jump problem.
    If you want just one jump, just modify the OnCollision function like this :

    — Detect whether the player is in the air or not
    function onCollision( event )
    if event.phase == “began” then
    if(event.object1.myName == “grass” and event.object2.myName == “guy”) then
    playerInAir = false;
    end
    elseif event.phase == “ended” then
    playerInAir = true;
    end
    end
    Runtime:addEventListener( “collision”, onCollision )

    That’s it, you just have to check the phase of the collision event to see if it’s currently active or not, and change the ballInAir variable to true or false according to its phase.

    Hope I’ve helped you, and sorry for my english, unfortunately my english isn’t very good, because I’m french.

  5. Hi, it’s me again ! I just wanted to share my code for those who would like to put “floating” platforms, and for this case the code provided wouldn’t work.

    Here’s mine, you just have to check y speed of the character and then allow him to jump depending if it’s equal to 0 (not falling or jumping) or not :

    –This is at the beginning of the file
    yspeed = 0
    oldypos = 0

    –This is wherever you can place it
    function onCollision( event )
    if event.phase == “began” then
    –if(event.object1.name == “ground” and event.object2.name == “ball”) or (event.object1.name == “ball” and event.object2.name == “ground”) then
    if yspeed == 0 then
    ballInAir = false
    end
    else
    ballInAir = true
    end
    end
    Runtime:addEventListener( “collision”, onCollision )

    function checkSpeed()
    yspeed = ball.y – oldypos
    oldypos = ball.y
    end

    • Obviously, replace the name I put for the character, ground (e.g. “ground” and not “grass” as in the example) with yours.

    • Thanks so much! Do you mind if I turn this into a blog post?

      • It would be an honor !

        But I made a mistake, if you really want to check speed (and not collision, but it’s technically the same result), you have to modify the code, here’s the final one :

        –At the beginning of the file
        yspeed = 0
        oldypos = 0

        –Wherever you can place it
        function checkSpeed()
        yspeed = guy.y – oldypos
        oldypos = guy.y
        print(yspeed)
        if yspeed == 0 then
        playerInAir = false
        else
        playerInAir = true
        end
        end
        Runtime:addEventListener( “enterFrame”, checkSpeed )

        That’s it. Again, sorry for the mistake.

        • Thanks for your permission! I’ll try to have the post up within a week.

  6. Why exactly must you add “myName” to both collision objects for it to work?

    • The property .myName is used in the collision detection. You can rename the property to be anything you want to as long as it doesn’t conflict with Corona’s API i.e. name, title, etc.

      if(event.object1.myName == “grass” and event.object2.myName == “guy”) then
      playerInAir = false;
      end

  7. I’ve noticed if you right-arrow the character all the way into the right wall, jump functionality gets disabled.

    Any idea why that is?

    • In this tutorial, I kept things simple and there may be a few bugs in it. However, have you tried increasing the iterations of the physics engine?

Leave a Reply