Python学习 day10-2021.3.8(飞机大战游戏)


Python入门课程系列:

  • Python学习 day1:认识Python
  • Python学习 day2:判断语句与循环控制
  • Python学习 day3:高级数据类型
  • Python学习 day4:函数基础
  • Python学习 day5:函数
  • Python学习 day6:内置函数
  • Python学习 day7:面向对象基础·上
  • Python学习 day8:面向对象基础·中
  • Python学习 day9:面向对象基础·下

1. Pygame

Pygame介绍:Pygame是一个利用SDL库写的游戏库,SDL库全名Simple DirectMedia Layer,是用C写的,不过也可以用C++进行开发,Pygame就是Python中使用它的一个库
官网教程:http://www.pygame.org/docs/
官网安装指南:https://www.pygame.org/wiki/GettingStarted#Pygame%20Installation
Pygame模块一览表:

模块名 功能 模块名 功能
pygame.cdrom 访问光驱 pygame.movie 播放视频
pygame.cursors 加载光标 pygame.music 播放音频
pygame.display 访问显示设备 pygame.overlay 访问高级视频叠加
pygame.draw 绘制形状、线和点 pygame 就是我们在学的这个东西了……
pygame.event 管理事件 pygame.rect 管理矩形区域
pygame.font 使用字体 pygame.sndarray 操作声音数据
pygame.image 加载和存储图片 pygame.sprite 操作移动图像
pygame.joystick 使用游戏手柄或者类似的东西 pygame.surface 管理图像和屏幕
pygame.key 读取键盘按键 pygame.surfarray 管理点阵图像数据
pygame.mixer 声音 pygame.time 管理时间和帧信息
pygame.mouse 鼠标 pygame.transform 缩放和移动图像

在电脑安装好pygame后,打开pycharm安装pygame模块


如果在pycharm中安装不成功,出现Command "python setup.py egg_info" failed with code 1 in xxx\xxx\xxx的报错,说明pycharm和pygame版本不同步,处理方法:1. 确保在系统层面的python环境里面已经安装了pygame(pip install pygame);2. 可以把已经安装好的pygame模块的文件夹拷贝到pycharm所创建项目中venv虚拟环境里面。

2. 思路

需求的描述:

存在4个对象:
我方飞机、敌方飞机、我方子弹、敌方子弹。
功能:
背景音乐的添加
我方飞机可以移动【根据按键来控制的】
敌方飞机也可以移动【随机的自动移动】
双方飞机都可以发射子弹
步骤:
1.创建一个窗口
2.创建一个我方飞机 根据方向键左右的移动
3.给我方飞机添加发射子弹的功能【按下空格键发射】
4.创建一个敌机
5.敌机可以自由移动
6.敌机可以发射子弹
准备背景音乐和素材图片(战机、敌机、战机子弹、敌机子弹)

控制玩具飞机-面向对象⚠️

实现步骤与原理:
实现步骤原理跟面向过程是一样的,不同的是代码的组织方式不一样:
1)创建一个飞机类,实现左移、右移、显示三个功能
2)创建一个键盘控制函数,实现键盘的左、右、空格键的功能
3)创建主函数,实现创建窗口、背景图片、背景音乐、并实现所有的逻辑

玩家飞机发射子弹⚠️

实现原理
1)每次按回车键就会有一颗子弹射出,起始位置就是从飞机的停靠位置
2)子弹超出窗口就会消失,并且删除掉子弹(否则子弹越来越多,界面会越来越卡)
3)每一颗子弹就代表一张图片
4)子弹从发射开始 ,慢慢往上移动直到消失。

