Python学习笔记5---飞机大战小游戏

一、游戏效果展示

          图片贴的很随意 不要在意这些细节。         O(∩_∩)O

二、功能简介、分析

游戏中我发飞机在下方,由玩家键盘控制左右移动和发射子弹。上方为敌方飞机,随机发射子弹和移动。暂时没有写飞机被击中的逻辑,这里只是为了课程总结,体验一下面向过程的编程方式。

分析,实现效果可分为一下几步操作

  1. 搭建界面、创建界面标题
  2. 添加背景音乐
  3. 玩家飞机的键盘控制检测
  4. 玩家飞机的显示、移动、发射子弹、子弹显示、子弹超出显示范围后删除
  5. 敌方飞机的显示、移动、发射子弹、子弹显示、子弹超出显示范围后删除
  6. 玩家子弹 和 敌方子弹的贴图、发射方式不同(玩家子弹由键盘控制发射、敌方子弹随机发射)

从上面的分析可看出,玩家 和 敌方的飞机和子弹都有共同之处,这些共同之处可有一个统一的基类实现,子类实现不同之处,子类继承父类。

三、程序源代码

废话不多说,上代码


import pygame    #导入第三方模块
import random    #加载随机数
import time      #加载时间函数
pygame.init()    #初始化pygame ,否则会报错[pygame.error: video system not initialized]
#抽象一个飞机的基类
class BasePlan():
    def __init__(self, screen,ImageName,x,y):  # Screen是要显示在哪个窗口
        # 设置要显示内容的窗口
        self.screen = screen
        # 生成飞机图片
        self.image = pygame.image.load(ImageName)
        # 存放子弹的列表
        self.BulletList = []
        # 默认位置
        self.x = x
        self.y = y

        pass
    def DisPlay(self):
        self.screen.blit(self.image, (self.x, self.y))  # 显示飞机主体
        #完善子弹的展示逻辑
        NeedDelTtemlist=[]                      #创建要删除的子弹列表
        for item in  self.BulletList:           #遍历子弹列表
            if item.Bullet_Judge():             #判断子弹是否要删除
                NeedDelTtemlist.append(item)    #要删除的子弹对象追加到要删除的列表中
                pass
            item.Bullet_Display()               #显示子弹位置
            item.Bullet_Move()                  #子弹移动
            pass
            for i in NeedDelTtemlist:               #遍历要删除的子弹列表
                self.BulletList.remove(i)           #删除子弹对象
                pass
            # for iB in self.BulletList:              #遍历子弹列表
            #     iB.Bullet_Display()                 #显示子弹位置
            #     iB.Bullet_Move()                    #子弹移动
            pass
        pass
    pass
class BaseBullet():
    def __init__(self,screen,ImageName,x,y,who):
        self.x = x
        self.y = y
        self.screen = screen
        self.image = pygame.image.load(ImageName)
        self.BulletType=who     #是谁发射的子弹
        pass
    def Bullet_Display(self):
        self.screen.blit(self.image, (self.x, self.y))  # 显示子弹
    def Bullet_Move(self):
        if self.BulletType =='Hero':
            self.y -= 1
            pass
        else:
            self.y += 1
            pass
        pass

    def Bullet_Judge(self):  # 判断子弹越界
        if self.BulletType == 'Hero':
            if self.y < 0:
                return True
            pass
        else:
            if self.y > 800:
                return True
        pass

    pass





#玩家飞机类
class HeroPlane(BasePlan): #继承飞机的基类
    def __init__(self,screen):    #Screen是要显示在哪个窗口
        super().__init__(screen,'玩家.png',0,680) #调用父类的方法
        pass
    def MoveLeft(self):         #玩家飞机左移
        if self.x > 0:
            self.x -= 5
            pass
        pass
    def MoveRight(self):        #玩家飞机右移
        if self.x < 550:
            self.x+=5
        pass
    def SendBullet(self):                          #发射子弹
        #创建一个子弹对象
        NewBullet=Bullet(self.x,self.y,self.screen)
        self.BulletList.append(NewBullet)               #子弹对象追加到子弹列表列表中
        pass
    pass

#敌机类
class EnemyPlane(BasePlan):   #继承飞机基类
    def __init__(self,screen):    #Screen是要显示在哪个窗口
        super().__init__(screen, '敌机.png', 0, 0)  # 调用父类的方法
        # 移动的默认方向
        self.mod = 'rigth'
        pass
    def EnemyPlane_Move(self):        #玩家飞机右移
        if self.mod =='rigth':
            self.x+=1
            pass
        else:
            self.x-=1
            pass
        if self.x>500:
            self.mod = 'left'
            pass
        elif self.x<10:
            self.mod = 'rigth'
            pass
        pass
    def EnemyPlane_SendBullet(self):                          #发射子弹
        #创建一个子弹对象
        a = random.randint(1, 10)  # 生成1~5的随机数
        if a == 3: #假如生成的数字是3 则发射子弹
            NewBullet=EnemyBullet(self.x,self.y,self.screen)
            self.BulletList.append(NewBullet)               #子弹对象追加到子弹列表列表中
        pass
    pass

