Pygame 2D Platformer Полная столкновение платформ - PullRequest
0 голосов
/ 15 февраля 2020

Я пытался создать 2D-платформер в Pygame, и я столкнулся с проблемой столкновения спрайта игрока с платформой. Я надеюсь реализовать полное столкновение для платформ, чтобы спрайт игрока остановился, когда он ударяет по платформе с любого направления. В настоящее время спрайт останавливается при достижении вершины платформ, но если он сталкивается с дном или боковыми сторонами платформы, он мгновенно перепрыгивает на верх платформы. Я пробовал разные вещи, чтобы решить эту проблему, но безрезультатно. Любая помощь будет оценена.

Я разделил свой код на 3 файла. Это мой основной файл:

import pygame
from settings import *
from sprites import *


#Game Class
class Game:                   

    def __init__(self):
        pygame.init()
        pygame.mixer.init()
        self.gameDisplay = pygame.display.set_mode((displayWidth, displayHeight))
        self.clock = pygame.time.Clock()
        self.gameRunning = True


    #Stars the game
    def new(self):
        self.allSprites = pygame.sprite.Group()
        self.platforms  = pygame.sprite.Group()
        self.player = Player(self)
        self.allSprites.add(self.player)
        floor = Platform(0, 680, displayWidth, 40)
        plat2 = Platform( 500, 400, 100, 40)
        self.allSprites.add(floor, plat2)
        self.platforms.add(floor, plat2)
        self.run()

    #Game Loop
    def run(self):
        self.gameRunning = True
        while self.gameRunning == True:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()

    #Updates the screen
    def update(self):     
        self.allSprites.update()

        hits = pygame.sprite.spritecollide(self.player, self.platforms, False)

        if hits:
            self.player.pos.y = hits[0].rect.top
            self.player.spd.y = 0
            self.player.rect.midbottom = self.player.pos

        if self.player.rect.left >= displayHeight - 200:
            self.player.pos.x -= abs(self.player.spd.x)
            for plat in self.platforms:
                plat.rect.x -= abs(self.player.spd.x)
        if self.player.rect.right <= displayHeight / 4:
            self.player.pos.x += abs(self.player.spd.x)
            for plat in self.platforms:
                plat.rect.x += abs(self.player.spd.x)


    #Events loop
    def events(self):       
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    self.player.jump()


    #Draws things to the screen
    def draw(self):         
        self.gameDisplay.fill(LIGHT_BLUE)
        self.allSprites.draw(self.gameDisplay)

        pygame.display.update()


def runGame():    
    game = Game()
    game.new()
runGame()

Файл спрайтов:

import pygame
from settings import *
vec = pygame.math.Vector2

#Player Class
class Player(pygame.sprite.Sprite):

    def __init__(self, game):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.image = pygame.Surface([40, 40])
        self.image.fill(DARK_BLUE)
        self.rect = self.image.get_rect()
        self.rect.center = (displayWidth / 2, displayHeight / 2)
        self.pos = vec(displayWidth / 2, displayHeight / 2)
        self.spd = vec(0,0)
        self.acc = vec(0,0)


    def update(self):
        self.acc = vec(0, playerGrav)
        keysPressed = pygame.key.get_pressed()
        if keysPressed[pygame.K_LEFT]:
            self.acc.x = - playerAcc
        if keysPressed[pygame.K_RIGHT]:
            self.acc.x = playerAcc


        self.acc.x += self.spd.x *  playerFric
        self.spd += self.acc
        self.pos += self.spd + 0.5 * self.acc

        self.rect.midbottom = self.pos



    def jump(self):
        self.rect.y +=1
        hits = pygame.sprite.spritecollide(self, self.game.platforms, False)
        self.rect.y -= 1
        if hits:
            self.spd.y = -20


class Platform(pygame.sprite.Sprite):

    def __init__(self, x, y, w, h):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((w, h))
        self.image.fill((GREEN))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

Файл настроек:

import pygame

pygame.font.init()

#Setup
FPS = 60
displayWidth = 1280
displayHeight = 720
pygame.display.set_caption("2D Platformer")
gameDisplay = pygame.display.set_mode((displayWidth, displayHeight))
clock = pygame.time.Clock()

#Player
playerAcc = 0.5
playerFric = -0.1
playerGrav = 0.5


#Colour Pallette
BLACK      = (0,   0,   0  )
WHITE      = (255, 255, 255)
RED        = (200, 0,   0  )
GREEN      = (0,   200, 0  )
BLUE       = (0,   0,   200)
LIGHT_BLUE = (0,   191, 255)
DARK_BLUE  = (0,   50,   150)

#Score
score = 0

Это код, который отвечает за столкновение:

hits = pygame.sprite.spritecollide(self.player, self.platforms, False)

if hits:
    self.player.pos.y = hits[0].rect.top
    self.player.spd.y = 0
    self.player.rect.midbottom = self.player.pos

Я понимаю, что причина, по которой спрайт переходит на верх платформы, заключается в следующих строках кода:

if hits:
    self.player.pos.y = hits[0].rect.top

Однако я не знаю, как реализовать полное столкновение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...