面向对象的飞机大战编程

2019-02-01  本文已影响0人  超人不会飞_9664

游戏框架分为两部分

1.创建一个plane_main.py的主文件,写出一个PlaneGame的主类。

import pygame
class PlaneGmae(object):
    def __init__(self):
        print('游戏初始化...')
    def start_game(self):
        print('游戏开始...')
if __name__ == '__main__':
    # 创建游戏对象
    game = PlaneGmae()
    # 启动游戏
    game.start_game()

运行结果为

D:\python\python36\python.exe D:/PycharmProjects/feijidazhan_1/feiji.py
游戏初始化...
游戏开始...

2.另新建一个plane_sprite.py 的模块

import pygame
class Game_Sprite(pygame.sprite.Sprite):#派生精灵子类
    '''飞机大战游戏精灵'''
    def __init__(self,image_name,speed = 1):
        # 继承父类的__init__()
        super().__init__()
        # 定义对象的属性
        self.image =pygame.image.load(image_name)
        self.rect = self.image.get_rect()
        '''self.image的get_rect()返回pygame.Rect(0,0,width,height)'''
        self.speed = speed
        def update(self):
           self.rect.y += self.speed

3. 主程序中设置游戏初始化的步骤

class PlaneGmae(object):
    def __init__(self):
        print('游戏初始化...')
        # 1.创建游戏屏幕
        self.screen = pygame.display.set_mode(SCREEN_RECT.size) #引入的常量
        # 2.创建游戏时钟
        self.clock = pygame.time.Clock()
        # 3.私有方法创建精灵和精灵组
        self.__creat_sprite()
    def __creat_sprite(self):
        pass

4主程序中游戏的开始部分的步骤

class PlaneGmae(object):
    游戏初始化部分...
    .......
    def start_game(self):
        print('游戏开始...')
        while True:
            # 1.设置帧率
            self.clock.tick(60)
            # 2. 事件监听
            self.__event_monitor()
            # 3. 碰撞检测
            self.__check_collide()
            # 4. 绘制图像
            self.__blit_photo()
            # 5.刷新显示
            pygame.display.update()

5.为了让程序可读性高,便于维护,建议是使用私有方法,由于上面的四个步骤都是私有方法,所以接下来在上面的主要类开始布置私有方法

    def __event_monitor(self):
        pass
    def __check_collide(self):
        pass
    def __blit_photo(self):
        pass
    @staticmethod
    def __game_over():
        print('退出游戏')
        # 卸载所有模块
        pygame.quit()
        # 退出程序
        exit()
image.png

6.接下来我们开始布置背景图(这里用到一个小套路,让背景图在垂直方向上移动,这样就可以让英雄飞机相对运动了)

1.在模块文档那里开始写背景类

class Background(Game_Sprite):
    def __init__(self,is_alt = False):
        super().__init__('./images/background.png')
        if is_alt:
            self.rect.bottom = 0
    def  update(self):
        # 让屏幕往下移动,所以可以用到父类的方法。所以可以继承
        super().update()
        # 判断底部照片是否超出屏幕
        if self.rect.y > SCREEN_RECT.height:
            self.rect.y =-SCREEN_RECT.height

2.回到主程序中的初始化部分那里,开始填写__creat_sprite()私有方法

 def __creat_sprite(self):
        # 创造背景精灵和精灵组
        bg1 = Background()
        bg2 = Background(True)
        self.bg_group = pygame.sprite.Group(bg1,bg2)

3.回到主程序中游戏开始部分那里,self.__blit_photo() 图像绘制更新那里

    def __blit_photo(self):
        # 背景图片的绘制
        self.bg_group.update()
        self.bg_group.draw(self.screen)

shift+f10 运行的效果是一向下移动的背景图

7.为了方便后面测试程序,我们在这里就开始写事件监听的代码,一旦检测到退出的信号就直接退出

    def __event_monitor(self):
        for event in pygame.event.get():
            # 判断监听是否有退出动作
            if event.type == pygame.QUIT:
                PlaneGmae. __game_over()

8.敌机的类的填写以及精灵类和精灵组的填写(由于敌机较多,要用到定时器)

class Enemy(Game_Sprite):
    def __init__(self):
        super().__init__('./images/enemy1')
        # 敌机初始化位置
        # 1.x轴上的随机位置
        Max_x = SCREEN_RECT.width-self.rect.width
        self.rect.x = random.randint(0,Max_x)
        # 2.y轴上的随机位置
        self.rect.bottom = 0
        # 初始速度的设置
        self.speed = random.randint(1,3)
    def update(self):
        # 继承父类的update让敌机向下移动
        super().update()
        # 判断敌机是否超出屏幕
        if self.rect.y > SCREEN_RECT.height:
            self.kill()
    def __del__(self):
        print('敌机挂了%s' % self.rect)