#玩家子弹类
class Bullet(BaseBullet):
    def __init__(self,x,y,screen):
        super().__init__(screen, '子弹.jpg', x+50, y-20,'Hero')  # 调用父类的方法
        pass
    pass

#敌机子弹类
class EnemyBullet(BaseBullet):
    def __init__(self,x,y,screen):
        super().__init__(screen, '敌机子弹.jpg', x+50, y+20,'Enemy')  # 调用父类的方法
        pass
    pass

#键盘检测
def KeyBood(HeroPlane):
    EventList = pygame.event.get()
    for event in EventList:
        if event.type == pygame.QUIT:  # 假如点击了“关闭”按钮
            print('退出')
            exit()
            pass
        elif event.type == pygame.KEYDOWN:  # 检测是否有按键按下
            if event.type == pygame.K_a or event.key == pygame.K_LEFT:  # 检测到左移
                print("left")
                HeroPlane.MoveLeft()
                pass
            if event.type == pygame.K_d or event.key == pygame.K_RIGHT:  # 检测到右移
                print("Right")
                HeroPlane.MoveRight()
                pass
            if event.key == pygame.K_SPACE:                             # 检测到空格 发射子弹
                print("发射子弹")
                HeroPlane.SendBullet()
                pass
            pass
        pass
    pass
#面向对象的实现方法
def main():
    # 创建一个窗口,用于显示内容
    Screen=pygame.display.set_mode((650,800),depth=0)
    #创建一个背景图片对象
    BackGround=pygame.image.load('background.jpg')
    #设置一个标题
    pygame.display.set_caption('ZXL的Python学习总结-----飞机大战')
    #添加背景音乐
    pygame.mixer.init()                         #类初始化
    pygame.mixer.music.load('坦克.mp3')          #添加音乐
    pygame.mixer.music.set_volume(0.5)          #设置音量
    pygame.mixer.music.play(-1)                 #设置循环次数,-1表示无限循环

    #载入我方飞机的对象
    Hero=HeroPlane(Screen)
    Enemy=EnemyPlane(Screen)
    while True:
        #显示背景
        Screen.blit(BackGround, (0, 0))
        #显示玩家飞机
        Hero.DisPlay()
        # 显示敌机
        Enemy.DisPlay()

        # 敌机移动
        Enemy.EnemyPlane_Move()
        #敌机发射子弹
        Enemy.EnemyPlane_SendBullet()

        #按键检测
        KeyBood(Hero)

        #更新显示
        pygame.display.update()
        pygame.time.Clock().tick(50)
        pass
    pass

if __name__=='__main__':
    main()
    pass

三、程序分析

3.1 安装pygame库

  Python制作小游戏可以依赖pygame库来实现。安装方法:

  1. 在windos cmd命令行输入  【pip install pygame】,之后等待安装
  2. 安装完成后用pycham新建工程

安装结束后通过命令【pip list】查看安装结果

3.2 创建窗口、标题、背景音乐

使用pygame中自带的操作函数实现。

    # 创建一个窗口,用于显示内容
    Screen=pygame.display.set_mode((650,800),depth=0)
    #创建一个背景图片对象
    BackGround=pygame.image.load('background.jpg')
    #设置一个标题
    pygame.display.set_caption('ZXL的Python学习总结-----飞机大战')
    #添加背景音乐
    pygame.mixer.init()                         #类初始化
    pygame.mixer.music.load('坦克.mp3')          #添加音乐
    pygame.mixer.music.set_volume(0.5)          #设置音量
    pygame.mixer.music.play(-1)                 #设置循环次数,-1表示无限循环

3.3 键盘检测

使用pygame中自带的操作函数实现。

EventList = pygame.event.get()     #获取按键
    for event in EventList:
        if event.type == pygame.KEYDOWN:  # 检测是否有按键按下

        '''
        下面就是根据按键的键值执行相应的操作
        '''

3.4 飞机属性的基类

基类中实现一些玩家飞机和敌方飞机共有的属性和方法。

属性有:贴图、显示的X和Y坐标、子弹列表、要显示的窗口

方法有:显示(包括子弹的显示和子弹的移除)

