到目前为止,我有一个玩家类,每次更新方法都会对其进行重力处理,现在我所有的引力方法都会检查玩家是否与地面发生碰撞,如果没有碰撞则玩家yVel + = 1,但是从不超过13(每帧不超过13个像素),但问题是如果我的播放器正好在地面上并且落在地面上(13)像素,他就会卡在中间位置地面,不能跳回来。有什么方法可以解决这个问题,还是我需要在我的播放器类中完全重写所有内容?
import pygame
import time # lint:ok
from pygame.locals import *
char = 'ball.png'
char_jump = 'ball_jump.png'
ball = pygame.image.load(char)
ballJump = pygame.image.load(char_jump)
class Player(pygame.sprite.Sprite):
def __init__(self, screen, image, xPos, yPos, xVel, yVel, checkGroup):
pygame.sprite.Sprite.__init__(self)
self.xPos = xPos
self.yPos = yPos
self.xVel = xVel
self.yVel = yVel
self.image = image
self.screen = screen
self.rect = self.image.get_rect()
self.isInAir = True
self.checkGroup = checkGroup
def draw(self, screen):
screen.blit(self.image, self.rect)
def update(self):
self.gravity()
self.xPos += self.xVel # updates x and y based on velocities
self.yPos += self.yVel # updates rect
self.rect.topleft = (self.xPos, self.yPos) # updates sprite rectangle
if self.xPos > 440: # keeps player from going to far right and left
self.xPos = 440
if self.xPos < -3: # #########
self.xPos = -3
def gravity(self):
if self.checkCollision(self.checkGroup) is True:
self.yVel = 0
elif self.checkCollision(self.checkGroup) is False:
self.yVel = 50
def jump(self):
if self.isInAir is False:
print('jump')
self.yVel -= 20
self.image = ballJump
def moveRight(self):
self.xVel = 3
def moveLeft(self):
self.xVel = -3
def stopLeft(self):
self.xVel = 0
self.image = ball
def stopRight(self):
self.xVel = 0
self.image = ball
def stopJump(self):
self.image = ball
if self.yVel < 0: # if player is still jumping up
self.yVel = 1 # make y Velocity positive (fall down)
def checkCollision(self, group):
if pygame.sprite.spritecollideany(self, group):
return True
elif not pygame.sprite.spritecollideany(self, group):
return False
答案 0 :(得分:1)
首先,您的碰撞检查是多余的:
def checkCollision(self, group):
if pygame.sprite.spritecollideany(self, group):
return True
elif not pygame.sprite.spritecollideany(self, group):
return False
如果没有碰撞,两次调用spritecollideany
。你可以使用:
def checkCollision(self, group):
return pygame.sprite.spritecollideany(self, group)
相同
def gravity(self):
if self.checkCollision(self.checkGroup) is True:
self.yVel = 0
elif self.checkCollision(self.checkGroup) is False:
self.yVel = 50
可以改写为
def gravity(self):
self.yVel = 0 if self.checkCollision(self.checkGroup) else 50
现在问题:
你检查你的玩家是否与某些东西发生碰撞,如果是,你就停止移动。这会导致您描述的问题,因为您不会检查移动的每个像素的碰撞,而只检查每个第n个像素的碰撞,其中n是您的行进速度。一种常见的方法是使用称为CCD(连续碰撞检测)的东西,但这超出了这个答案的范围。
更简单的方法如下:
首先检查x轴的碰撞,然后检查y轴的碰撞。如果注册碰撞,请检测导致碰撞的对象。然后将玩家的位置改为该对象的顶部。您可以找到完整的示例here。
def collide(self, xvel, yvel, platforms):
for p in platforms:
if sprite.collide_rect(self, p):
...
if xvel > 0: self.rect.right = p.rect.left
if xvel < 0: self.rect.left = p.rect.right
if yvel > 0:
self.rect.bottom = p.rect.top # <- relevant line
...
self.yvel = 0
if yvel < 0: self.rect.top = p.rect.bottom
如果你有一个简单的游戏,大多数时候这是一个很好的方法。