plane pro需求的描述:
存在四个对象:
我方飞机、敌方飞机、我方子弹、敌方子弹
功能:
背景音乐的添加
我方飞机可以移动【根据按键来控制的】
敌方飞机也可以移动【随机的自动移动】
双方飞机都可以发送子弹
步骤:
1.创建一个窗口
2.创建一个我方飞机 根据方向键左右的移动
3.给我方飞机添加发射子弹的功能【按下空格键去发送】
4.创建一个敌人飞机
5.敌人飞机可以自由的移动
6.敌人飞机可以自动的发射子弹
在安装pygame模块的时候尤其要注意一下:
如果在pychram中安装不成功 如下错误:
EOFError: EOF when reading a line
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\Administrator\AppData\Local\Temp\pip-install-392v1at0\pygame\
此时我们就可以换种思路:
1:确保在系统层面的python环境里面 已经安装了pygame[pip install pygame] 一般都可以安装成功
2: 我们就可以把 已经安装好的 pygame 模块的 文件夹拷贝到 pycharm 所创建项目中的venv虚拟环境里面【E:\PythonPro\PlaneDemo\venv\Lib\site-packages】
soure path:C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\Lib\site-packages
dst path: 你的项目路径/venv\Lib\site-packages
1、首先设置进行窗口、背景设置
- import pygame # 引用pygame模块
- from pygame.locals import *
- import time
-
- def main():
-
- #----------------------------- 窗口、背景的基本设置 -------------------------
-
- # 首先创建一个窗口,用来显示内容
- screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
- # 创建一个背景图片对象
- background = pygame.image.load('./feiji/background.png') # 当前路径下的
- # 设置一个标题
- pygame.display.set_caption('阶段总结-飞机大战')
- # 添加背景音乐
- pygame.mixer.init() # 初始化这个函数
- pygame.mixer.music.load('./feiji/background.mp3')
- pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
- pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
- #函数原型:pygame.key.set_repeat(delay, interval)
2、载入己方和地方飞机
- # 载入玩家的飞机图片
- hero = pygame.image.load('./feiji/hero.png')
- # 初始化玩家的位置:
- x, y = 155, 450 # 玩家飞机hero大小:40×50;(155, 450)表示在窗口最下方居中显示的位置
3、循环更新显示界面
- # 设定要显示的内容
- while True:
- screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
- screen.blit(hero, (x, y)) # 显示玩家飞机
- # 获取键盘事件
- eventlist = pygame.event.get()
- for event in eventlist:
- if event.type == QUIT:
- print('退出')
- exit()
- pass
- elif event.type == KEYDOWN: # 是否按下了键盘
- if event.key == K_a or event.key == K_LEFT: # 按下了左键
- print('left')
- if x > 0:
- x -= 5
- elif x < 0:
- x = 0
- pass
-
- elif event.key == K_d or event.key == K_RIGHT: # 按下了右键
- print('right')
- if x < 310:
- x += 5
- elif x > 310:
- x = 310
- pass
-
- elif event.key == K_SPACE:
- print('K_SPACE')
- # 更新显示内容
- pygame.display.update()
- pass
-
- if __name__ == '__main__':
- main()
到这里发现,可以控制飞机移动,但是每按下一次键盘只能移动一次,好像不符合正常游戏要求