class BasePlan():
    def __init__(self, screen,ImageName,x,y):  # Screen是要显示在哪个窗口
        # 设置要显示内容的窗口
        self.screen = screen
        # 生成飞机图片
        self.image = pygame.image.load(ImageName)
        # 存放子弹的列表
        self.BulletList = []
        # 默认位置
        self.x = x
        self.y = y

        pass
    def DisPlay(self):
        self.screen.blit(self.image, (self.x, self.y))  # 显示飞机主体
        #完善子弹的展示逻辑
        NeedDelTtemlist=[]                      #创建要删除的子弹列表
        for item in  self.BulletList:           #遍历子弹列表
            if item.Bullet_Judge():             #判断子弹是否要删除
                NeedDelTtemlist.append(item)    #要删除的子弹对象追加到要删除的列表中
                pass
            item.Bullet_Display()               #显示子弹位置
            item.Bullet_Move()                  #子弹移动
            pass
            for i in NeedDelTtemlist:               #遍历要删除的子弹列表
                self.BulletList.remove(i)           #删除子弹对象
                pass
            # for iB in self.BulletList:              #遍历子弹列表
            #     iB.Bullet_Display()                 #显示子弹位置
            #     iB.Bullet_Move()                    #子弹移动
            pass
        pass
    pass

3.41 玩家飞机子类

玩家飞机的[[属性]直接继承【飞机的基类】,玩家飞机类中独特的是左移右移、和发射子弹都是由键盘控制的,因此都要有自己的[方法]去实现。

需要介绍的是发射子弹的方法,在【父类】中有一个[属性]是发射子弹的列表,当检测到玩家键盘按下要发射子弹,则直接在列表中追加一个【子弹类型】的对象,子弹的移动操作由【子弹基类】中的方法完成。【子弹基类】中有子弹超限的方法,在【飞机基类】中有子弹超界删除的操作

#玩家飞机类
class HeroPlane(BasePlan): #继承飞机的基类
    def __init__(self,screen):    #Screen是要显示在哪个窗口
        super().__init__(screen,'玩家.png',0,680) #调用父类的方法
        pass
    def MoveLeft(self):         #玩家飞机左移
        if self.x > 0:
            self.x -= 5
            pass
        pass
    def MoveRight(self):        #玩家飞机右移
        if self.x < 550:
            self.x+=5
        pass
    def SendBullet(self):                          #发射子弹
        #创建一个子弹对象
        NewBullet=Bullet(self.x,self.y,self.screen)
        self.BulletList.append(NewBullet)               #子弹对象追加到子弹列表列表中
        pass
    pass

3.42 敌机子类

敌机和玩家飞机大部分相同,其[[属性]也是直接继承【飞机的基类】,不同的是敌机的移动方式和发射子弹方式与玩家飞机不同。不同处由【敌机子类】自行完成.

#敌机类
class EnemyPlane(BasePlan):   #继承飞机基类
    def __init__(self,screen):    #Screen是要显示在哪个窗口
        super().__init__(screen, '敌机.png', 0, 0)  # 调用父类的方法
        # 移动的默认方向
        self.mod = 'rigth'
        pass
    def EnemyPlane_Move(self):        #玩家飞机右移
        if self.mod =='rigth':
            self.x+=1
            pass
        else:
            self.x-=1
            pass
        if self.x>500:
            self.mod = 'left'
            pass
        elif self.x<10:
            self.mod = 'rigth'
            pass
        pass
    def EnemyPlane_SendBullet(self):                          #发射子弹
        #创建一个子弹对象
        a = random.randint(1, 10)  # 生成1~5的随机数
        if a == 3: #假如生成的数字是3 则发射子弹
            NewBullet=EnemyBullet(self.x,self.y,self.screen)
            self.BulletList.append(NewBullet)               #子弹对象追加到子弹列表列表中
        pass
    pass

3.5 子弹基类

无论是敌机子弹还是玩家飞机的子弹都有以下共同的方法。从【对象】的角度出发,两者只是贴图不同而已。

基类中的方法有 : 子弹的显示、子弹的移动、子弹的越界判断

子弹的属性有    : 显示坐标、贴图、窗口、发射主角

class BaseBullet():
    def __init__(self,screen,ImageName,x,y,who):
        self.x = x
        self.y = y
        self.screen = screen
        self.image = pygame.image.load(ImageName)
        self.BulletType=who     #是谁发射的子弹
        pass
    def Bullet_Display(self):
        self.screen.blit(self.image, (self.x, self.y))  # 显示子弹
    def Bullet_Move(self):
        if self.BulletType =='Hero':
            self.y -= 1
            pass
        else:
            self.y += 1
            pass
        pass
    def Bullet_Judge(self):  # 判断子弹越界
        if self.BulletType == 'Hero':
            if self.y < 0:
                return True
            pass
        else:
            if self.y > 800:
                return True
        pass

    pass

3.51 玩家子弹 和 敌机子弹的子类

基类中的方法和属性完全满足使用。因此子类直接继承基类即可。

#玩家子弹类
class Bullet(BaseBullet):
    def __init__(self,x,y,screen):
        super().__init__(screen, '子弹.jpg', x+50, y-20,'Hero')  # 调用父类的方法
        pass
    pass

#敌机子弹类
class EnemyBullet(BaseBullet):
    def __init__(self,x,y,screen):
        super().__init__(screen, '敌机子弹.jpg', x+50, y+20,'Enemy')  # 调用父类的方法
        pass
    pass

猜你喜欢

转载自blog.csdn.net/qq_34301282/article/details/111405448