1.敌机定时器的三步骤:
a.在模块文件中写出定时器常量 eg:XXX = pygame.USEREVENT
b.在主程序的初始化中

pygame.time.set_timer(CREAT_TIMER,1000)

其中1000指的1000毫秒也就是1秒执行一个定时器的动作
c.在事件监听里

            elif event.type == CREAT_TIMER:
                print('产生敌机...')

那样就可以1秒一个敌机出现
2.开始在初始化位置创建精灵组

# 创建敌机精灵组
       self.enemy_group = pygame.sprite.Group()

3.在事件监听那里去写精灵组,因为这是持续不断的要精灵组的

 elif event.type == CREAT_TIMER:
                print('产生敌机...')
                # 敌机精灵
                enemy = Enemy()

                # 敌机精灵组
                self.enemy_group.add(enemy)

4.将敌机精灵组进行绘制

 # 敌机的绘制
        self.enemy_group.update()
        self.enemy_group.draw(self.screen)

9.开始英雄的类已经精灵的布置

class Hero(Game_Sprite):
    # 继承父类,设置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 确定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120
# 创建英雄精灵和精灵组
       self. hero_sprite = Hero()  #此对象要在其他方法被调用所以加self
        self.hero_sprite_group = pygame.sprite.Group(hero_sprite)
 # 英雄的绘制
        self.hero_sprite_group.update()
        self.hero_sprite_group.draw(self.screen)

10.开始让飞机在左右移动但是不能超出左右边界

# 使用键盘方法获取按键元组
        keys_pressed = pygame.key.get_pressed()
        # 判断元组中对应按键索引值
        if keys_pressed[pygame.K_RIGHT]:
            self.hero_sprite.speed = 2
        elif keys_pressed[pygame.K_LEFT]:
            self.hero_sprite.speed = -2
        else:
            self.hero_sprite.speed = 0
class Hero(Game_Sprite):
    # 继承父类,设置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 确定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120
    def update(self):
        # 因为是左右移动,所以可以完全改写父类方法
        self.rect.x += self.speed

        # 判断英雄飞机是否飞出屏幕外
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.x > SCREEN_RECT.width-self.rect.width:
            self.rect.right = SCREEN_RECT.right

11.开始设置子弹

class Bullet(Game_Sprite):
    def __init__(self):
        # 继承父类,加载图片
        super().__init__('./images/bullet1.png',-2)
        # 初始位置先不要管,等到英雄类里再去弄
    def update(self):
        # 继承父类方法,让子弹移动
        super().update()

        # 判断子弹是否超出屏幕
        if self.rect.bottom < 0:
            self.kill()
    def __del__(self):
        print('超出子弹被销毁%s'%self.rect)

注意下,这里不要设置子弹的初始位置,因为子弹的初始位置是要和英雄一起弄得

# 子弹常量
HERO_FIRE = pygame.USEREVENT+1
 # 5. 发射子弹的定时器调用
        pygame.time.set_timer(HERO_FIRE,500)
 elif event.type ==  HERO_FIRE:
                self.hero_sprite.fire()

考虑到子弹是要和英雄一起弄的,我们把创建子弹精灵和精灵组放到英雄类中去

class Hero(Game_Sprite):
    # 继承父类,设置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 确定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120

        # 创建子弹精灵组
        self.bullets = pygame.sprite.Group()
            elif event.type ==  HERO_FIRE:
                self.hero_sprite.fire()
def fire(self):
      print('发射子弹...')
      for i in range(3):
          # 创建子弹精灵
          bullet = Bullet()
          # 设置子弹的初始位置
          bullet.rect.bottom = self.rect.y- i*20
          bullet.rect.centerx = self.rect.centerx
          # 设置子弹的精灵组
          self.bullets.add(bullet)
 # 子弹的绘制
        self.hero_sprite.bullets.update()
        self.hero_sprite.bullets.draw(self.screen)

呈现的效果为


image.png

12.开始碰撞检测

 def __check_collide(self):
        # 子弹碰到飞机
        pygame.sprite.groupcollide(self.hero_sprite.bullets,self.enemy_group,True,True)
        # 敌机撞毁飞机
        enemies = pygame.sprite.spritecollide(self.hero_sprite, self.enemy_group, True)
        # 判断列表是否有内容
        if len(enemies) > 0:
            # 让英雄牺牲
            self.hero_sprite.kill()

            # 结束游戏
            PlaneGmae.__game_over()

shift +f10


image.png

碰撞的基础知识

image.png image.png
上一篇下一篇

猜你喜欢

热点阅读