Python Forum
[PyGame] infinity jump problem
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] infinity jump problem
#1
hey hi, i add jump to my game but the charracter can keep jumping infinitely, how do i fix that? heres my code
import pygame, sys

    level_map = [                   
'                             ',
'                             ',
' XX    XXX            XX     ',
' XX P                        ',
' XXXX         XX         XX  ',
' XXXX       XX               ',
' XX    X  XXXX    XX  XX     ',
'       X  XXXX    XX  XXX    ',
'    XXXX  XXXXXX  XX  XXXX   ',
'XXXXXXXX  XXXXXX  XX  XXXX   ']

title_size = 64
screen_width = 1200
screen_height = len(level_map) * title_size 

class Tile(pygame.sprite.Sprite):
    def __init__(self,pos,size):
        super().__init__()
        self.image = pygame.Surface((size,size))
        self.image.fill('grey')
        self.rect = self.image.get_rect(topleft = pos)

    def update(self,x_shift):
        self.rect.x += x_shift


class Player(pygame.sprite.Sprite):
    def __init__(self,pos):
        super().__init__()
        self.image = pygame.Surface((32,64))
        self.image.fill('red')
        self.rect = self.image.get_rect(topleft = pos)
        #player movment
        self.direction = pygame.math.Vector2(0,0)
        self.speed = 8
        self.gravity = 0.8
        self.jump_speed = -16
        self.jump_counter= 1


    def get_input(self):
        keys = pygame.key.get_pressed()
        #COMANDOS
        if keys[pygame.K_RIGHT]:
            self.direction.x = 1

        elif keys[pygame.K_LEFT]:
            self.direction.x = -1

        else:
             self.direction.x = 0

        if self.jump_counter==1:
            if keys[pygame.K_UP] or keys[pygame.K_SPACE]:
                self.jump()
                self.jump_counter+1
            
    

    def apply_gravity(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y
    def jump(self):
        self.direction.y = self.jump_speed

    def update(self):
        self.get_input()

class Level:
    def __init__(self,level_data,surface):

        # level setup
        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self,layout):
        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()

        for row_index,row in enumerate(layout):
            for col_index,cell in enumerate(row):
                x = col_index * title_size
                y = row_index * title_size
                if cell == 'X':
                    tile = Tile((x,y),title_size)
                    self.tiles.add(tile)
                if cell == 'P':
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)

    def scream_scroll(self):
        Player = self.player.sprite
        Player_x = Player.rect.centerx
        direction_x = Player.direction.x

        if Player_x < screen_width / 10 and direction_x < 0:
            self.world_shift = 5
            Player.speed = 0
        
        elif Player_x > screen_width - (screen_width / 10) and direction_x > 0:
            self.world_shift = -5
            Player.speed = 0

        else:
            self.world_shift = 0
            Player.speed = 5

    def colision_x(self):
        player = self.player.sprite
        player.rect.x += player.direction.x * player.speed
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left

    def colision_y(self):
        player = self.player.sprite
        player.apply_gravity()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                    player.direction.y = 0
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom
                    player.direction.y = 0.5

    

    def run(self):

        #level tiles
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        self.scream_scroll()
        #player
        self.player.update()
        self.colision_x()
        self.colision_y()
        self.player.draw(self.display_surface)



        pygame.init() 
screen = pygame.display.set_mode((screen_width,screen_height))
clock = pygame.time.Clock()
level = Level(level_map,screen)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.fill('black')
    level.run()
    pygame.display.update()

    clock.tick(60)
Reply
#2
You jump as long as the up arrow or space key are pressed.

How do you want to jump. Do you want to do something like flappy birds where each press of the flap/jump key results in accelerating upward, or do you want to jump from the ground?

Assuming the latter, you just need to disallow jumping until you land. The code below uses a "jumping" attribute that is set True when the player jumps and False when the player lands.
import pygame, sys

level_map = [
    "                             ",
    "                             ",
    " XX    XXX            XX     ",
    " XX P                        ",
    " XXXX         XX         XX  ",
    " XXXX       XX               ",
    " XX    X  XXXX    XX  XX     ",
    "       X  XXXX    XX  XXX    ",
    "    XXXX  XXXXXX  XX  XXXX   ",
    "XXXXXXXX  XXXXXX  XX  XXXX   ",
]

title_size = 64
screen_width = 1200
screen_height = len(level_map) * title_size


class Tile(pygame.sprite.Sprite):
    def __init__(self, pos, size):
        super().__init__()
        self.image = pygame.Surface((size, size))
        self.image.fill("grey")
        self.rect = self.image.get_rect(topleft=pos)

    def update(self, x_shift):
        self.rect.x += x_shift


