Search code examples
python-3.xpygamethonny

How to make image jump only on the ground?


I am trying to make an image jump. I when I press the up arrow it goes up until it arrives at a certain position on the Y axis and starts going down. But I have a problem, the image is able to jump infinitely in the air kind of like flappy bird. I would like it to be only able to jump when it arrives at the jump. Here is my code for now:

#Variables
display_width = 900
display_height = 800
gameName = 'Slash'

#Settings
gameTitle = pygame.display.set_caption(gameName)
wn = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()

#Game Loop
def gameLoop():
   #stick man
    manImg = pygame.image.load('blueStickman.png')
    man_width = 58
    man_height = 146
    Xchange = 0
    Ychange = 0
    x = (display_width/2) - (man_width/2) + 1
    y = display_height - man_height
    def man(x,y):
        wn.blit(manImg, (x,y))
    while True:
        wn.fill(white)
        man(x,y)
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()

            if event.type == pygame.KEYDOWN:   
                if event.key == pygame.K_x:
                    pygame.display.quit()
                    pygame.quit()

                if event.key == pygame.K_UP:
                        Ychange = -5
                if event.key == pygame.K_LEFT:
                    Xchange = -4
                if event.key == pygame.K_RIGHT:
                    Xchange = 4

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                        Ychange = -5
                if event.key == pygame.K_LEFT:
                    Xchange = 0
                if event.key == pygame.K_RIGHT:
                    Xchange = 0           

        x += Xchange
        y += Ychange
        if y <= 385:
            Ychange = 5
        if y >= display_height - man_height:
            Ychange = 0

        clock.tick(60)

gameLoop()

Hope you can help and thanks if you can!


Solution

  • First of all I recommend to use pygame.key.get_pressed() for the left and right movement of the player, rather than the KEYDOWN and KEYUP event:

    keys = pygame.key.get_pressed()
    Xchange = 0
    if keys[pygame.K_LEFT]:
        Xchange -= 4
    if keys[pygame.K_RIGHT]:
        Xchange += 4 
    

    Define the ground level of the payer:

    y = display_height - man_height
    ground_y = y
    

    Evaluate if the player is on the ground in the main application loop and discard jumping if the player is not on the ground:

    while True:
        # [...]
    
        on_ground = y == ground_y
    
        for event in pygame.event.get():
                # [...]
    
                if event.type == pygame.KEYDOWN:   
                    # [...]
    
                    if event.key == pygame.K_UP and on_ground:
                        Ychange = -5
    

    See the example:

    import pygame
    
    white = (255, 255, 255)
    
    #Variables
    display_width = 900
    display_height = 800
    gameName = 'Slash'
    
    #Settings
    gameTitle = pygame.display.set_caption(gameName)
    wn = pygame.display.set_mode((display_width, display_height))
    clock = pygame.time.Clock()
    
    #Game Loop
    def gameLoop():
        #stick man
        manImg = pygame.image.load('blueStickman.png')
        man_width, man_height = 58, 156
        Xchange, Ychange = 0, 0
        x = (display_width/2) - (man_width/2) + 1
        y = display_height - man_height
        ground_y = y
    
        def man(x,y):
            wn.blit(manImg, (x,y))
    
        while True:
            wn.fill(white)
            man(x,y)
            pygame.display.update()
    
            on_ground = y == ground_y
    
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
    
                if event.type == pygame.KEYDOWN:   
                    if event.key == pygame.K_x:
                        pygame.display.quit()
                        pygame.quit()
    
                    if event.key == pygame.K_UP and on_ground:
                        Ychange = -5
    
            keys = pygame.key.get_pressed()
            Xchange = 0
            if keys[pygame.K_LEFT]:
                Xchange -= 4
            if keys[pygame.K_RIGHT]:
                Xchange += 4 
    
            x += Xchange
            y += Ychange
            if y <= 385:
                Ychange = 5
            if y >= display_height - man_height:
                Ychange = 0
    
            clock.tick(60)
    
    gameLoop()