Tutorial:Baseline 2D Platformer

O.png This tutorial is incomplete. Do you want to complete it?  


Due to a request on IRC, this guide has been written to show a basic implementation of platformer-style jumping physics for a player character.

The tutorial is fairly basic and even a newbie should have no issue understanding.

First, let's start off with our basic code, without any jumping.

function love.load()
  -- Nice and organised
  player = {
    x = 0,
    y = 0,
    
    image = love.graphics.newImage("hamster.png") -- Let's just re-use this sprite
  }

  winW, winH = love.graphics.getWidth(), love.graphics.getHeight() -- This is just so we can draw it in a fabulous manner
end

function love.draw()
  love.graphics.rectangle("fill", 0, winH / 2, winW, winH / 2)
  love.graphics.translate(winW / 2, winH / 2) -- You don't need to understand this

  love.graphics.draw(player.image, player.x, -player.y, 0, 1, 1, 64, 103) -- Trust me on the origin position. Just trust me
end
Note: The hamster.png file is File:Resource-HamsterBall.png.

You should get something that looks like this:

PlatformerJumpingStepOne.jpg

Now, it's time to make it jump. To do this, we'll give the player an upwards velocity, create a gravity variable and a jump height variable.

Add this to your love.load function:

player = {
  ...
  y_velocity = 0,
  ...
}

...
gravity = 400
jump_height = 300
...

When the player presses the jump button (spacebar for this tutorial) we will increase the x_velocity by the jump_height.

Then, we will move the player upwards while decreasing the velocity by the gravity. We'll add a love.update and love.keypressed callback to make this work.

function love.update(dt)
  if player.y_velocity ~= 0 then -- We're probably jumping
    player.y = player.y + player.y_velocity * dt -- "dt" means we wont move at different speeds if the game lags
    player.y_velocity = player.y_velocity - gravity * dt
		
    if player.y < 0 then -- We hit the ground again
      player.y_velocity = 0
      player.y = 0
    end
  end
end

function love.keypressed(key, scancode, isrepeat)
  if key == "space" then
    if player.y_velocity == 0 then -- We're probably on the ground, let's jump
      player.y_velocity = jump_height
    end
  end
end

Yay, jumping!

However, this is not true platformer-style jumping. In a lot of platformers, holding the jump key makes you jump higher. Let's implement this.

First, let's create a new player variable in love.load.

player = {
  ...
  jetpack_fuel = 0.5, -- Note: not an actual jetpack. Variable is the time (in seconds) you can hold spacebar and jump higher.
  jetpack_fuel_max = 0.5,
  ...
}

Now, we remove our love.keypressed callback. We won't exact time, which is just bothersome to find out using keypressed and keyreleased. Instead, we'll move that logic to love.update.

function love.update(dt)
  if player.jetpack_fuel > 0 and love.keyboard.isDown("space") then -- We can still move upwards and we're actually holding space
    player.jetpack_fuel = player.jetpack_fuel - dt -- Decrease the fuel meter
    player.y_velocity = player.y_velocity + jump_height * (dt / player.jetpack_fuel_max)
  end

  if player.y_velocity ~= 0 then -- we're probably jumping
    player.y = player.y + player.y_velocity * dt -- "dt" means we wont move at different speeds if the game lags
    player.y_velocity = player.y_velocity - gravity * dt

    -- We hit the ground again
    if player.y < 0 then
      player.y_velocity = 0
      player.y = 0
      player.jetpack_fuel = player.jetpack_fuel_max
    end
  end
end


Other languages