How to make a cube jump in pygame?

Solved
ZHN -  
 Jean -

Hello!

I'm in 11th grade and specializing in computer science - we have to make a game. I'm using Pygame (and PyCharm) - I need to make my cube jump, but I'm struggling to do it. Any solutions TwT?

 import pygame import self as self from pygame import * # Screen size (temporary) SCREEN_WIDTH = 1600 SCREEN_HEIGHT = 850 # Class defining the character #(for now it only has movement across the entire screen, it needs to be restricted and all its functions added) class Character (pygame.sprite.Sprite): # Initialization of the character def __init__(self): super(Character, self).__init__() #shape to be replaced by an image self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #base coordinates to also modify self.rect.x= 200 self.rect.y= 520 self.jump_up = 0 self.jump_down = 3 self.jump_count = 0 #self.resistance #self.gravity self.health=3 def jump(self): jump = True gravity = 1 jump_height = 1 speed = jump_height # Update when the player presses a key to move def update(self, pressed_keys): # Move to the left if pressed_keys[K_LEFT]: self.rect.move_ip(-5, 0) # Move to the right if pressed_keys[K_RIGHT]: self.rect.move_ip(5, 0) if pressed_keys[K_UP]: jump=True if self.rect.left<0: self.rect.left=0 if self.rect.right>SCREEN_WIDTH: self.rect.right = SCREEN_WIDTH if self.rect.y<0: self.rect.y=0 if self.rect.y>520: self.rect.y=520 class Obstacle (pygame.sprite.Sprite): """ this class is really shaky but it displays. the goal is for the obstacle to move left continuously until it exits the screen and eventually there will be multiple subclasses of obstacles with different shapes and effects (like in geometry dash) and when obstacle coordinates = character coordinates (collision) it removes a point """ def __init__ (self): super (Obstacle, self).__init__() #shape to be replaced by an image self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Clock setup clock = pygame.time.Clock() # Sprite group all_sprites = pygame.sprite.Group() # Creating elements (this is to make the elements of the classes display) player = Character() obstacles=Obstacle() all_sprites.add(player) all_sprites.add(obstacles) # Page initialization pygame.init() pygame.display.set_caption("test game") screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) #background = pygame.image.load("images/background.png") # Game loop (continuous loop that continuously updates the game) continue_game = True while continue_game: # close the window for event in pygame.event.get(): if event.type == pygame.QUIT: continue_game = False # black screen (temporary) #fd screen.fill((120, 170, 255)) #ground pygame.draw.rect (screen, (100, 200, 80), (0, 600, 1600, 350)) #keys key_pressed = pygame.key.get_pressed() player.update(key_pressed) # Redraw the objects on the surface for my_sprite in all_sprites: screen.blit(my_sprite.surf, my_sprite.rect) # We pass our surface to display it pygame.display.flip() # Indicates to Pygame not to do more than 50 times per second the gameloop to slow down movement clock.tick(100) pygame.quit() 

Thank you. :)

