Прыжки при столкновении со стеной в Pygame

Я делаю платформер с редактором уровней с pygame 2.7.9. Есть несколько проблем с кодом. Во-первых, я не могу прыгать, когда стою на стене. Во-вторых, движения моего персонажа на стенах не плавные. playWallList - это список всех стен на уровне.

import pygame, random, sys
from pygame.locals import *
running = True #Flags game as on

class PlayPlayer(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = images["spr_player"]
        self.rect = self.image.get_rect()
        self.rect.topleft = placedPlayer.rect.topleft
        self.speedX, self.speedY = 0, 0
    def update(self):
        global playWallList
        self.rect.y += self.speedY
        self.rect.x += self.speedX
        self.calc_grav()
        wall_hit_list = pygame.sprite.spritecollide(self, playWallList, False)
        for wall in wall_hit_list:
            if(self.speedX > 0): #player moves right and collides into wall
                self.rect.left = wall.rect.right
            elif(self.speedX < 0): #player moves left and collides into wall
                self.rect.right = wall.rect.left
        # Check and see if we hit anything
        wall_hit_list = pygame.sprite.spritecollide(self, playWallList, False)
        for wall in wall_hit_list:
            # Reset our position based on the top/bottom of the object.
            if self.speedY > 0:
                self.rect.bottom = wall.rect.top
            elif self.speedY < 0:
                self.rect.top = wall.rect.bottom
            # Stop our vertical movement
            self.speedY = 0
    def go_left(self):
        self.speedX = -3
    def go_right(self):
        self.speedX = 3
    def stop(self):
        self.speedX = 0
    def calc_grav(self):
        if self.speedY == 0:
            self.speedY = 1
        else:
            self.speedY += .25
    def jump(self):
        global playWallList
        self.speedY += 2
        platform_hit_list = pygame.sprite.spritecollide(self, playWallList, False)
        self.speedY -= 2
        # Checks to make sure if it is ok to jump
        if len(platform_hit_list) > 0 or self.rect.bottom >= screenHeight:
            self.speedY = -10

while running:
    for event in pygame.event.get():
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT and player[0].speedX < 0:
                player[0].stop()
            if event.key == pygame.K_RIGHT and player[0].speedX > 0:
                player[0].stop()
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[K_LEFT]:
        player[0].go_left()
    if keys_pressed[K_RIGHT]:
        player[0].go_right()
    if keys_pressed[K_UP]:
        player[0].jump()

person gamelanguage    schedule 26.05.2015    source источник
comment
вы можете опубликовать полный код?   -  person Liam    schedule 27.05.2015
comment
Разобрался, выложил свое решение   -  person gamelanguage    schedule 27.05.2015


Ответы (1)


Первую проблему мне удалось решить, но я забыл, как это сделать. Вторую проблему я решил, установив self.rect.y + = self.speedY после, а не до wall_hit_list (при проверке коллизий для X). Вот обновленный код, который работает (для прыжков и столкновений со стенами):

class PlayPlayer(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = images["spr_player"]
        self.rect = self.image.get_rect()
        self.rect.topleft = placedPlayer.rect.topleft
        playsprites.add(self)
        self.speedX, self.speedY = 0, 0
        self.jumpReset = 0
    def update(self):
        global playWallList, wall_hit_list
        self.calc_grav()
        self.rect.x += self.speedX
        wall_hit_list = pygame.sprite.spritecollide(self, playWallList, False)
        for wall in wall_hit_list:
            if(self.speedX > 0): #player moves right and collides into wall
                self.rect.right = wall.rect.left
            elif(self.speedX < 0): #player moves left and collides into wall
                self.rect.left = wall.rect.right
        self.rect.y += self.speedY
        # Check and see if we hit anything
        wall_hit_list = pygame.sprite.spritecollide(self, playWallList, False)
        for wall in wall_hit_list:
        # Reset our position based on the top/bottom of the object.
            if self.speedY > 0:
                self.rect.bottom = wall.rect.top #On top of the wall
                self.jumpReset = 0
            elif self.speedY < 0:
                self.rect.top = wall.rect.bottom #Below the wall
            # Stop our vertical movement
            self.speedY = 0
def go_left(self):
    self.speedX = -3
def go_right(self):
    self.speedX = 3
def stop(self):
    self.speedX = 0
def calc_grav(self):
    if self.speedY == 0:
        self.speedY = 1
    else:
        self.speedY += .25
    # On ground?
    if self.rect.y >= screenHeight-32 and self.speedY >= 0:
        self.jumpReset = 0
        self.speedY = 0
        self.rect.y = screenHeight-32
def jump(self):
    global wall_hit_list
    self.speedY += 2
    self.speedY -= 2
    # Checks to make sure if it is ok to jump
    if len(wall_hit_list) > 0 or self.rect.bottom >= screenHeight-32:
        self.speedY = -8
        self.jumpReset = 1
while running:
    for event in pygame.event.get():
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT and player[0].speedX < 0:
                player[0].stop()
            if event.key == pygame.K_RIGHT and player[0].speedX > 0:
                player[0].stop()
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[K_LEFT]:
        if player[0].rect.left > 0:
            player[0].go_left()
        else:
            player[0].stop()
    if keys_pressed[K_RIGHT]:
        if player[0].rect.right < screenWidth:
            player[0].go_right()
        else:
            player[0].stop()
    if keys_pressed[K_UP]:
        if player[0].jumpReset == 0:
            player[0].jump()
person gamelanguage    schedule 27.05.2015