jump_physics_improved

The game screen appears here if your browser supports the Canvas API.

Attribution

This code example is taken from Wireframe #7 Source Code: Super Mario-style jumping physics, pages 32-33. The code example was created by Rik Cross.

Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.

Original Python code


# define screen size
WIDTH = 800
HEIGHT = 800
# define a colour
MAROON = 128,0,0
# vertical acceleration
GRAVITY = 0.2

# a list of platforms, each is a rectangle
# in the form ((x,y)(w,h))
platforms = [
    Rect((0,780),(800,20)),
    Rect((200,700),(100,100)),
    Rect((400,650),(100,20)),
    Rect((600,600),(100,20))
]

# create a player and define initial vertical velocity
player = Actor('player',(50,450), anchor=('left','top'))
player.w = 20
player.h = 20
# define initial and jump velocities
player.y_velocity = 0
player.jump_velocity = -7

def update():

    #
    # horizontal movement
    #

    # temporary variable to store new x position
    newx = player.x
    # calculate new horizontal position if
    # arrow keys are pressed
    if keyboard.left and player.x > 0:
        newx -= 2
    if keyboard.right and player.x < 780:
        newx += 2

    # create a rectangle for the new x position
    newpositionx = Rect((newx,player.y),(player.w,player.h))

    # check whether the new player position
    # collides with any platform
    x_collision = False
    for p in platforms:
        x_collision = newpositionx.colliderect(p) or x_collision

    # only allow the player to move if it
    # doesn't collide with any platforms
    if not x_collision:
        player.x = newx

    #
    # vertical movement
    #

    # temporary variable to store new y position
    newy = player.y

    # acceleration is rate of change of velocity
    player.y_velocity += GRAVITY
    # velocity is rate of change of position
    newy += player.y_velocity

    # create a rectangle for the new y position
    newplayerpositiony = Rect((player.x,newy),(player.w,player.h))

    # check whether the new player position
    # collides with any platform
    y_collision = False
    # also check whether the player is on the ground
    playeronground = False
    # distance from colliding platform (used if on ground)
    ydist = 0
    for p in platforms:
        y_collision = newplayerpositiony.colliderect(p) or y_collision
        # player collided with ground if player's y position is
        # lower than the y position of the platform
        if newplayerpositiony.colliderect(p) and (player.y < p.y):
            playeronground = True or playeronground
            # stick the player to the ground
            player.y = p.y - player.h

    # player no longer has vertical velocity
    # if colliding with a platform
    if y_collision:
        player.y_velocity = 0
    # only allow the player to move if it
    # doesn't collide with any platforms
    else:
        player.y = newy

    # pressing space sets a negative vertical velocity
    # only if player is on the ground
    if keyboard.space and playeronground:
        player.y_velocity = player.jump_velocity

def draw():

    screen.clear()

    # draw platforms
    for p in platforms:
        screen.draw.filled_rect(p,MAROON)

    # draw player
    player.draw()