Log In  


I'm trying to put together the physics of a classic platform game in Pico-8. I want to achieve something that behaves like Super Mario Bros.

I have coded a jump system where when the player presses jump, the character rises by a set number of pixels each frame, with that number decreasing every frame, so the character slows down as he gets to the top of his jump. This works well, but I run into problems when I try to implement a variable jump. Like Mario, I'd like my character's jump height to depend on how long the jump button is held down. I did achieve this simply by cancelling the vertical climb when the button is released, but this means that the jump doesn't slow to a halt unless the button is held long enough to see the full jump.

I suspect I'm going about the whole thing in the wrong way and wondered if someone can tell me how the guys at Nintendo did it with Mario. I'm sure there are lots of ways of achieving something similar, but I'd like to know how it was achieved on the NES if possible as I'm as interested in the technique as I am in the end result.

Some Googling suggests that the best method to use is by setting up forces acting on the character. Is this how it would have been accomplished back in the 1980s?

Thanks for any help! :)


P#26259 2016-08-01 08:44 ( Edited 2016-08-02 14:06)

Actually I just found this great description of how the jumping in Sonic the Hedgehog is handled. I'm guessing something similar was done on the Mario games.

Sonic Physics Guide: Jumping

P#26260 2016-08-01 09:34 ( Edited 2016-08-01 13:34)

I don't know exactly how Mario's jump was done, but I imagine there are about 3 variables involved.

jump_height -> How long the button has been held, we need to track this so we can stop the user from jumping once they reach the highest possible height.

y_force -> gravity basically. The amount of pixels to add to the Y position of the character every update.

jump_allowed -> a flag to disabled further jumping if the jump button is released or if they reach the highest they can jump.

Mario appears to have a constant jumping speed while the jump is held down until he reaches the highest point of the jump at which he starts being affected by gravity, so I'd say do something like this (and this is sudo code since I haven't touched pico in a while)

  jump_height = 0
  y_force = 0
  jump_allowed = true


  if jump is held and jump_height < 10 and jump_allowed then
     y_force = -3
     jump_height += 1

  if jump_height == 10 or not jump_allowed
     jump_allowed = false
     jump_height = 0
     y_force += 1 --To have the player start falling

  if player touches the ground
    jump_allowed = true
    y_force = 0

  player_y += y_force

P#26265 2016-08-01 11:07 ( Edited 2016-08-01 15:10)

Hunted down an exhaustive analysis of mario physics. For some reason it was in image format, so I'll just restate the the pertinent part:

Current run speed determines initial velocity (and slightly tweaks gravity). When you jump, holding A reduces gravity as long as vertical speed is upwards.

(Also no air friction and caps for horz and vert speed.)

 (values in pixels, approximately)
[b]run    jump   A   full
speed  vel  grav  grav[/b]
1       4   -2     -7
2.3     4   -1.9   -6
2.6     5   -2.5   -9
P#26296 2016-08-02 00:09 ( Edited 2016-08-02 04:31)

TAS has a complete description of all the NES Mario games. Here is a link to SMB3.

P#26299 2016-08-02 03:44 ( Edited 2016-08-02 07:44)

Those are all great bits of advice and resources, thanks guys!

I have managed to get something set up with acceleration in x and y directions, with gravity, friction, variable jumps and of course floor detection. I'm going to try to get jumps to take into account the run speed as described above and then I'll stick my efforts up on the forum to see what people think.

P#26323 2016-08-02 10:06 ( Edited 2016-08-02 14:06)

Yes, the best way to implement a variable jump in Pico-8, or any other game engine, is to use forces acting on the character. This is how Nintendo did it with Mario in Super Mario Bros and @super mario 64
To implement a variable jump, you would simply increase the jump force the longer the jump button is held down. This would allow the player to jump higher if they hold the jump button down longer.

Here is a simple example of how to implement a force-based jump in Pico-8:

-- Gravity
local gravity = 0.5

-- Jump force
local jump_force = 10

-- Drag
local drag = 0.1

-- Player velocity
local player_velocity = {x = 0, y = 0}

-- Update the player's velocity
function update_player_velocity()
  -- Calculate the net force acting on the player
  local net_force = {x = 0, y = -gravity}

  -- Add the jump force if the jump button is held down
  if pico8.keyp("jump") then
    net_force.y += jump_force

  -- Apply the drag force
  net_force.x *= (1 - drag)
  net_force.y *= (1 - drag)

  -- Add the net force to the player's velocity
  player_velocity.x += net_force.x
  player_velocity.y += net_force.y

-- Update the player's position
function update_player_position()
  player_velocity.x = math.min(player_velocity.x, 10)
  player_velocity.x = math.max(player_velocity.x, -10)

  player_velocity.y = math.min(player_velocity.y, 20)
  player_velocity.y = math.max(player_velocity.y, -20)

  player.x += player_velocity.x
  player.y += player_velocity.y
P#136725 2023-11-01 06:59 ( Edited 2023-11-01 07:01)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2023-12-11 22:35:35 | 0.009s | Q:15