python 飞机大战等游戏类编程思路

一.  类与对象的概念 

一个游戏里面的组成元素其实都是一个个的对象,而对象又是在类中的一个实例

比如你是一个人,而你所属的类别叫做人类,你是人类中的一个实例。类中可以定义属性和方法,而对象是具有这些属性和方法的。方法可以就理解为函数。

比如人类有身高体重等属性,有走路和奔跑等方法。属性是静态特征,方法是动态行为

那么由此我们可以类比到游戏里面,我们可以定义一个飞机类。

飞机要呈现出来要有属性图像吧,你的飞机要移动得有属性速度吧,如果给飞机一个生命值,那是不是得有一个属性血量值,这是最基本得属性,还有别的属性我们后面讲。

上面的属性有感觉了吧,是不是就是用来描述飞机得静态特征的。

飞机要动起来是不是得有一个移动方法,比如键盘上得↑↓←→来控制飞机的移动;飞机要发射子弹是不是得有一个发射子弹的方法;上面我们给出了飞机的图像属性,那么飞机如何搬到游戏界面上 是不是得再来一个方法,把飞机得那张图像搬到游戏界面上。

方法是不是用来描述飞机的动态行为的

咱们对属性和方法有了初步的了解,现在我们对类再来深入了解一下。

我们是人类,但同时我们是不是也是动物,我们不是植物所以我们没有植物的那一套东西。但是我们是动物,动物会呼吸吧,动物会移动吧。所以我们人类会呼吸会移动。同时,鸟类是不是也是动物,他们也会呼吸会移动。所以人类是动物,鸟类也是动物。动物也是一个类,人类是动物的子类,动物称作父类,动物所具备的,我们人类也具备,鸟类也具备。所以子类可以继承父类。

动物会进食,人类和鸟类也会进食,但是人类和鸟类进食的方式是不一样的,人类进食需要先将食物搞熟,将食物搞美味,并且在用餐的时候会使用工具,而鸟类直接通过喙进食。进食是动物的方法,也是人类和鸟类的方法,但动物的进食方法很抽象,人类和鸟类的进食方法很具体,所以在写子类的时候可以将父类抽象的方法写得更具体。

所以子类在继承父类的时候可以将父类的方法覆盖重写。这被称为继承的多态性。

二. 模块与包 -- 我们站在巨人的肩膀上

我们在了解上面的内容之后,我在想一个问题,既然子类可以继承父类,那么我的飞机类是不是也可以继承它的父类,那样的话,我不就可以在他的父类上面修修补补不就行了。

对的,由于类的继承性,我们可以站在巨人的肩膀上,父类让别人给我写好,我直接继承,拿来吧你。

所以面向对象语言生态圈里就有这么一群人,他们专门写一些父类与模块,然后供别人使用。

pygame模块里就有一个精灵类,游戏里面的飞机类,子弹类,都可以继承这个精灵类。最下面有介绍精灵类里面的一些方法。

面向对象语言中,多个类和多个对象的关系是一个树形图的关系,大类就是树干,子类就是枝干,对象就是叶子。比如pygame.sprite.Sprite就是pygame.sprite的子类

python 飞机大战等游戏类编程思路_第1张图片

 pygame里面的各种类和方法,就是给出了树干,剩下的叶子根据我们的需求自己去完善

三. 思路大纲

我方飞机类  Class MyPlane(pygame.sprite.Sprite):

敌方飞机类  Class EnemyPlane(pygame.sprite.Sprite):

我方子弹类  Class MyBullet(pygame.sprite.Sprite):

敌方子弹类  Class EnemyBullet(pygame.sprite.Sprite):

游戏声音类  Class GameSound:

爆炸类         Class Bomb:

游戏背景类  Class GameBackgroud:

游戏管理类  Class Manager:

-------------------------------------------------------------------------

"由于我方飞机与敌方飞机共用的属性和方法非常少(本例中 他们的图片 速度 矩形区域等等属性都不一样)所以直接定义两个类(如果他们共用的属性和方法很多的话,我们可以定义一个他们的父类Plane)。"

细讲类里面的方法与属性(实例属性定义在初始化方法中,类属性的值在所有实例之间共享):

Class MyPlane(pygame.sprite.Sprite):

初始化方法       def __init__(self,screen):  # 初始化就相当于一个具体对象的出生,定义各项属性

键盘控制方法   def key_control(self):         # 飞机要移动需定义键盘控制方法

显示方法          def display(self):                # 显示飞机图像,显示子弹图像,

更新方法          def update(self):                 # 更新飞机按键状态和显示状态

清除子弹方法  @classmethod

                        def clear_bullets(cls):          # 类方法,清除子弹,避免子弹对象占用过多系统资源

Class EnemyPlane(pygame.sprite.Sprite):

