问题描述
我目前正在尝试习惯 pygame,因此正在构建一个平台游戏。我已经搜索过这个问题,但我找不到任何相关的东西。问题是我的播放器在我的平台矩形顶部发生碰撞时会在左侧或右侧发生碰撞。我尝试实施多个修复,例如交替玩家 y 位置,这会产生其他问题,并且仅在玩家击中任一侧而不是顶部时才触发碰撞效果,但似乎没有任何东西可以放弃传送玩家。这会导致碰撞不会触发或玩家与平台左上角或右上角的隐形墙发生碰撞。下面是相关文件的代码(pg = pygame):
from pygame.locals import *
from settings import *
vec = pg.math.Vector2
platforms = pg.sprite.Group()
grounds = pg.sprite.Group()
all_except_player = pg.sprite.Group()
class Player(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((20,20))
self.image.fill(blue)
self.rect = self.image.get_rect()
self.pos = vec((10,780))
self.vel = vec(0,0)
self.acc = vec(0,0)
def update(self):
platforms.add(plat1)
grounds.add(ground)
all_except_player.add(plat1,ground)
self.acc = vec(0,0.5)
hits = pg.sprite.spritecollide(p,all_except_player,False)
if p.vel.y > 0:
if hits:
self.pos.y = hits[0].rect.top + 1
self.vel.y = 0
# this is where I assume the problem lies
wall_hits = pg.sprite.spritecollide(p,platforms,False)
if p.vel.x > 0:
if wall_hits:
self.pos.x = wall_hits[0].rect.left - 10
self.vel.x = 0
if p.vel.x < 0:
if wall_hits:
self.pos.x = wall_hits[0].rect.right + 10
self.vel.x = 0
keys = pg.key.get_pressed()
if keys[pg.K_a]:
self.acc.x -= acc
if keys[pg.K_d]:
self.acc.x += acc
if keys[pg.K_SPACE]:
self.jump()
self.acc.x += self.vel.x * fric
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
if self.pos.x > width:
self.pos.x = 0
if self.pos.x < 0:
self.pos.x = width
self.rect.midbottom = self.pos
def jump(self):
hits = pg.sprite.spritecollide(self,False)
if hits:
self.vel.y -= 15
class Ground(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((width,20))
self.image.fill(green)
self.rect = self.image.get_rect(center=(width/2,height - 10))
class Platform(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((100,300))
self.image.fill(gray)
self.rect = self.image.get_rect(center=(width/2,height - 10))
plat1 = Platform()
p = Player()
ground = Ground()
如果有人能帮助我并指出我的错误,我将不胜感激。
解决方法
将其拆分为 2 个单独的问题。首先处理与平台侧面的碰撞。 玩家向右移动时与平台左侧发生碰撞,发生碰撞但玩家左侧不与平台发生碰撞。 向右移动时与平台右侧碰撞,发生碰撞但右侧不与平台碰撞。 如果玩家侧向碰撞,请纠正他的位置,以免他进一步碰撞。 之后,再做一次新的碰撞测试,处理与平台顶部的碰撞:
# handle sideways collision
self.rect.midbottom = self.pos
hits = pg.sprite.spritecollide(p,all_except_player,False)
if hits:
if p.vel.x > 0 and self.rect.left < hits[0].rect.left:
self.rect.right = hits[0].rect.left
self.pos = self.rect.midbottom
self.vel.y = 0
elif p.vel.x < 0 and self.rect.right > hits[0].rect.right:
self.rect.left = hits[0].rect.right
self.pos = self.rect.midbottom
self.vel.y = 0
# handel vertical collision
hits = pg.sprite.spritecollide(p,False)
if hits and p.vel.y > 0:
self.rect.bottom = hits[0].rect.top + 1
self.rect.midbottom = self.pos
self.vel.y = 0