SzczureX
SzczureX

Reputation: 91

How to make an object "jump" in pygame

I was trying to create something along the lines of mario, this is far from perfect I know. Anyways, while trying to make the "jumping" method I ran into an issue - The jumping doesn't work the way I intended it to work. Whenether I click the space bar my red square moves up and down randomly, I have to press the spacebar and hold it to complete a jump and even then its not perfect. Sometimes when I hold the space bar for too long the red square will continue to jump again. Is there any way to solve this issue? I'd be very thankful for any help, thanks.

import pygame, time, math, random, sys
from pygame.locals import *

background = pygame.image.load("assets/MarioBackground.png")

def events():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

W, H = 640, 400
HW, HH = W / 2, H / 2
AREA = W * H
FPS = 60
bg_x = 0
isJump = False
jumpCount = 10

pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((W,H))
pygame.display.set_caption("Mario")

class Mario():

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def draw(self):
        pygame.draw.rect(screen, (255,0,0), (self.x, self.y, 40, 40))

    def move(self):
        global bg_x
        if pressed_keys[K_RIGHT] and bg_x > -920:
            if self.x > 490:
                bg_x -= 5
            else:
                self.x += 5
        if pressed_keys[K_LEFT] and self.x > 5:
            self.x -= 5

    def jump(self):
        global jumpCount, isJump
        if pressed_keys[K_SPACE]:
            if jumpCount >= -10:
                isJump = True
                print(jumpCount)
                neg = 1
                if jumpCount < 0:
                    neg = -1
                self.y -= (jumpCount ** 2) * 0.1 * neg
                jumpCount -= 1
            else:
                isJump = False
                jumpCount = 10




mario = Mario(50, 270)

while True:
    clock.tick(FPS)
    events()
    pressed_keys = pygame.key.get_pressed()

    screen.blit(background, (bg_x,0))


    mario.move()
    mario.draw()
    mario.jump()



    pygame.display.update()

Upvotes: 0

Views: 17911

Answers (2)

skrx
skrx

Reputation: 20438

Just check if isJump is true and then execute the jumping code in the jump method. I also recommend adding the isJump and jumpCount as attributes to Mario, so that you don't have to modify global variables.

To prevent the continuous jumping while Space is pressed, you have to handle the key press in the event queue. Then the jump action is triggered only once per key press not while the key is being held down.

import pygame, time, math, random, sys
from pygame.locals import *

background = pygame.Surface((640, 400))
background.fill((30, 90, 120))

W, H = 640, 400
HW, HH = W / 2, H / 2
AREA = W * H
FPS = 60
bg_x = 0

pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((W,H))


class Mario():

    def __init__(self, x, y):
        self.x = x
        self.y = y
        # isJump and jumpCount should be attributes of Mario.
        self.isJump = False
        self.jumpCount = 10

    def draw(self):
        pygame.draw.rect(screen, (255,0,0), (self.x, self.y, 40, 40))

    def move(self):
        global bg_x
        if pressed_keys[K_RIGHT] and bg_x > -920:
            if self.x > 490:
                bg_x -= 5
            else:
                self.x += 5
        if pressed_keys[K_LEFT] and self.x > 5:
            self.x -= 5

    def jump(self):
        # Check if mario is jumping and then execute the
        # jumping code.
        if self.isJump:
            if self.jumpCount >= -10:
                neg = 1
                if self.jumpCount < 0:
                    neg = -1
                self.y -= self.jumpCount**2 * 0.1 * neg
                self.jumpCount -= 1
            else:
                self.isJump = False
                self.jumpCount = 10


mario = Mario(50, 270)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # Start to jump by setting isJump to True.
                mario.isJump = True

    clock.tick(FPS)
    pressed_keys = pygame.key.get_pressed()
    screen.blit(background, (bg_x,0))
    mario.move()
    mario.draw()
    mario.jump()
    pygame.display.update()

Upvotes: 3

Thomas Sablik
Thomas Sablik

Reputation: 16454

You can fix it by implementing the following rules:

  • you can only begin a jump when you touch the floor
  • you start a jump by pressing the space bar (set a variable) and stop it, when you touch the floor
  • you start a jump on keydown (pygame.KEYDOWN) not if pressed.

Some code snippets:

Begin jump

for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE and self.y == 0:
            isJump = True

End jump

if self.y == 0:
    isJump = False

With this rules you can only jump, when you're on the floor. You don't need to hold the space bar and you won't jump a second time if you hold the space bar to long

Upvotes: 3

Related Questions