class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((32, 64))
        self.image.fill("red")
        self.rect = self.image.get_rect(topleft=pos)
        # player movment
        self.direction = pygame.math.Vector2(0, 0)
        self.speed = 8
        self.gravity = 0.8
        self.jump_speed = -16
        self.jumping = False

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0

        if (keys[pygame.K_UP] or keys[pygame.K_SPACE]) and not self.jumping:
            self.direction.y = self.jump_speed
            self.jumping = True

    def move_y(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y

    def move_x(self):
        self.rect.x += self.direction.x * self.speed


class Level:
    def __init__(self, level_data, surface):
        # level setup
        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self, layout):
        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()

        for row_index, row in enumerate(layout):
            for col_index, cell in enumerate(row):
                x = col_index * title_size
                y = row_index * title_size
                if cell == "X":
                    tile = Tile((x, y), title_size)
                    self.tiles.add(tile)
                if cell == "P":
                    player_sprite = Player((x, y))
                    self.player.add(player_sprite)

    def scream_scroll(self):
        Player = self.player.sprite
        Player_x = Player.rect.centerx
        direction_x = Player.direction.x

        if Player_x < screen_width / 10 and direction_x < 0:
            self.world_shift = 5
            Player.speed = 0

        elif Player_x > screen_width - (screen_width / 10) and direction_x > 0:
            self.world_shift = -5
            Player.speed = 0

        else:
            self.world_shift = 0
            Player.speed = 5

    def colision_x(self):
        player = self.player.sprite
        player.move_x()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left

    def colision_y(self):
        player = self.player.sprite
        player.move_y()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                    player.jumping = False
                    player.direction.y = 0
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom
                    player.direction.y = 0.5

    def run(self):
        # level tiles
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        self.scream_scroll()
        # player
        self.player.update()
        self.colision_x()
        self.colision_y()
        self.player.draw(self.display_surface)

        pygame.init()


screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
level = Level(level_map, screen)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.fill("black")
    level.run()
    pygame.display.update()

    clock.tick(60)
augusto_A likes this post
Reply
#3
(May-23-2023, 06:01 PM)deanhystad Wrote: You jump as long as the up arrow or space key are pressed.

How do you want to jump. Do you want to do something like flappy birds where each press of the flap/jump key results in accelerating upward, or do you want to jump from the ground?

Assuming the latter, you just need to disallow jumping until you land. The code below uses a "jumping" attribute that is set True when the player jumps and False when the player lands.
import pygame, sys

level_map = [
    "                             ",
    "                             ",
    " XX    XXX            XX     ",
    " XX P                        ",
    " XXXX         XX         XX  ",
    " XXXX       XX               ",
    " XX    X  XXXX    XX  XX     ",
    "       X  XXXX    XX  XXX    ",
    "    XXXX  XXXXXX  XX  XXXX   ",
    "XXXXXXXX  XXXXXX  XX  XXXX   ",
]

title_size = 64
screen_width = 1200
screen_height = len(level_map) * title_size


class Tile(pygame.sprite.Sprite):
    def __init__(self, pos, size):
        super().__init__()
        self.image = pygame.Surface((size, size))
        self.image.fill("grey")
        self.rect = self.image.get_rect(topleft=pos)

    def update(self, x_shift):
        self.rect.x += x_shift


class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((32, 64))
        self.image.fill("red")
        self.rect = self.image.get_rect(topleft=pos)
        # player movment
        self.direction = pygame.math.Vector2(0, 0)
        self.speed = 8
        self.gravity = 0.8
        self.jump_speed = -16
        self.jumping = False

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0

        if (keys[pygame.K_UP] or keys[pygame.K_SPACE]) and not self.jumping:
            self.direction.y = self.jump_speed
            self.jumping = True

    def move_y(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y

    def move_x(self):
        self.rect.x += self.direction.x * self.speed


class Level:
    def __init__(self, level_data, surface):
        # level setup
        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self, layout):
        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()

        for row_index, row in enumerate(layout):
            for col_index, cell in enumerate(row):
                x = col_index * title_size
                y = row_index * title_size
                if cell == "X":
                    tile = Tile((x, y), title_size)
                    self.tiles.add(tile)
                if cell == "P":
                    player_sprite = Player((x, y))
                    self.player.add(player_sprite)

    def scream_scroll(self):
        Player = self.player.sprite
        Player_x = Player.rect.centerx
        direction_x = Player.direction.x

        if Player_x < screen_width / 10 and direction_x < 0:
            self.world_shift = 5
            Player.speed = 0

        elif Player_x > screen_width - (screen_width / 10) and direction_x > 0:
            self.world_shift = -5
            Player.speed = 0

        else:
            self.world_shift = 0
            Player.speed = 5

    def colision_x(self):
        player = self.player.sprite
        player.move_x()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left

    def colision_y(self):
        player = self.player.sprite
        player.move_y()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                    player.jumping = False
                    player.direction.y = 0
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom
                    player.direction.y = 0.5

    def run(self):
        # level tiles
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        self.scream_scroll()
        # player
        self.player.update()
        self.colision_x()
        self.colision_y()
        self.player.draw(self.display_surface)

        pygame.init()


screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
level = Level(level_map, screen)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.fill("black")
    level.run()
    pygame.display.update()

    clock.tick(60)

yes thx that solve my problem
Reply
#4
I was thinking about this, and my code is wrong. As is, you could run off the edge of a platform, and while falling, jump. I think it might make more sense to modify the y collision logic to check for jumping. If you are colliding with the top of a platform and the jump key is pressed, jump.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pygame double jump problem Yegor123 3 2,624 May-02-2023, 09:34 PM
Last Post: sudoku6
  [PyGame] Problems with jump code in pygame Joningstone 4 5,421 Aug-23-2021, 08:23 PM
Last Post: deanhystad
  [PyGame] Doodle Jump Dafteaser 2 4,597 May-25-2020, 09:06 AM
Last Post: lolloiltizio
  [PyGame] Having 4 players(Sprites) all being able to jump ElijahCastle 5 4,054 May-07-2019, 05:04 PM
Last Post: SheeppOSU
  Doodle Jump themed game! georgecoopers 1 5,843 Apr-11-2017, 08:47 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

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