问题描述
我正在创建平台游戏,有红色方块(他们应该杀了我)和白色方块(平台) 当我死了,我应该在当前关卡开始时复活。 我做了碰撞检测,但只有在我移动时才有效(当我跳到红色方块并且我没有按任何东西时,它不起作用)
所以我真的很想知道如何更好地处理碰撞。
谢谢 代码:
from pygame import *
WIN_WIDTH = 1923
WIN_HEIGHT = 1000
disPLAY = (WIN_WIDTH,WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30
pygame.init()
green = (0,255,0)
screen = pygame.display.set_mode(disPLAY,FLAGS,DEPTH)
font = pygame.font.SysFont('Consolas',30)
text = font.render('Your score: ',True,(0,0))
textRect = text.get_rect()
textRect.center = (40,55)
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP","P P","P PP P","P PP P","P PP P","P PP P","P P P","P PP P P","P PP P P","P PP P P","P PPP P PP","P P LP","PSSSSSSSSSSSSSSSSSSSSsspPPSSSSSSSSSSSSSSSSSSSSSSSSsspsspPPPPPP","EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",]
def main():
pygame.display.set_caption("Use W,A,S,D and Space to move!")
timer = pygame.time.Clock()
up = down = left = right = running = left_dash = right_dash = dashing = False
bg = Surface((3200,32))
bg.convert()
bg.fill(Color("#000000"))
entities = pygame.sprite.Group()
platforms = []
killing_entities = []
another_level = []
blockade = []
player = Player(767,900)
x = y = 0
global level
for row in level:
for col in row:
if col == "P":
p = Platform(x,y)
platforms.append(p)
entities.add(p)
if col == "E":
e = Block(x,y)
platforms.append(e)
entities.add(e)
if col == "S":
s = Spike(x,y)
killing_entities.append(s)
entities.add(s)
if col == "L":
l = Another_Level(x,y)
another_level.append(l)
entities.add(l)
x += 32
y += 32
x = 0
entities.add(player)
running = True
while running:
screen.blit(text,textRect)
timer.tick(65)
for e in pygame.event.get():
if e.type == KEYDOWN and e.key == K_SPACE:
up = True
if e.type == KEYDOWN and e.key == K_s:
down = True
if e.type == KEYDOWN and e.key == K_a:
left = True
if e.type == KEYDOWN and e.key == K_d:
right = True
if e.type == KEYDOWN and e.key == K_q:
running = True
if e.type == KEYDOWN and e.key == K_LEFT:
left_dash = True
if e.type == KEYDOWN and e.key == K_RIGHT:
right_dash = True
if e.type == KEYUP and e.key == K_SPACE:
up = False
if e.type == KEYUP and e.key == K_s:
down = False
if e.type == KEYUP and e.key == K_d:
right = False
if e.type == KEYUP and e.key == K_a:
left = False
if e.type == KEYUP and e.key == K_d:
right = False
if pygame.sprite.spritecollideany(player,killing_entities):
main()
if pygame.sprite.spritecollideany(player,another_level):
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP","PPS P","PEE P","PSS P","PP P","P P P","PSSSSSSSSSSSSSSSSSSSSsspPPSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSsspPPP","EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",]
main()
for y in range(32):
for x in range(32):
screen.blit(bg,(x * 32,y * 32))
player.update(up,down,left,right,left_dash,right_dash,running,dashing,platforms)
entities.draw(screen)
pygame.display.flip()
pygame.display.update()
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Player(Entity):
def __init__(self,x,y):
Entity.__init__(self)
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((32,32))
self.image.fill(Color("#0000FF"))
self.image.convert()
self.rect = Rect(x,y,32,32)
def update(self,up,platforms):
if up:
if self.onGround: self.yvel -= 9
if down:
pass
if running:
self.xvel = 12
if left_dash:
self.rect.move_ip(-20,-2)
left_dash = False
if right_dash:
self.rect.move_ip(20,-2)
right_dash = False
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
self.yvel += 0.25
if self.yvel > 100: self.yvel = 100
if not(left or right):
self.xvel = 0
self.rect.left += self.xvel
self.collide(self.xvel,platforms)
self.rect.top += self.yvel
self.onGround = False
self.collide(0,self.yvel,platforms)
def collide(self,xvel,yvel,platforms):
for p in platforms:
if pygame.sprite.collide_rect(self,p):
if isinstance(p,Block):
pygame.event.post(pygame.event.Event(QUIT))
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
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
self.onGround = False
class Platform(Entity):
def __init__(self,y):
Entity.__init__(self)
self.image = Surface((32,32))
self.image.convert()
self.image.fill(Color("#ddddDF"))
self.rect = Rect(x,32)
def update(self):
pass
class Block(Platform):
def __init__(self,y):
Platform.__init__(self,y)
self.image.fill(Color("#000000"))
class Spike(pygame.sprite.Sprite):
def __init__(self,y)
self.image = Surface((33,33))
self.image.convert()
self.image.fill(Color("#E70018"))
self.rect = Rect(x,33,33)
class Another_Level(pygame.sprite.Sprite):
def __init__(self,33))
self.image.convert()
self.image.fill(Color("#8C563E"))
self.rect = Rect(x,33)
if __name__ == "__main__":
main()```
解决方法
您检查每个帧中每个事件与 killing_entities
列表的冲突。因此,如果事件队列中当前没有事件,则行:
if pygame.sprite.spritecollideany(player,killing_entities):
main()
永远不会被执行。我猜您只希望在主循环中使用该代码,而不是在事件处理循环中。
您的代码中还有一些奇怪的地方,例如
-
您不处理
QUIT
event,因此无法关闭游戏窗口。 -
您使用相同的变量
running
作为主循环的条件并更改播放器的xvel
。 -
也无需两次更新显示(只需使用
pygame.display.flip()
)。 -
您正在将一个巨大的 (3200x32px) Surface 每帧 1024 次传送到屏幕上。如果您想用黑色填充屏幕,只需每帧调用一次
screen.fill('black')
。