import pygame #引用第三方模块
import random
import time
from pygame.locals import * #*表示要导入这个包所有的内容
'''
1. 实现飞机的显示,并且可以控制飞机的移动【面向对象】
'''
class HeroPlane(object):
    def __init__(self,screen):
        '''
        初始化函数
        :param screen: 主窗体对象
        '''
        #设定飞机的默认位置
        self.x=175
        self.y=615
        #设置要显示内容的窗口
        self.screen=screen
        #生成飞机的图片对象
        self.imageName='./雷霆战机/images/hero/hero04.png'
        self.image=pygame.image.load(self.imageName)
        #用来存放子弹的列表
        self.bulletList=[]
        pass
    def moveleft(self):
        '''
        左移
        :return:
        '''
        if self.x>0:
            self.x-=10
        pass
    def moveright(self,):
        '''
        右移
        :return:
        '''
        if self.x<490:
            self.x+=10
        pass
    def display(self):
        '''
        飞机在主窗口中的显示
        :return:
        '''
        self.screen.blit(self.image,(self.x,self.y))
        #完善子弹的显示逻辑
        needDelItemList=[]
        for item in self.bulletList:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        #重新遍历一下
        for i in needDelItemList:
            self.bulletList.remove(i)
            pass
        for bullet in self.bulletList:
            bullet.display() #显示子弹的位置
            bullet.move() #让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
        pass
    #发射子弹
    def sheBullet(self):
        #创建一个新的子弹对象
        newBullet=Bullet(self.x,self.y,self.screen)
        self.bulletList.append(newBullet)
        pass
    pass

#创建子弹类对象
class Bullet(object):
    def __init__(self,x,y,screen):
        '''

        :param x:
        :param y:
        :param screen:
        '''
        self.x=x+50
        self.y=y-10
        self.screen=screen
        self.image=pygame.image.load('./雷霆战机/images/bullet/img_bullet.png')
        pass
    def display(self):
        self.screen.blit(self.image,(self.x,self.y))
        pass
    def move(self):
        self.y-=5
        pass
    def judge(self):
        '''
        判断子弹是否越界
        :return:
        '''
        if self.y<0:
            return True
        else:
            return False
    pass

#创建敌机类
class EnemyPlane:
    def __init__(self,screen):
        #默认设置一个方向
        self.direction='right'
        # 设定飞机的默认位置
        self.x = 0
        self.y = 0
        # 设置要显示内容的窗口
        self.screen = screen
        self.bulletList=[]
        # 生成飞机的图片对象
        self.imageName = './雷霆战机/images/enemy/boss.png'
        self.image = pygame.image.load(self.imageName)
        pass
    def display(self):
        '''
        显示敌机以及子弹位置信息
        :return:
        '''
        self.screen.blit(self.image,(self.x,self.y))
        # 完善子弹的显示逻辑
        needDelItemList = []
        for item in self.bulletList:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        # 重新遍历一下
        for i in needDelItemList:
            self.bulletList.remove(i)
            pass
        for bullet in self.bulletList:
            bullet.display()  # 显示子弹的位置
            bullet.move()  # 让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
        pass
        pass
    def sheBullet(self):
        '''
        敌机随机发射子弹
        :return:
        '''
        num=random.randint(1,100)
        if num==3:
            newBullet=EnemyBullet(self.x,self.y,self.screen)
            self.bulletList.append(newBullet)
        pass
    def move(self):
        '''
        敌机移动,随机进行
        :return:
        '''
        if self.direction=='right':
            self.x+=1
            pass
        elif self.direction=='left':
            self.x-=1
            pass
        if self.x>260:
            self.direction='left'
            pass
        elif self.x<0:
            self.direction='right'
    pass

#敌机子弹类
class EnemyBullet(object):
    def __init__(self,x,y,screen):
        '''

        :param x:
        :param y:
        :param screen:
        '''
        self.x=x+90
        self.y=y+90
        self.screen=screen
        self.image=pygame.image.load('./雷霆战机/images/bullet/enemy_bullet.png')
        pass
    def display(self):
        self.screen.blit(self.image,(self.x,self.y))
        pass
    def move(self):
        self.y+=3
        pass
    def judge(self):
        '''
        判断子弹是否越界
        :return:
        '''
        if self.y>700:
            return True
        else:
            return False
    pass

