Python Forum
pygame double jump problem
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
pygame double jump problem
#1
Im making a platformer game and I added the jump function but for some reason my player can do double jumps triple jumps and so on how do I fix this
here is my code

from pickle import FALSE
import pygame

from pygame.locals import *

pygame.init()
Clock = pygame.time.Clock()
fps = 60


screen_width =  800
screen_height = 800

screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Platformer')

#define game variables
tile_size = 40
game_over = 0

#load image
bg_img = pygame.image.load("sky.png")
sun_img = pygame.image.load("sun.png")
restart_img = pygame.image.load("restart.png")

class Button():
     def __init__(self, x, y, image):
        self.image = image
        self.rect= self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.clicked = FALSE

     def draw(self):
        action = FALSE

        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                action = True
                self.clicked = True

        if pygame.mouse.get_pressed()[0]  == 0:
            self.clicked = FALSE
                 

        #draw button
        screen.blit(self.image, self.rect)

        return action



class Player():
    def __init__(self, x, y):
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.count = 0
        for num in range (1,3):
            img_right = pygame.image.load(f'guy{num}.png')
            img_right = pygame.transform.scale(img_right, (30, 50))
            img_left = pygame.transform.flip(img_right, True, False)
            self.images_right.append(img_right)
            self.images_left.append(img_left)
        self.dead_image = pygame.image.load('ghost.png')
        self.image = self.images_right[self.index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.width = self.image.get_width()
        self.height = self.image.get_height()
        self.vel_y = 0
        self.jumped = False
        self.direction = 0



    def update(self, game_over):
        dx = 0
        dy = 0
        walk_cooldown = 5

        if game_over == 0:
            #get keypresses
            key = pygame.key.get_pressed()
            if key[pygame.K_SPACE] and self.jumped == False:
                self.vel_y = -15
                self.jumped = True
            if key[pygame.K_SPACE] == False:
                self.jumped = False
            if key[pygame.K_LEFT]:
                dx -= 5
                self.counter += 1
                self.direction = -1
            if key[pygame.K_RIGHT]:
                dx += 5
                self.counter += 1
                self.direction = 1
            if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
                self.counter = 0
                self.index = 0
                if self.direction == 1:
                    self.image = self.images_right[self.index]
                if self.direction == -1:
                    self.image = self.images_left[self.index]


            #handle animation
            if self.counter > walk_cooldown:
                self.counter = 0    
                self.index += 1
                if self.index >= len(self.images_right):
                    self.index = 0
                if self.direction == 1:
                    self.image = self.images_right[self.index]
                if self.direction == -1:
                    self.image = self.images_left[self.index]


            #add gravity
            self.vel_y += 1
            if self.vel_y > 10:
                self.vel_y = 10
            dy += self.vel_y

            #check for collision
            for tile in world.tile_list:
                #check for collision in x direction
                if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
                    dx = 0
                #check for collision in y direction
                if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
                    #check if below the ground i.e. jumping
                    if self.vel_y < 0:
                        dy = tile[1].bottom - self.rect.top
                        self.vel_y = 0
                    #check if above the ground i.e. falling
                    elif self.vel_y >= 0:
                        dy = tile[1].top - self.rect.bottom
                        self.vel_y = 0


            #check for collision with enemies
            if pygame.sprite.spritecollide(self, blob_group, False):
                game_over = -1

            #check for collision with lava
            if pygame.sprite.spritecollide(self, lava_group, False):
                game_over = -1

            #update player coordinates
            self.rect.x += dx
            self.rect.y += dy

        elif game_over == -1:
            self.image = self.dead_image
            if self.rect.y > 800:
             self.rect.y -= 5
          
        #draw player onto screen
        screen.blit(self.image, self.rect)
        pygame.draw.rect(screen, (255, 255, 255), self.rect, 2)

        return game_over

 

class World():
   def __init__(self, data):
        self.tile_list = []

        #load images
        dirt_img = pygame.image.load("dirt.png")
        grass_img = pygame.image.load("grass.png")
        
        #tile and enemie positioning
        row_count = 0
        for row in data: 
            col_count = 0
            for tile in row:
                if tile == 1:
                    img = pygame.transform.scale(dirt_img, (tile_size, tile_size)) 
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect) 
                    self.tile_list.append(tile)              
                if tile == 2:
                    img = pygame.transform.scale(grass_img, (tile_size, tile_size)) 
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect) 
                    self.tile_list.append(tile)   
                if tile == 3:   
                    blob = Enemy(col_count * tile_size, row_count * tile_size + 13)        
                    blob_group.add(blob)
                if tile == 6:
                    lava = Lava(col_count * tile_size, row_count * tile_size + (tile_size // 2))
                    lava_group.add(lava)
                col_count += 1
            row_count += 1
               

   def draw(self):
        for tile in self.tile_list:
            screen.blit(tile[0], tile[1])
            pygame.draw.rect(screen, (255, 255, 255), tile[1], 2)
           



# adding enemies
class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('blob.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y 
        self.move_direction = 1
        self.move_counter = 0

    def update(self):
        self.rect.x += self.move_direction
        self.move_counter += 1
        if abs(self.move_counter) > 50:
            self.move_direction *= -1
            self.move_counter *= -1

class Lava(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('lava.png')
        self.image = pygame.transform.scale(img, (tile_size, tile_size // 2))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y 
    
 
world_data = world_data = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 2, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1,], 
[1, 7, 0, 0, 2, 2, 2, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1,], 
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 1,], 
[1, 0, 2, 0, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,],  
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 1, 1, 1, 1, 1, 1,], 
[1, 0, 0, 0, 0, 2, 2, 2, 2, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1,],  
[1, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], 
[1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,]
]


player = Player(100, screen_height - 130)

#sprite groups help manage multiple sprite object methods for collision detection
blob_group = pygame.sprite.Group()
lava_group = pygame.sprite.Group()

world = World(world_data)

# create buttons
restart_button = Button(screen_width // 2 - 50, screen_height // 2 + 100, restart_img)



run = True
while run:
    
    Clock.tick(fps)

    screen.blit(bg_img, (0,0))
    screen.blit(sun_img, (100,100))

    world.draw()

    if game_over == 0:
        blob_group.update()

    blob_group.draw(screen)
    lava_group.draw(screen)

    game_over = player.update(game_over)

    #if player has died
    if game_over == -1:
        if restart_button.draw():
            pass
         

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

    pygame.display.update()

pygame.quit()
Reply
#2
Your are setting jumped = False when the jump button is not pressed. Instead you should set jumped = False when you land.
                if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
                    #check if below the ground i.e. jumping
                    if self.vel_y < 0:
                        dy = tile[1].bottom - self.rect.top
                        self.vel_y = 0
                    #check if above the ground i.e. falling
                    elif self.vel_y >= 0:
                        dy = tile[1].top - self.rect.bottom
                        self.vel_y = 0
                        self.jumped = False   # The jump is done when you land, not when you stop holding the jump button
Reply
#3
(Nov-20-2022, 06:30 AM)deanhystad Wrote: Your are setting jumped = False when the jump button is not pressed. Instead you should set jumped = False when you land.
                if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
                    #check if below the ground i.e. jumping
                    if self.vel_y < 0:
                        dy = tile[1].bottom - self.rect.top
                        self.vel_y = 0
                    #check if above the ground i.e. falling
                    elif self.vel_y >= 0:
                        dy = tile[1].top - self.rect.bottom
                        self.vel_y = 0
                        self.jumped = False   # The jump is done when you land, not when you stop holding the jump button

Thanks
Reply
#4
A year later I found a solution to this problem in my code thanks to you :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Problem with pygame.event.clear qq12346 1 2,126 Oct-05-2023, 08:39 AM
Last Post: patriciainman
  [PyGame] infinity jump problem augusto_A 3 1,593 May-27-2023, 01:17 AM
Last Post: deanhystad
  [PyGame] Problems with jump code in pygame Joningstone 4 5,394 Aug-23-2021, 08:23 PM
Last Post: deanhystad
  (HELP GREATLY APPRECIATED) New user- Huge Pygame Installation Problem! Jbomb 1 2,841 Jan-12-2021, 07:32 PM
Last Post: MK_CodingSpace
  problem with pygame Aladdin 3 4,231 Jun-25-2020, 01:41 PM
Last Post: Aladdin
  [PyGame] Doodle Jump Dafteaser 2 4,548 May-25-2020, 09:06 AM
Last Post: lolloiltizio
  Problem with music - Pygame.error GaseBall 1 3,210 Nov-28-2019, 07:46 PM
Last Post: SheeppOSU
  [PyGame] Rotation Problem in PyGame thunderbird028 1 2,713 Nov-14-2019, 06:49 AM
Last Post: Windspar
  [PyGame] Having 4 players(Sprites) all being able to jump ElijahCastle 5 4,030 May-07-2019, 05:04 PM
Last Post: SheeppOSU
  My Pygame Project's Problem **huh** osmanb06 2 3,677 Nov-06-2018, 09:27 AM
Last Post: osmanb06

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020