1

I've watched many videos but couldn't implement the code into my code. All I need is a smooth jump. I've written most of this from video tutorials by DaFluffyPotato. I've just begun OOP so it wud be great if there aren't too many classes and such!

Please read the comments in the code

# I have a player image and with the a and d keys, I can move left and right.
# The w key is for jumping
# I've also implemented Gravity on the Y axis.


import pygame
import sys
pygame.init()
clock = pygame.time.Clock()

# window_width
ww = 760
# window_height
wh = 520
# window_color
wc = (135, 206, 250)
# window
w = pygame.display.set_mode((ww, wh))

tile_size = 40

# loading and scaling images
player_img = pygame.image.load('player.png')
player_img = pygame.transform.scale(player_img, (40, 40))


# global variables for movement
# the 'p's stand for player
# X and Y axis for player
pcoors = [400, 300]
pleft = False
pright = False
pjump = False
pspeed = 2
gravity = 1.2

Check if they are True or False and then implement movement in the player_movement func below

def userInput():
    # you cannot alter global variables from a local scope
    global pleft, pright, pjump
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # keyPresses
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                pleft = True

            if event.key == pygame.K_d:
                pright = True

            if pjump == False and event.key == pygame.K_SPACE and jump_offset == 0:
                pjump = True

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                pleft = False

            if event.key == pygame.K_d:
                pright = False



def player_movement():
    global pleft, pright, pjump, pcoors, pspeed, gravity

    if pleft:
        pcoors[0] -= pspeed

    if pright:
        pcoors[0] += pspeed

    pcoors[1] += gravity

    

def col_detection():
    global pcoors
    
    if pcoors[1] + 40 >= wh:
        pcoors[1] = wh - 40



def img_blit():
    w.blit(player_img, (pcoors))
    


while True:
    w.fill(wc)

    # calling the functions to keep the while loop clean
    userInput()
    player_movement()
    img_blit()
    col_detection()

    clock.tick(360)
    pygame.display.update()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Lord weebu
  • 25
  • 4

1 Answers1

1

Add variables for the vertical acceleration and movement of the player:

acc_y = 0
vel_y = 0

The acceleration is set by the force of gravity in each frame. When space> is pressed an the player jumps, the acceleration is changed:

def userInput():
    # you cannot alter global variables from a local scope
    global pleft, pright, pjump, acc_y
    
    acc_y = gravity
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # keyPresses
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                pleft = True
            if event.key == pygame.K_d:
                pright = True

            if pjump == False and event.key == pygame.K_SPACE and not pjump:
                pjump = True
                acc_y = -15   # <---

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                pleft = False
            if event.key == pygame.K_d:
                pright = False

Change the velocity depending on the acceleration and the y coordinate depending on the velocity in every frame:

def player_movement():
    global pleft, pright, pjump, pcoors, pspeed, vel_y, acc_y

    if pleft:
        pcoors[0] -= pspeed
    if pright:
        pcoors[0] += pspeed

    vel_y += acc_y
    pcoors[1] += vel_y

The jump ends when the player hits the ground:

def col_detection():
    global pcoors, pjump, vel_y
    
    if pcoors[1] + 40 >= wh:
        pcoors[1] = wh - 40
        pjump = False
        vel_y = 0

Your frame rate is very high (clock.tick(360)). I recommend to reduce the framerate, but increase the speed of the player:

pspeed = 10
clock.tick(60)

Complete example

import pygame
import sys
pygame.init()
clock = pygame.time.Clock()

# window_width
ww = 760
# window_height
wh = 520
# window_color
wc = (135, 206, 250)
# window
w = pygame.display.set_mode((ww, wh))

tile_size = 40

# loading and scaling images
try:
    player_img = pygame.image.load('player.png')
    player_img = pygame.transform.scale(player_img, (40, 40))
except:
    player_img = pygame.Surface((40, 40))
    player_img.fill((255, 0, 0))

# global variables for movement
# the 'p's stand for player
# X and Y axis for player
pcoors = [400, 300]
pleft = False
pright = False
pjump = False
pspeed = 10
gravity = 1.2
acc_y = 0
vel_y = 0

def userInput():
    # you cannot alter global variables from a local scope
    global pleft, pright, pjump, acc_y
    
    acc_y = gravity
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # keyPresses
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                pleft = True
            if event.key == pygame.K_d:
                pright = True

            if pjump == False and event.key == pygame.K_SPACE and not pjump:
                pjump = True
                acc_y = -20

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                pleft = False
            if event.key == pygame.K_d:
                pright = False


def player_movement():
    global pleft, pright, pjump, pcoors, pspeed, vel_y, acc_y

    if pleft:
        pcoors[0] -= pspeed
    if pright:
        pcoors[0] += pspeed

    vel_y += acc_y
    pcoors[1] += vel_y
    
def col_detection():
    global pcoors, pjump, vel_y
    
    if pcoors[1] + 40 >= wh:
        pcoors[1] = wh - 40
        pjump = False
        vel_y = 0

def img_blit():
    w.blit(player_img, (pcoors))
    
while True:
    w.fill(wc)
    userInput()
    player_movement()
    col_detection()
    img_blit()
    pygame.display.update()
    clock.tick(60)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174