9 answers

  1. Diablo76 Posted messages 344 Registration date   Status Member Last intervention   140
     

    Hello,

    It's true that if you're just starting out, diving into object-oriented programming is likely to demotivate you :(, but if you do a search online, you should find examples that are more accessible to you like this one:

    import pygame pygame.init() win = pygame.display.set_mode((500,500)) pygame.display.set_caption("First Game") x = 100 y = 400 width = 40 height = 60 vel = 10 isJump = False jumpCount = 10 run = True while run: pygame.time.delay(30) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] and x > vel: x -= vel if keys[pygame.K_RIGHT] and x < 500 - vel - width: x += vel if not(isJump): if keys[pygame.K_UP] and y > vel: y -= vel if keys[pygame.K_DOWN] and y < 500 - height - vel: y += vel if keys[pygame.K_SPACE]: isJump = True else: if jumpCount >= -10: y -= (jumpCount * abs(jumpCount)) * 0.5 jumpCount -= 1 else: jumpCount = 10 isJump = False win.fill((0,0,0)) pygame.draw.rect(win, (255,0,0), (x, y, width, height)) pygame.display.update() pygame.quit()

    Now it's up to you to understand and modify it for your exercise.

    3
    1. ZHN
       

      Yess! Thank you! I managed to adapt it to my code & I understood all the lines!!

      Thank you very much :D

      0
    2. Jean
       

      uh hello :)))

      I have a question similar to ZHN's so I'm writing here to avoid opening a duplicate.
      I'm also planning to take the NSI specialization, and I've started learning a few things. However, in my code, I don't understand how I could make the player jump even when they are in the air (just like in Flappy Bird lol).

      import pygame import random # Pygame initialization pygame.init() # Definition of game window dimensions SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 # Colors WHITE = (255, 255, 255) BLACK = (0, 0, 0) COLLO = (98, 119, 29) BROWN = (153, 76, 0) COLOR = (100, 100, 99) # Creating the game window screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Class for creating enemies class Enemy(pygame.sprite.Sprite): def __init__(self, obstacles): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(BLACK) self.rect = self.image.get_rect() self.rect.x = SCREEN_WIDTH self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) while self.rect.bottom > SCREEN_HEIGHT - 50: self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) self.speed = 3 self.obstacles = obstacles def update(self): self.rect.x -= self.speed # Checks for collision with an obstacle for obstacle in self.obstacles: if self.rect.colliderect(obstacle.rect): self.rect.right = obstacle.rect.left class Obstacle(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(COLOR) self.rect = self.image.get_rect() self.rect.x = SCREEN_WIDTH self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) while self.rect.bottom > SCREEN_HEIGHT - 50: self.rect.y = random.randint(0, SCREEN_HEIGHT - 100) self.speed = random.randint(1, 3) def update(self): self.rect.x -= self.speed class Ground(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((SCREEN_WIDTH, 50)) self.image.fill(BROWN) self.rect = self.image.get_rect() self.rect.x = 0 self.rect.y = SCREEN_HEIGHT - 50 # Class for creating the player class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50, 50)) self.image.fill(COLLO) self.rect = self.image.get_rect() self.speed = 10 self.jump_speed = 20 self.is_jumping = False self.speed_y = 0 def update(self, keys): if keys[pygame.K_UP]: # Allow jumping even if already jumping self.is_jumping = True if self.is_jumping or self.rect.bottom < SCREEN_HEIGHT - 50: self.speed_y += 1 self.rect.y += self.speed_y if self.rect.bottom >= SCREEN_HEIGHT - 50: self.rect.bottom = SCREEN_HEIGHT - 50 self.is_jumping = False self.speed_y = 0 # Creating sprites for enemies and player all_sprites = pygame.sprite.Group() enemies = pygame.sprite.Group() obstacles = pygame.sprite.Group() player = Player() all_sprites.add(player) ground = Ground() all_sprites.add(ground) # Place the player on the ground player.rect.y = SCREEN_HEIGHT - 100 # Main game loop running = True clock = pygame.time.Clock() score = 0 enemy_timer = 0 enemy_spawn_rate = 800 obstacle_timer = 0 obstacle_spawn_rate = 1600 while running: # Event handling for event in pygame.event.get(): if event.type == pygame.QUIT: running = False enemy_timer += clock.get_time() if enemy_timer >= enemy_spawn_rate: enemy = Enemy(obstacles) all_sprites.add(enemy) enemies.add(enemy) enemy_timer = 0 obstacle_timer += clock.get_time() if obstacle_timer >= obstacle_spawn_rate: obstacle = Obstacle() all_sprites.add(obstacle) obstacles.add(obstacle) obstacle_timer = 0 # Moving enemies and collision with player for enemy in enemies: enemy.update() if enemy.rect.right < 0: enemies.remove(enemy) all_sprites.remove(enemy) if enemy.rect.colliderect(player.rect): running = False for obstacle in obstacles: obstacle.update() if obstacle.rect.right < 0: obstacles.remove(obstacle) all_sprites.remove(obstacle) if obstacle.rect.colliderect(player.rect): running = False keys = pygame.key.get_pressed() player.update(keys) # Displaying enemies and player screen.fill(WHITE) all_sprites.draw(screen) pygame.display.flip() # Limit to 60 frames per second clock.tick(80) # Closing Pygame pygame.quit() 
      0
      1. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   1 588 > Jean
         

        If you don't find the answer here, it's best to start a new discussion.

        1
      2. Jean > yg_be Posted messages 23437 Registration date   Status Contributor Last intervention  
         

        ok :) thank you

        0
  2. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   Ambassadeur 1 588
     

    Hello, can't you move your cube up? What have you tried?

    0
  3. ZHN
     

    Hello, thanks for responding :)

    Well, first I tried to

    - move the cube with the up and down arrows across the entire surface - that worked

    - then I wanted to make it jump when pressing space or the up arrow, but that doesn’t work at all (not at all lol) I wrote a jump function

    def jump(self):
    if self.can_jump:
    if self.jump_up>=10:
    self.jump_down-=1
    self.jump=self.jump_down

    else:
    self.jump_up+=1
    self.jump=self.jump_up

    if self.jump_down<0:
    self.jump_up=0
    self.jump_down=5
    self.jump.can_jump = False

    self.rect.y=self.rect.y - (10*(self.jump/2))

    I put that in the Player class, I wrote that in the main game loop

    if event.key == pygame.K_UP:
    self.player.can_jump = True

    self.player.jump_count+=1

    And then at the end I called the jump function, but that doesn’t work either

    Then I followed another tutorial but the game doesn’t open even though there are no errors in the code :(((

    Right now my goal is just to make the cube jump with space or the up arrow

    0
    1. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   1 588
       

      Why didn't you add the code to jump to line 58 instead of in the "base" loop?

      0
  4. ZHN
     

    the code with the function def jump(self): ?

    import pygame import self as self from pygame import * # Screen size (temporary) SCREEN_WIDTH = 1600 SCREEN_HEIGHT = 850 # Class defining the character #(for now there is only its movement across the whole screen it needs to be restricted and add all its functions) class Character (pygame.sprite.Sprite): # Initialization of the character def __init__(self): super(Character, self).__init__() #shape to be replaced by an image self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #base coordinates to modify too self.rect.x= 200 self.rect.y= 520 self.jump_ascent = 0 self.jump_descent = 3 self.number_of_jumps = 0 #self.resistance #self.gravity self.health_points=3 def jump(self): if self.has_jumped: if self.jump_ascent >= 10: self.jump_descent -= 1 self.jump = self.jump_descent else: self.jump_ascent += 1 self.jump = self.jump_ascent if self.jump_descent < 0: self.jump_ascent = 0 self.jump_descent = 5 self.jump.has_jumped = False self.rect.y = self.rect.y - (10 * (self.jump / 2)) # Update when the player presses a key to move def update(self, pressed_keys): # Move left if pressed_keys[K_LEFT]: self.rect.move_ip(-5, 0) # Move right if pressed_keys[K_RIGHT]: self.rect.move_ip(5, 0) if pressed_keys[K_UP]: self.has_jumped = True self.number_of_jumps += 1 if self.rect.left < 0: self.rect.left = 0 if self.rect.right > SCREEN_WIDTH: self.rect.right = SCREEN_WIDTH if self.rect.y < 0: self.rect.y = 0 if self.rect.y > 520: self.rect.y = 520 class Obstacle (pygame.sprite.Sprite): """ this class is really shaky but it displays. the goal is for the obstacle to move left continuously until out of the screen and eventually there will be several subclasses of obstacles with different shapes and effects (like in geometry dash) and when obstacle coordinates = character coordinates (collision) it removes a point """ def __init__ (self): super (Obstacle, self).__init__() #shape to be replaced by an image self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Setting the clock clock = pygame.time.Clock() # Group of Sprites all_sprites = pygame.sprite.Group() # Creation of elements (this is to make the elements of the classes display) player = Character() obstacles=Obstacle() all_sprites.add(player) all_sprites.add(obstacles) # Initialization of the page pygame.init() pygame.display.set_caption("test game") screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) #background = pygame.image.load("images/background.png") # Game loop (continuous loop that continuously updates the game) continue_game = True while continue_game: # close the window for event in pygame.event.get(): if event.type == pygame.QUIT: continue_game = False # black screen (temporary) #fd screen.fill((120, 170, 255)) #ground pygame.draw.rect (screen, (100, 200, 80), (0, 600, 1600, 350)) #keys key_pressed = pygame.key.get_pressed() player.update(key_pressed) # Copy the objects onto the surface screen for my_sprite in all_sprites: screen.blit(my_sprite.surf, my_sprite.rect) # We send our surface to display it pygame.display.flip() # Indicates to Pygame not to run the game loop more than 50 times per second to slow down movement clock.tick(100) pygame.quit()

    ?

    0
    1. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   1 588
       

      Where do you call jump()?

      0
  5. ZHN
     
    import pygame import self as self from pygame import * # Screen size (temporary) SCREEN_WIDTH = 1600 SCREEN_HEIGHT = 850 # Class defining the character #(for now it only has movement across the screen, it needs to be restricted and all its functions added) class Character (pygame.sprite.Sprite): # Initialization of the character def __init__(self): super(Character, self).__init__() #shape to be replaced with an image self.surf = pygame.Surface ((80, 80)) self.surf.fill ((255, 255, 255)) self.rect = self.surf.get_rect () #base coordinates to be modified too self.rect.x= 200 self.rect.y= 520 self.jump_up = 0 self.jump_down = 3 self.number_of_jumps = 0 #self.resistance #self.gravity self.health_points=3 def jump(self): if self.has_jumped: if self.jump_up >= 10: self.jump_down -= 1 self.jump = self.jump_down else: self.jump_up += 1 self.jump = self.jump_up if self.jump_down < 0: self.jump_up = 0 self.jump_down = 5 self.jump.has_jumped = False self.rect.y = self.rect.y - (10 * (self.jump / 2)) # Update when the player presses a key to move def update(self, pressed_keys): # Move left if pressed_keys[K_LEFT]: self.rect.move_ip(-5, 0) # Move right if pressed_keys[K_RIGHT]: self.rect.move_ip(5, 0) if pressed_keys[K_UP]: self.has_jumped = True self.number_of_jumps += 1 if self.rect.left<0: self.rect.left=0 if self.rect.right>SCREEN_WIDTH: self.rect.right = SCREEN_WIDTH if self.rect.y<0: self.rect.y=0 if self.rect.y>520: self.rect.y=520 class Obstacle (pygame.sprite.Sprite): """ this class is really shaky but it displays. the goal is for the obstacle to move continuously to the left until it exits the screen and eventually to have multiple subclasses of obstacles with different shapes and effects (like in geometry dash) and when obstacle coordinates = character coordinates (collision) it removes a point """ def __init__ (self): super (Obstacle, self).__init__() #shape to be replaced with an image self.surf = pygame.Surface ((60, 60)) self.surf.fill ((255, 0, 55)) self.rect = self.surf.get_rect () self.rect.x = 1500 self.rect.y= 520 # Adjusting the clock clock = pygame.time.Clock() # Group of Sprites all_sprites = pygame.sprite.Group() # Creating the elements (this is so that the elements of the classes display) player = Character() obstacles=Obstacle() all_sprites.add(player) all_sprites.add(obstacles) # Initializing the page pygame.init() pygame.display.set_caption("game test") screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) #background = pygame.image.load("images/background.png") # Game loop (continuous loop that continuously updates the game) continue_game = True while continue_game: # close the window for event in pygame.event.get(): if event.type == pygame.QUIT: continue_game = False # black screen (temporary) #fd screen.fill((120, 170, 255)) #ground pygame.draw.rect (screen, (100, 200, 80), (0, 600, 1600, 350)) #keys keys_pressed = pygame.key.get_pressed() player.update(keys_pressed) # Redrawing objects on the surface screen for my_sprite in all_sprites: screen.blit(my_sprite.surf, my_sprite.rect) # We pass our surface to display it pygame.display.flip() # Indicates to Pygame not to do more than 50 times per second in the gameloop to slow down movement clock.tick(100) pygame.quit() 

    it is in the character class and I call the class below

    can I call it jump=jump() ??

    0
    1. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   1 588
       

      Is this your first exercise in Python?

      0
  6. ZHN
     

    Yes :/

    0
    1. yg_be Posted messages 23437 Registration date   Status Contributor Last intervention   1 588
       

      I don't think you're going to make progress by trying to modify a program you don't understand.

      Start with a simpler program that you do yourself.

      0
  7. hudada
     

    Hello.

    Making a character or object jump is simulating gravity, meaning there is a deceleration during the ascent and conversely an acceleration during the descent, one being the opposite of the other, so one might as well use the values from the ascent for the fall.

    An example with some comments.

    import pygame as pg FPS = 60 SCREEN_WIDTH = 500 SCREEN_HEIGHT = 400 SCREEN_COLOR = (0, 0, 0) PLAYER_COLOR = (255, 255, 0) PLAYER_SPEED = 8 GRAVITY = 0.18 class Player(pg.sprite.Sprite): def __init__(self): super().__init__() # A simple surface filled with a color self.image = pg.Surface((50, 50)) self.image.fill(PLAYER_COLOR) self.rect = self.image.get_rect() self.jumping = False self.jumping_list = [] def jump(self, height): if self.jumping: # There is a jump in progress # We don't go further return self.jumping_height = height self.jumping_goal = self.rect.y - height self.jumping_list.append(self.rect.y) self.jumping = -1 def left(self): self.rect.x -= PLAYER_SPEED def right(self): self.rect.x += PLAYER_SPEED def update(self): # Ascent phase if self.jumping == -1: dy = self.jumping_height * GRAVITY self.jumping_height -= dy self.rect.y -= dy # Add the y to the list to use it later # when falling self.jumping_list.append(self.rect.y) if self.rect.y <= self.jumping_goal: # Add 5 times the value of the height to be reached # to have a "heaviness" effect in the fall self.jumping_list.extend([self.jumping_goal] * 5) # Indicates we are moving to falling self.jumping = 1 # Descent phase elif self.jumping == 1: try: # Extract the last value from the list # and assign it to the player's y value self.rect.y = self.jumping_list.pop() except IndexError: # The list is empty, meaning we have returned to the ground # We end the jump phase and indicate that the player can # jump again self.jumping = 0 screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) screen_rect = screen.get_rect() player = Player() # Position the player at the bottom of the screen and 30 px from the left edge player.rect.bottomleft = 30, SCREEN_HEIGHT # Create a sprite group and add our player to this group. draw_group = pg.sprite.Group() draw_group.add(player) clock = pg.time.Clock() running = True while running: for evt in pg.event.get(): if evt.type == pg.QUIT: running = False pressed_keys = pg.key.get_pressed() if pressed_keys[pg.K_LEFT]: player.left() elif pressed_keys[pg.K_RIGHT]: player.right() if pressed_keys[pg.K_UP]: player.jump(100) # Prevent the player from going outside the screen limits player.rect.clamp_ip(screen_rect) screen.fill(SCREEN_COLOR) # Update the group, thereby all the sprites in the group draw_group.update() # Then draw the sprites draw_group.draw(screen) pg.display.update() clock.tick(FPS) pg.quit()

    Add print statements in the player's update method to better understand if you have a hard time knowing what the variables and attributes are worth.

    0