def key_control(HeroObj):
    '''
    定义普通函数 用来实现键盘的检测
    :param HeroObj: 可控制检测的对象
    :return:
    '''
    # 获取键盘事件
    eventlist = pygame.event.get()
    for event in eventlist:
        if event.type == QUIT:
            print('退出')
            exit()
            pass
        elif event.type == KEYDOWN:
            if event.type == K_a or event.key == K_LEFT:
                print('left')
                HeroObj.moveleft() #调用函数实现左移
            elif event.type == K_d or event.key == K_RIGHT:
                print('right')
                HeroObj.moveright() #调用函数实现右移
            elif event.key == K_SPACE:
                print('K_SPACE')
                HeroObj.sheBullet()
    pass

def main():
    # 首先创建窗口对象
    screen=pygame.display.set_mode((450,700))
    #创建一个背景图片对象
    background=pygame.image.load('./雷霆战机/images/bg/bg1.jpg')
    #设置一个title
    pygame.display.set_caption('huihui飞机大战')
    #添加背景音乐
    pygame.mixer.init() #初始化这个函数
    pygame.mixer.music.load('./PlaneWar/sound/game_music.ogg')
    pygame.mixer.music.set_volume((0.2))
    pygame.mixer.music.play(-1) #表示无限循环

    #创建一个飞机对象
    hero=HeroPlane(screen)
    #创建一个敌机对象
    enemyplane=EnemyPlane(screen)
    #设定需要显示的内容
    while True:
        screen.blit(background,(0,0))
        # 显示玩家飞机图片
        hero.display()
        enemyplane.display() #显示敌机
        enemyplane.move() #敌机移动
        enemyplane.sheBullet() #敌机随机发射子弹
        #获取键盘事件
        key_control((hero))
        #更新显示内容
        pygame.display.update()
        # time.sleep(1) #休眠一秒钟
        pygame.time.Clock().tick(20) #一秒钟运行20次

    pass
if __name__=='__main__':
    main()
抽象基类⚠️
import pygame #引用第三方模块
import random
import time
from pygame.locals import * #*表示要导入这个包所有的内容
'''
1. 实现飞机的显示,并且可以控制飞机的移动【面向对象】
'''
'''
1:实现飞机的显示 并且可以控制飞机的移动【面向对象】
'''
#抽象一个飞机的基类
class BasePlane(object):
    def __init__(self,screen,imageName):
        '''
        初始化基类函数
        :param screen:主窗体对象
        :param imageName:加载的图片
        '''
        self.screen=screen
        self.image=pygame.image.load(imageName)
        self.bulletList=[] #存储所有的子弹
        pass
    def display(self):
        self.screen.blit(self.image, (self.x, self.y))
        # 完善子弹的显示逻辑
        needDelItemList = []
        for item in self.bulletList:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        # 重新遍历一下
        for i in needDelItemList:
            self.bulletList.remove(i)
            pass
        for bullet in self.bulletList:
            bullet.display()  # 显示子弹的位置
            bullet.move()  # 让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
        pass
    pass

class CommonBullet(object):
    '''
    公共的子弹类
    '''
    def __init__(self,x,y,screen,bulletTYpe):
        self.type=bulletTYpe
        self.screen=screen
        if self.type=='hero':
            self.x=x+50
            self.y=y-10
            self.imagePath='./雷霆战机/images/bullet/img_bullet.png'
        elif self.type=='enemy':
            self.x=x+90
            self.y=y+90
            self.imagePath='./雷霆战机/images/bullet/enemy_bullet.png'
            pass
        self.image=pygame.image.load(self.imagePath)
        pass
    def move(self):
        '''
        子弹的移动
        :return:
        '''
        if self.type=='hero':
            self.y-=5
        elif self.type=='enemy':
            self.y+=3
            pass
        pass
    def display(self):
        self.screen.blit(self.image,(self.x,self.y))
        pass
    def judge(self):
        '''
        判断子弹是否越界
        :return:
        '''
        if self.y>700 or self.x<0:
            return True
        else:
            return False
        pass
    pass

