我最近在python 2.7.6中使用pygame制作了一个游戏,我现在正在将所有语法和代码转换为使用python 3.3.3。但我遇到了碰撞问题。在我转换之前,碰撞工作完美无缺,但在3.3.3中,所有的碰撞都完全搞砸了。这是我目前的玩家,僵尸和老板碰撞的代码:
def player_move(self):
# Line start
self.point = self.player.rect.x + 30, self.player.rect.y + 30
# add gravity
self.player.do_jump()
# simulate gravity
self.player.on_ground = False
if not self.player.on_ground and not self.player.jumping:
self.player.velY = 4
if self.player.rect.y >= 680:
self.player.lives -= 1
self.player.rect.x = 320
self.player.rect.y = 320
# Drops
for drop in self.gameDrops:
if pygame.sprite.collide_rect(self.player, drop):
if type(drop) == HealthDrop:
self.player.health += 50
self.gameDrops.remove(drop)
elif type(drop) == SuperHealthDrop:
self.player.health += 1000
self.gameDrops.remove(drop)
elif type(drop) == TriBullets:
self.player.power = POWER_TRIBULLETS
self.gameDrops.remove(drop)
elif type(drop) == ShieldDrop:
self.player.power = POWER_SHIELD
self.gameDrops.remove(drop)
if self.player.score >= self.next_level_score:
self.game_state = STATE_VICTORY
self.player.score = 0
self.zombieskilled = 0
self.alivetime = 0
self.lives = 3
self.health = 200
self.player.rect.x = 320
self.player.rect.y = 320
for zombie in self.zombies:
zombie.rect.x = random.randint(0, 1280)
zombie.rect.y = random.randint(0, 100)
# Health
for m in self.meteors:
if pygame.sprite.collide_rect(self.player, m):
if self.player.power == POWER_SHIELD:
self.player.health -= 25
else:
self.player.health -= 50
for zombie in self.zombies:
if pygame.sprite.collide_rect(self.player, zombie):
if self.player.power == POWER_SHIELD:
self.player.health -= 1
else:
self.player.health -= 5
for boss in self.bosses:
if pygame.sprite.collide_rect(self.player, boss):
if self.player.power == POWER_SHIELD:
self.player.health -= 50
else:
self.player.health -= 50
# check if we die
if self.player.health <= 0:
self.player.power = POWER_NONE
self.player.lives -= 1
self.player.rect.x = 320
self.player.rect.y = 320
self.player.health = 200
if self.player.lives <= 0:
self.player.lives += 3
self.player.score = 0
self.targetscore = 100
self.player.rect.x = 320
self.player.rect.y = 320
self.game_state = STATE_GAMEOVER
for zombie in self.zombies:
zombie.rect.x = random.randint(0, 1280)
zombie.rect.y = random.randint(0, 100)
# move player and check for collision at the same time
self.player.rect.x += self.player.velX
self.check_collision(self.player, self.player.velX, 0)
self.player.rect.y += self.player.velY
self.check_collision(self.player, 0, self.player.velY)
def zombie_move(self, zombie_sprite):
# add gravity
zombie_sprite.do_jump()
percentage = random.randint(0, 100)
# simualte gravity
zombie_sprite.on_ground = False
if not zombie_sprite.on_ground and not zombie_sprite.jumping:
zombie_sprite.velY = 8
if zombie_sprite.jumping:
zombie_sprite.velX = 0
for zombie in self.zombies:
if zombie.rect.y >= 680:
self.zombies.remove(zombie)
dx = zombie_sprite.rect.x - self.player.rect.x
if dx > 20 and not zombie_sprite.jumping:
zombie_sprite.velX = -5
elif dx < 20 and not zombie_sprite.jumping:
zombie_sprite.velX = +5
# Zombie damage
for zombie in self.zombies:
for m in self.meteors:
if pygame.sprite.collide_rect(m, zombie):
zombie.health -= 10
if zombie.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(zombie.rect.x + 10, zombie.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(zombie.rect.x + 20, zombie.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(zombie.rect.x + 30, zombie.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(zombie.rect.x + 40, zombie.rect.y + 30))
self.zombieskilled += 0
self.player.score += 0
self.meteors.remove(m)
break
for zombie in self.zombies:
for b in self.bullets:
if pygame.sprite.collide_rect(b, zombie):
#The same bullet cannot be used to kill
#multiple zombies and as the bullet was
#no longer in Bullet.List error was raised
zombie.health -= 10
self.bullets.remove(b)
if zombie.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(zombie.rect.x + 10, zombie.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(zombie.rect.x + 20, zombie.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(zombie.rect.x + 30, zombie.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(zombie.rect.x + 40, zombie.rect.y + 30))
self.zombieskilled += 1
self.player.score += 10
self.total_score += 10
self.zombies.remove(zombie)
break
# move zombie and check for collision
zombie_sprite.rect.x += zombie_sprite.velX
self.check_collision(zombie_sprite, zombie_sprite.velX, 0)
zombie_sprite.rect.y += zombie_sprite.velY
self.check_collision(zombie_sprite, 0, zombie_sprite.velY)
def boss_move(self, boss_sprite):
# add gravity
boss_sprite.do_jump()
percentage = random.randint(0, 100)
# simualte gravity
boss_sprite.on_ground = False
if not boss_sprite.on_ground and not boss_sprite.jumping:
boss_sprite.velY = 8
if boss_sprite.jumping:
boss_sprite.velX = 0
for boss in self.bosses:
if boss.rect.y >= 620:
self.bosses.remove(boss)
dx = boss_sprite.rect.x - self.player.rect.x
if dx > 20 and not boss_sprite.jumping:
boss_sprite.velX = -5
elif dx < 20 and not boss_sprite.jumping:
boss_sprite.velX = +5
# Zombie damage
for boss in self.bosses:
for m in self.meteors:
if pygame.sprite.collide_rect(m, boss):
boss.health -= 0
if boss.health <= 0:
if (percentage >= 0) and (percentage < 40):
self.gameDrops.append(HealthDrop(boss.rect.x + 10, boss.rect.y + 30))
elif (percentage >= 0) and (percentage < 5):
self.gameDrops.append(SuperHealthDrop(boss.rect.x + 20, boss.rect.y + 30))
elif (percentage >= 1) and (percentage < 20):
self.gameDrops.append(TriBullets(boss.rect.x + 30, boss.rect.y + 30, self.player.direction))
elif (percentage >= 1) and (percentage < 50):
self.gameDrops.append(ShieldDrop(boss.rect.x + 40, boss.rect.y + 30))
self.zombieskilled += 0
self.player.score += 0
self.meteors.remove(m)
break
for boss in self.bosses:
for b in self.bullets:
if pygame.sprite.collide_rect(b, boss):
#The same bullet cannot be used to kill
#multiple bosses and as the bullet was
#no longer in Bullet.List error was raised
boss.health -= 5
self.bullets.remove(b)
if boss.health <= 0:
if (percentage >= 0) and (percentage < 50):
self.gameDrops.append(SuperHealthDrop(boss.rect.x + 90, boss.rect.y + 90))
elif (percentage >= 0) and (percentage < 50):
self.gameDrops.append(TriBullets(boss.rect.x + 90, boss.rect.y + 90, self.player.direction))
self.zombieskilled += 1
self.player.score += 50
self.total_score += 50
self.bosses.remove(boss)
break
# move boss and check for collision
boss_sprite.rect.x += boss_sprite.velX
self.check_collision(boss_sprite, boss_sprite.velX, 0)
boss_sprite.rect.y += boss_sprite.velY
self.check_collision(boss_sprite, 0, boss_sprite.velY)
def check_collision(self, sprite, x_vel, y_vel):
# for every tile in Background.levelStructure, check for collision
for block in self.moon.get_surrounding_blocks(sprite):
if block is not None:
if pygame.sprite.collide_rect(sprite, block):
# we've collided! now we must move the collided sprite a step back
if x_vel < 0:
sprite.rect.x = block.rect.x + block.rect.w
if type(sprite) is Zombie:
# the sprite is a zombie, let's make it jump
if not sprite.jumping:
sprite.jumping = True
sprite.on_ground = False
else:
sprite.jumping = False
sprite.on_ground = True
if x_vel > 0:
sprite.rect.x = block.rect.x - sprite.rect.w
if type(sprite) is Zombie:
# the sprite is a zombie, let's make it jump
if not sprite.jumping:
sprite.jumping = True
sprite.on_ground = False
else:
sprite.jumping = False
sprite.on_ground = True
if y_vel < 0:
sprite.rect.y = block.rect.y + block.rect.h
if y_vel > 0 and not sprite.on_ground:
sprite.on_ground = True
sprite.rect.y = block.rect.y - sprite.rect.h
这是来自玩家,僵尸和老板的所有代码,因为他们碰撞并且有功能,所以他们知道要碰撞。我已经调用了碰撞功能,你可以在所有三个代码中看到。我真的很生气,因为我不确定它是用语法还是用什么做的。任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
我终于找到了修复!在我的leveltructure文件中随机生成地形和位置。在我的一代课程中,我有一个get_surrounding_blocks,你可以在def check_collision中看到。在那个aroundblocks我有:
def get_surrounding_blocks(self, sprite):
# calculate the grid position of the sprite
sprite_x = sprite.rect.x / 64
sprite_y = sprite.rect.y / 64
在python 2.7.6中,一个除法符号(/)会给你一个整数但是在python 3.3.3中你必须//得到一个整数,否则你可能得到一个只有一个/的浮点数。