所以添加
pygame.key.set_repeat(10, 15) # 放到初始化中,这两个参数都是以ms为单位的
函数即可实现,按下连续移动
只需要将这段代码放到初始化中即可!(ps:)
代码的具体意义:
在pygame中对按键的连续检测是默认失能的,调用上述函数便可以使能按键的连续检测。按键的连续检测使能后,当按键按下时,将会以delay的延时去触发第一次的KEYDOWN事件,之后则会以interval的延时去触发接下来的KEYDOWN事件。通俗的讲,第一个参数影响着按键的灵敏度,第二个参数影响着按键的移动时间间隔。即:以上述(10,15)来说,每次按下键盘触发KEYDOWN事件后,延时10ms后再次检测是否有还在按下,若在10ms内有按下,则之后以15ms的延时连续触发接下来的KEYDOWN。
- import pygame # 引用pygame模块
- from pygame.locals import *
- import time
- import random
- # ---------------------------------- 面对对象 -------------------------------------
-
- '''
- 1:实现飞机的显示,并且可以控制飞机的移动【面向对象】
- '''
- # 抽象出来一个飞机的基类
- class BasePlane(object):
- def __init__(self, screen, imagePath):
- '''
- 初始化基类函数
- :param screen: 主窗体对象
- :param imageName: 加载的图片
- '''
- self.screen = screen
- self.image = pygame.image.load(imagePath)
- 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 += 20
- self.y -= 20
- self.imagePath = './feiji/bullet.png'
- elif self.type == "enemy":
- self.x = x
- self.y += 10
- self.imagePath = './feiji/bullet1.png'
- self.image = pygame.image.load(self.imagePath)
- def move(self):
- '''
- 子弹的移动
- :return:
- '''
- if self.type == 'hero':
- self.y -= 2
- elif self.type == 'enemy':
- self.y += 2
- def display(self):
- self.screen.blit(self.image,(self.x, self.y))
- pass
-
- class HeroPlane(BasePlane):
- def __init__(self, screen):
- '''
- 初始化函数
- :param screen: 主窗体对象
- '''
-
- super().__init__(screen, './feiji/hero.png') # 调用父类的构造方法
- # 飞机的默认位置
- self.x = 155
- self.y = 450
- pass
- def moveleft(self):
- '''
- 左移动
- :return:
- '''
- if self.x > 0:
- self.x -= 5
- elif self.x <= 0:
- self.x = 0
- pass
- def moveright(self):
- '''
- 右移动
- :return:
- '''
- if self.x < 310:
- self.x += 5
- elif self.x >= 310:
- self.x = 310
- pass
- def moveup(self):
- '''
- 上移动
- :return:
- '''
- if self.y > 0:
- self.y -= 5
- elif self.y <= 0:
- self.y = 0
- pass
- def movedown(self):
- '''
- 下移动
- :return:
- '''
- if self.y < 450:
- self.y += 5
- elif self.y >= 450:
- self.y = 450
- pass
- # 发射子弹
- def ShotBullet(self):
- # 创建一个新的子弹对象
- newbullet = CommonBullet(self.x, self.y, self.screen, 'hero')
- self.bulletlist.append(newbullet)
- pass
-
- '''
- 创建敌机类
- '''
- class EnemyPlane(BasePlane):
- def __init__(self, screen):
- super().__init__(screen, './feiji/enemy0.png')
- # 默认设置一个方向
- self.direction = 'right'
- # 飞机的默认位置
- self.x = 0
- self.y = 0
- pass
- def shotenemybullet(self):
- '''
- 敌机随机发射
- :return:
- '''
- num = random.randint(1,50)
- 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 += 2
- elif self.direction == 'left':
- self.x -= 2
- if self.x > 330:
- self.direction = 'left'
- elif self.x < 0:
- self.direction = 'right'
- pass
-
- def key_control(HeroObj):
- '''
- 定义普通的函数,用来实现键盘的检测
- :param HeroObj:可控制检测的对象
- :return:
- '''
-
- # 获取键盘事件
- eventlist = pygame.event.get()
- # pygame.key.set_repeat(10, 15)
- pygame.key.set_repeat(200, 15)
- # pygame.key.set_repeat(200, 200)
- for event in eventlist:
- if event.type == QUIT:
- print('退出')
- exit()
- pass
- elif event.type == KEYDOWN: # 是否按下了键盘
- if event.key == K_a or event.key == K_LEFT: # 按下了左键
- print('left')
- HeroObj.moveleft() # 调用函数实现左移动
- pass
- elif event.key == K_d or event.key == K_RIGHT: # 按下了右键
- print('right')
- HeroObj.moveright() # 调用函数实现右移动
- pass
- elif event.key == K_w or event.key == K_UP: # 按下了右键
- print('up')
- HeroObj.moveup() # 调用函数实现上移动
- pass
- elif event.key == K_s or event.key == K_DOWN: # 按下了右键
- print('down')
- HeroObj.movedown() # 调用函数实现下移动
- pass
- elif event.key == K_SPACE:
- print('K_SPACE')
- HeroObj.ShotBullet()
-
-
- def main():
- #----------------------------- 窗口、背景的基本设置 -------------------------
- # 首先创建一个窗口,用来显示内容
- screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
- # 创建一个背景图片对象
- background = pygame.image.load('./feiji/background.png') # 当前路径下的
- # 设置一个标题
- pygame.display.set_caption('阶段总结-飞机大战')
- # 添加背景音乐
- pygame.mixer.init() # 初始化这个函数
- pygame.mixer.music.load('./feiji/background.mp3')
- pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
- pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
- #函数原型:pygame.key.set_repeat(delay, interval)
-
- # 创建一个飞机对象
- hero = HeroPlane(screen)
- # 创建一个敌人
- enemyplane = EnemyPlane(screen)
-
- # 设定要显示的内容
- while True:
- screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
- hero.display()
- enemyplane.display() # 显示敌机
- enemyplane.move() # 敌机移动
- enemyplane.shotenemybullet() # 敌机随机发射子弹
- # 获取键盘事件
- key_control(hero)
- # 更新显示内容
- pygame.display.update()
- # time.sleep(1)
- pygame.time.Clock().tick(15) # 每秒发生15次
- pass
-
- if __name__ == '__main__':
- main()