class HeroPlane(BasePlane):
    def __init__(self,screen):
        '''
        初始化函数
        :param screen: 主窗体对象
        '''
        super().__init__(screen,'./雷霆战机/images/hero/hero04.png')
        #设定飞机的默认位置
        self.x=175
        self.y=615
        pass
    def moveleft(self):
        '''
        左移
        :return:
        '''
        if self.x>0:
            self.x-=10
        pass
    def moveright(self,):
        '''
        右移
        :return:
        '''
        if self.x<490:
            self.x+=10
        pass
    #发射子弹
    def sheBullet(self):
        #创建一个新的子弹对象
        newBullet=CommonBullet(self.x,self.y,self.screen,'hero')
        self.bulletList.append(newBullet)
        pass
    pass

#创建敌机类
class EnemyPlane(BasePlane):
    def __init__(self,screen):
        super.__init__(screen,'./雷霆战机/images/enemy/boss.png')
        #默认设置一个方向
        self.direction='right'
        # 设定飞机的默认位置
        self.x = 0
        self.y = 0
        pass
    def sheBullet(self):
        '''
        敌机随机发射子弹
        :return:
        '''
        num=random.randint(1,100)
        if num==3:
            newBullet=CommonBullet(self.x,self.y,self.screen,'enemy')
            self.bulletList.append(newBullet)
        pass
    def move(self):
        '''
        敌机移动,随机进行
        :return:
        '''
        if self.direction=='right':
            self.x+=1
            pass
        elif self.direction=='left':
            self.x-=1
            pass
        if self.x>260:
            self.direction='left'
            pass
        elif self.x<0:
            self.direction='right'
    pass

def key_control(HeroObj):
    '''
    定义普通函数 用来实现键盘的检测
    :param HeroObj: 可控制检测的对象
    :return:
    '''
    # 获取键盘事件
    eventlist = pygame.event.get()
    for event in eventlist:
        if event.type == QUIT:
            print('退出')
            exit()
            pass
        elif event.type == KEYDOWN:
            if event.type == K_a or event.key == K_LEFT:
                print('left')
                HeroObj.moveleft() #调用函数实现左移
            elif event.type == K_d or event.key == K_RIGHT:
                print('right')
                HeroObj.moveright() #调用函数实现右移
            elif event.key == K_SPACE:
                print('K_SPACE')
                HeroObj.sheBullet()
    pass

def main():
    # 首先创建窗口对象
    screen=pygame.display.set_mode((450,700))
    #创建一个背景图片对象
    background=pygame.image.load('./雷霆战机/images/bg/bg1.jpg')
    #设置一个title
    pygame.display.set_caption('huihui飞机大战')
    #添加背景音乐
    pygame.mixer.init() #初始化这个函数
    pygame.mixer.music.load('./PlaneWar/sound/game_music.ogg')
    pygame.mixer.music.set_volume((0.2))
    pygame.mixer.music.play(-1) #表示无限循环

    #创建一个飞机对象
    hero=HeroPlane(screen)
    #创建一个敌机对象
    enemyplane=EnemyPlane(screen)
    #设定需要显示的内容
    while True:
        screen.blit(background,(0,0))
        # 显示玩家飞机图片
        hero.display()
        enemyplane.display() #显示敌机
        enemyplane.move() #敌机移动
        enemyplane.sheBullet() #敌机随机发射子弹
        #获取键盘事件
        key_control((hero))
        #更新显示内容
        pygame.display.update()
        # time.sleep(1) #休眠一秒钟
        pygame.time.Clock().tick(20) #一秒钟运行20次

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

你可能感兴趣的:(Python学习 day10-2021.3.8(飞机大战游戏))