Pygame 2,7碰撞到3,3

时间:2014-02-04 17:11:14

标签: python-2.7 python-3.x pygame

我最近在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

这是来自玩家,僵尸和老板的所有代码,因为他们碰撞并且有功能,所以他们知道要碰撞。我已经调用了碰撞功能,你可以在所有三个代码中看到。我真的很生气,因为我不确定它是用语法还是用什么做的。任何帮助将不胜感激。谢谢。

1 个答案:

答案 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中你必须//得到一个整数,否则你可能得到一个只有一个/的浮点数。