敌人的船只健康 - 使用Pygame

时间:2015-12-16 20:20:07

标签: python pygame

我在这里向刚刚开始使用Python的儿子提问。 他正在制作一个简单的游戏,敌舰投掷导弹,玩家移动盾牌阻挡坠落的导弹撞击地球。他增加了盾牌在船上发射子弹以摧毁它的能力(目前设定为3次点击)这一切似乎都有效但游戏在此时崩溃并给出了错误:typeerror:Die( )取1个位置参数(给定0)。 他很不清楚为什么我没有太多使用传递了一些HTML :)

这是他的代码:

#Space Defence
#Wes L-M

#Players must defend the city from alien missiles and attack the mother ship 

from livewires import games, color
import random
import pygame

games.init(screen_width = 1280, screen_height = 1024, fps = 50)
pygame.display.set_mode((1280,1024),pygame.FULLSCREEN)


class Killer(games.Sprite):
    """ Makes a simple die methord for all the class's. """

    def die(self):
        """ Destroy self. """
        self.destroy()


class Collider(Killer):
    """ A class that detects collisions. """
    def update(self):
        """ Check for overlapping sprites. """
        super(Collider, self).update()

        if self.overlapping_sprites:
            for sprite in self.overlapping_sprites:
                sprite.die()
            self.die()

    def die(self):
        """ Destroy self and leave explosion behind. """
        new_explosion = Explosion(x = self.x, y = self.y)
        games.screen.add(new_explosion)
        self.destroy()


class Collider_B(Killer):
    """ A class that detects collisions for Bullet and Ship. """

    def update(self):
        """ Check for overlapping sprites and take way from health. """
        super(Collider_B, self).update()

        if self.overlapping_sprites:
            for sprite in self.overlapping_sprites:
                sprite.die()
            self.die()

    def die(self):
        """ destroy self and leave differant explostion behind. """
        new_explosion = Explosion(x = self.x, y = self.y)
        games.screen.add(new_explosion)
        self.destroy()


class  Explosion(games.Animation):
    """ Explosion animation. """
    images = ["explosion_1.bmp",
              "explosion_2.bmp",
              "explosion_3.bmp",
              "explosion_4.bmp",
              "explosion_5.bmp",
              "explosion_6.bmp",
              "explosion_7.bmp",
              "explosion_8.bmp",
              "explosion_9.bmp"]

    def __init__(self, x, y):
        super(Explosion, self).__init__(images = Explosion.images,
                                        x = x, y = y,
                                        repeat_interval = 6, n_repeats = 1,
                                        is_collideable = False)


class Shield(Killer):
    """
    A Shield controlled by player to catch falling missiles.
    """
    image = games.load_image("shield.bmp")
    BULLET_DELAY = 20

    def __init__(self, y = 800):
        """ Initialize Shield object and create Text object for score. """
        super(Shield, self).__init__(image = Shield.image,
                                  x = games.screen.width/2,
                                  y = y)
        self.bullet_wait = 0

        self.score = games.Text(value = 0, size = 25, color = color.black,
                                top = 5, right = games.screen.width - 10,
                                is_collideable = False)
        games.screen.add(self.score)

    def update(self):
        """ Use A and D to controll, SPACE too fire. """
        if games.keyboard.is_pressed(games.K_o):
            self.x -= 12
        if games.keyboard.is_pressed(games.K_p):
            self.x += 12

        if self.left < 0:
            self. left = 0

        if self.right > games.screen.width:
            self.right = games.screen.width

        self.Check_catch()

        #fire bullets if spacebar is pressed
        if games.keyboard.is_pressed(games.K_SPACE) and self.bullet_wait == 0:
            new_bullet = Bullet(self.x, self.y)
            games.screen.add(new_bullet)
            self.bullet_wait = Shield.BULLET_DELAY

        #if waiting until the shield can fire next, decrease wait
        if self.bullet_wait > 0:
            self.bullet_wait -= 1

    def Check_catch(self):
        """ Check if catch missiles. """
        for missile in self.overlapping_sprites:
            self.score.value += 10
            self.score.right = games.screen.width - 10
            missile.handle_caught()


class Ship(Killer):
    """
    A ship which moves left and right, dropping shield.
    """
    image = games.load_image("ship.bmp")
    health = 3

    def __init__(self, y = 55, speed = 3, odds_change = 200):
        """ Initialize the Chef object. """
        super(Ship, self).__init__(image = Ship.image,
                                   x = games.screen.width / 2,
                                   y = y,
                                   dx = speed)

        self.odds_change = odds_change
        self.time_til_drop = 0

    def update(self):
        """ Determine if direction needs to be reversed. """
        if self.left < 0 or self.right > games.screen.width:
            self.dx = -self.dx
        elif random.randrange(self.odds_change) == 0:
            self.dx = -self.dx

        self.check_drop()
        self.check_hit()


    def check_drop(self):
        """ Decrease countdown or drop missile reset countdown. """
        if self.time_til_drop > 0:
            self.time_til_drop -= 1
        else:
            new_missile = Missile(x = self.x)
            games.screen.add(new_missile)

            #set buffer to approx 30% of missile height, regardless of missile speed
            self.time_til_drop = int(new_missile.height * 1.3 / Missile.speed) + 1

    def check_hit(self):
        """ Check if Bullet has hit. """
        for Bullet in self.overlapping_sprites:
            Bullet.handle_hit()