有和上面类似的初始化方法,显示方法,更新方法。

自动移动方法  def auto_move(self):           # 敌方飞机自动移动

自动开火方法  def auto_fire(self):               # 敌方飞机自动开火

清除子弹方法  

Class MyBullet(pygame.sprite.Sprite):

初始化方法

更新方法

 Class EnemyBullet(pygame.sprite.Sprite):

初始化方法

更新方法

Class GameSound:

初始化方法                   #加载下面的两种音乐

背景音乐方法            

爆炸音效方法

Class Bomb:

初始化方法

爆炸触发方法   def action(self,rect):        # 爆炸的位置与是否爆炸的开关

爆炸绘画方法   def draw(self):                 # 爆炸的动画绘制

# 爆炸与背景移动本质上是类似的  两张图片的切换形成爆炸图像效果  都有触发方法和绘制 只不过一个需要触发条件  一个是一直触发  

Class GameBackgroud:

初始化方法

背景移动方法   def move(self):

背景绘制方法   def draw(self):

Class Manager:

类属性定义(给其他方法共享)

初始化方法

游戏退出方法                      def exit(self):

显示游戏结束文字方法       def show_over_text(self):

游戏结束倒计时方法           def game_over_timer(self):

游戏重新开始方法              def start_game(self):

更新玩家飞机方法              def new_player(self):

更新敌方飞机方法              def new_enemy(self):

显示文本方法                     def drawText(self,text,x,y, textHeight=30,

                                                fontColor=(255,0,0), backgroundColor=None):

主方法                                def main(self):

四. 代码实现细节

我方飞机类

class HeroPlane(pygame.sprite.Sprite):
    # group to store all aircraft bullets
    bullets = pygame.sprite.Group()

将子弹添加到pygame.sprite.Group()中,方便对子弹对象进行批量处理和管理

    def __init__(self, screen):
        # The initialization method of this sprite must be called:
        pygame.sprite.Sprite.__init__(self)

        # Create a picture as a player's plane
        self.player = pygame.image.load("./photo/hero1.png")
        # getting a rectangle object based on the image
        self.rect = self.player.get_rect()
        self.rect.topleft = [Manager.bg_size[0]/ 2 - 134 / 2 , 580]
        # aircraft speed
        self.speed = 4
        self.screen = screen
        # list of loaded bullets
        self.bullets = pygame.sprite.Group()

初始化,将我方飞机像生小孩一样生下来。然后给飞机加载图像,“ . ”表示当前目录,“ .. ”表示上级目录。"./photo/hero1.png"表示在当前python脚本目录下的'photo'目录中查找'hero1.png'文件。

先定义一下 self.player ,加载玩家飞机图像 然后再self.rect=self.player.get_rect 相当于self.rect=pygame.image.load("./photo/hero1.png").get_rect  

topleft是get_rect里面的,代表着图像坐上角的坐标,x定为背景图片的x/2-飞机x/2  y定为靠下方就行了(根据你背景图片的像素)  飞机速度自己定  self.screen = screen 以便后续飞机的display方法使用,将飞机显示到窗口上。

self.bullets = pygame.sprite.Group()将飞机子弹放入精灵组方便后续统一处理和管理
    def key_control(self):
        # Listen for keyboard events
        key_pressed = pygame.key.get_pressed()

        if key_pressed[K_w] or key_pressed[K_UP]:
            self.rect.top -= self.speed
        if key_pressed[K_s] or key_pressed[K_DOWN]:
            self.rect.bottom += self.speed
        if key_pressed[K_a] or key_pressed[K_LEFT]:
            self.rect.left -= self.speed
        if key_pressed[K_d] or key_pressed[K_RIGHT]:
            self.rect.right += self.speed
        if key_pressed[K_SPACE]:
            # Create a new bullet
            bullet = Bullet(self.screen, self.rect.left, self.rect.top)
            self.bullets.add(bullet)
            HeroPlane.bullets.add(bullet)

因为窗口坐标左上角为原点,所以飞机往上就是y值(top)减小,往左就是x值(left)减小

我们把飞机的左上角的坐标参数传给我方子弹类,

self.bullets.add(bullet)是将子弹添加到此飞机的列表里方便后续管理

HeroPlane.bullets.add(bullet)是将子弹添加到我方的所有飞机的列表里,如果我方只有一个飞机,此行代码可不要

    def display(self):
        # 3.Paste the player picture into the window
        self.screen.blit(self.player, self.rect)
        # updating the coordinates of the bullet
        self.bullets.update()
        # adding all bullets to the screen
        self.bullets.draw(self.screen)

    def update(self):
        self.key_control()
        self.display()

    @classmethod
    def clear_bullets(cls):
        # clearing bullets
        cls.bullets.empty()

blit是block t

你可能感兴趣的:(python,pygame,开发语言)