Merle
Merle

Reputation: 81

How can I get my player to wall jump in python 3 and pygame?

I'm trying to make a game in python/pygame where the player can run, jump, and walk on platforms, but I can't get the player to be able to wall jump. I want to make it so the player can land on the side of walls, and then jump off of it, but I can't get it to do this specifically. here's my code, although it's a bit long:

import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

class Player(pygame.sprite.Sprite):

    def __init__(self, color, X, Y):

        super().__init__()

        width = 40
        height = 40

        self.image = pygame.Surface([width, height])

        self.rect = self.image.get_rect()

        self.image.fill(color)

        self.rect.x = X
        self.rect.y = Y

        self.change_x = 0
        self.change_y = 0

        self.jumping = True

    def calc_grav(self):

        if self.change_y == 0:
            self.change_y = 1
        else:
            self.change_y += .35

        if self.rect.y >= 460:
            self.rect.y = 460
            self.change_y = 0

    def update(self, platforms):

        self.calc_grav()

        self.rect.x += self.change_x

        platform_hit_list = pygame.sprite.spritecollide(self, platforms, False)

        for platform in platform_hit_list:
            if self.change_x > 0:
                self.rect.right = platform.rect.left
            else:
                self.rect.left = platform.rect.right

        self.rect.y += self.change_y

        platform_hit_list = pygame.sprite.spritecollide(self, platforms, False)

        for platform in platform_hit_list:
            if self.change_y > 0:
                self.rect.bottom = platform.rect.top
                self.change_y = 0
            elif self.change_y < 0:
                self.rect.top = platform.rect.bottom
                self.change_y = 0
        if self.rect.x >= 680:
            self.rect.x = 680
        elif self.rect.x <= 0:
            self.rect.x = 0

    def jump(self):

        self.rect.y -= 2
        self.change_y = -10
        self.jumping = True

    def bounce(self, x):

        self.rect.x += x
        self.jump()

class Platform(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, color):

        super().__init__()

        self.image = pygame.Surface([width, height])
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.image.fill(color)

pygame.init()

all_sprites_list = pygame.sprite.Group()
platforms = pygame.sprite.Group()

size = (700, 500)

screen = pygame.display.set_mode(size)

pygame.display.set_caption("My Game")

player = Player(RED, 100, 100)
platform = Platform(50, 300, 200, 50, BLUE)

platforms.add(platform)
all_sprites_list.add(player, platform)

done = False

clock = pygame.time.Clock()

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                player.change_x = -6
            elif event.key == pygame.K_d:
                player.change_x = 6
            elif event.key == pygame.K_SPACE and player.change_y == 0:
                player.jump()
            elif event.key == pygame.K_LSHIFT:
                if player.change_x == 6:
                    player.change_x = 9
                elif player.change_x == -6:
                    player.change_x = -9

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                player.change_x = 0
            if event.key == pygame.K_d:
                player.change_x = 0

    player.update(platforms)

    screen.fill(WHITE)
    all_sprites_list.draw(screen)
    pygame.display.flip()

    clock.tick(60)

pygame.quit()

Upvotes: 0

Views: 406

Answers (1)

Peter Gibson
Peter Gibson

Reputation: 19554

You have a condition in your key hander code that will only allow jump to be called if the y velocity is zero:

        elif event.key == pygame.K_SPACE and player.change_y == 0:
            player.jump()

So that's probably why you can't jump when in contact with a wall (your velocity is not zero). I would suggest adding variables to the player class to indicate when they are "wall sliding" and add that as a condition to the key handler above. For example:

        elif event.key == pygame.K_SPACE and (player.change_y == 0 or player.wall_sliding):
            player.jump()

Upvotes: 1

Related Questions