Я недавно сделал игру в 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 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 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
Это все код игрока, зомби и босса для них, с которыми вы сталкиваетесь, и там функционирует так, чтобы они знали, что они сталкиваются. Я также вызвал функцию столкновения, как вы можете видеть в коде для всех трех. Меня это очень раздражает, потому что я не уверен, связано ли это с синтаксисом или чем-то. Любая помощь будет оценена. Спасибо.
Наконец-то я нашел исправление! В файле levelstructure для случайного создания рельефа и положения. В моем классе поколения у меня были get_surrounding_blocks, как вы можете видеть в def check_collision. В этих окружающих блоках у меня было:
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 вы должны сделать //, чтобы получить целое число, иначе вы можете получить float с одним или.