class Bullet(Collider_B):
    """ A Bullet fired by the player's shield. """
    image = games.load_image("bullet.bmp")
    BUFFER = -30
    LIFETIME = 100

    def __init__(self, shield_x, shield_y):
        """ Initialize bullet sprite. """

        #bullet starting position
        buffer_y = Bullet.BUFFER
        x = shield_x 
        y = shield_y + buffer_y

        #bullet speed
        dx = random.choice([1, 0.5, 0.3, 0.1, 0, -0.1, -0.3, -0.5, -1])
        dy = -10

        #create the bullet
        super(Bullet, self).__init__(image = Bullet.image,
                                     x = x, y = y,
                                     dx = dx, dy = dy)
        self.lifetime = Bullet.LIFETIME

    def update(self):
        """ Move the bullet. """

        #if lifetime is up, destroy missile
        self.lifetime -= 1
        if self.lifetime == 0:
            self.destroy()

    def handle_hit(self):
        """ Handles what happens when hit by Bullet. """
        Ship.health -= 1
        if Ship.health == 0:    #ship loses health and eventually dies
            Ship.die()

        self.die()


class Missile(Collider):
    """
    A missile which falls to the ground.
    """
    image = games.load_image("missile.bmp")
    speed = 1

    def __init__(self, x, y = 90):
        """ Initialize a Missile object. """
        super(Missile, self).__init__(image = Missile.image,
                                    x = x, y = y,  
                                    dy = random.randint(1, 4))  
    def update(self):
        """ Check if bottom edge has reached screen bottom. """
        if self.bottom > games.screen.height:
            self.end_game()
            self.die()

    def handle_caught(self):
        """ Destroy self if caught. """
        self.die()

    def handle_hit(self):
        """ Handle if missile gets hit... nothing. """

    def end_game(self):
        """ End the games. """
        end_message = games.Message(value = "Game Over",
                                    size = 90,
                                    color = color.red,
                                    x = games.screen.width/2,
                                    y = games.screen.height/2,
                                    lifetime = 5 * games.screen.fps,
                                    after_death = games.screen.quit)
        games.screen.add(end_message)


def main():
    """ Play the game. """
    city_image = games.load_image("Citybackground.jpg", transparent = False)
    games.screen.background = city_image

    #load and play theme music
    games.music.load("Star-Command.mp3")
    games.music.play(-1)

    the_ship = Ship()
    games.screen.add(the_ship)

    the_shield = Shield()
    games.screen.add(the_shield)

    games.mouse.is_visible = False

    games.screen.event_grab = True
    games.screen.mainloop()

#start it up!!!!
main()

2 个答案:

答案 0 :(得分:1)

我明白了。这里:

def handle_hit(self):
        """ Handles what happens when hit by Bullet. """
        Ship.health -= 1
        if Ship.health == 0:    #ship loses health and eventually dies
            Ship.die()

        self.die()

在这里,您尝试在类上调用实例方法。 (有点像试图在房子的蓝图上修理管道)Ship资本是指船的蓝图,python只是告诉你它不知道要杀哪艘船(即使有只有一艘船。)

尝试将其替换为:

def handle_hit(self):
        """ Handles what happens when hit by Bullet. """
        the_ship.health -= 1
        if the_ship.health == 0:    #ship loses health and eventually dies
            the_ship.die()

        self.die()

同样在main()添加:

global the_ship

位于函数顶部

答案 1 :(得分:-1)

这段代码根本就错了。除了模块&#34;颜色&#34;在livewires中不存在(它&#34; color&#34;)。根据代码OP尝试使用宽度,高度和fps初始化游戏库。快速搜索源代码表明正确的调用将是:

    screen = games.Screen(width=1280, height=1024)

这意味着main函数中的代码是错误的,因为它一直在调用不存在的函数。此外,由于在github上的第二次快速搜索显示,在livewires库中没有参考音乐&#34;出现。但是,pygame模块包含一个音乐播放器,但不会像OP暗示的那样远程调用。我不知道OP是如何运行此代码的。

如果由于一些奇怪的原因代码运行OP:

def handle_hit(self):
    """ Handles what happens when hit by Bullet. """
    Ship.health -= 1
    if Ship.health == 0:    #ship loses health and eventually dies
        Ship.die()

    self.die()

也是错误的,因为在这段代码中他引用了Ship类而不是他创建的实例。在这种情况下,我可以给出OP的最佳解决方案是将handle_hit()方法中Ship的所有出现发生在&#34; the_ship&#34;实例变量