问题描述
我试图做到这一点,当敌人与玩家发生碰撞时,会失去一条生命并且玩家位于屏幕中央。它大约有一半的时间有效,但另一半时间则是因为一次碰撞而失去两三个生命。
def collide(self):
for enemy in enemies:
if ((robot.hitBox[0] < enemy.x + 16 < robot.hitBox[0] + robot.hitBox[2]) or (robot.hitBox[0] < enemy.x - 16 < robot.hitBox[0] + robot.hitBox[2])) and ((robot.hitBox[1] < enemy.y + 16 < robot.hitBox[1] + robot.hitBox[3]) or (robot.hitBox[1] < enemy.y - 16 < robot.hitBox[1] + robot.hitBox[3])):
robot.alive = False
robot.x = 400
robot.y = 300
for enemy in enemies:
enemies.remove(enemy)
robot.lives -= 1
robot.alive = True
这是Enemy类下的一个函数,在Enemy的draw函数内部调用,在while循环中调用。
while running:
## add if robot.alive == True into loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
userInput = pygame.key.get_pressed()
if len(enemies) <= 3:
randSpawnX = random.randint(32,768)
randSpawnY = random.randint(77,568)
if (robot.x - 100 <= randSpawnX <= robot.x + 100) or (robot.y - 100 <= randSpawnY <= robot.y + 100):
randSpawnX = random.randint(32,768)
randSpawnY = random.randint(77,568)
else:
enemy = Enemy(randSpawnX,randSpawnY)
enemies.append(enemy)
if robot.alive == True:
for enemy in enemies:
enemy.move()
robot.shoot()
robot.movePlayer(userInput)
drawGame()
谁能帮我弄清楚为什么会这样?我相信这是因为记录了多次碰撞,但是由于我在记录第一次命中并且在失去生命之前将机器人移动到屏幕中间,为什么会发生这种情况?
解决方法
读取 How do I detect collision in pygame? 并使用 pygame.Rect
/ colliderect()
进行碰撞检测。
读取 How to remove items from a list while iterating? 并遍历列表的副本。
如果遇到碰撞,仅仅改变玩家的 x
和 y
属性是不够的。您还需要更改 hitbox
。另外break
检测到碰撞时的循环:
def collide(self):
robot_rect = pygame.Rect(*robot.hitbox)
for enemy in enemies[:]:
enemy_rect = pygame.Rect(enemy.x,enemy.y,16,16)
if robot_rect.colliderrect(enemy_rect):
enemies.remove(enemy)
robot.x,robot.y = 400,300
robot.hitbox[0] = robot.x
robot.hitbox[1] = robot.y
robot.lives -= 1
break