• Python——飞机大战(day10)


    目录

    一、面向过程实现

    二、面向对象


    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、首先设置进行窗口、背景设置

    1. import pygame # 引用pygame模块
    2. from pygame.locals import *
    3. import time
    4. def main():
    5. #----------------------------- 窗口、背景的基本设置 -------------------------
    6. # 首先创建一个窗口,用来显示内容
    7. screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
    8. # 创建一个背景图片对象
    9. background = pygame.image.load('./feiji/background.png') # 当前路径下的
    10. # 设置一个标题
    11. pygame.display.set_caption('阶段总结-飞机大战')
    12. # 添加背景音乐
    13. pygame.mixer.init() # 初始化这个函数
    14. pygame.mixer.music.load('./feiji/background.mp3')
    15. pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
    16. pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
    17. #函数原型:pygame.key.set_repeat(delay, interval)

    2、载入己方和地方飞机

    1. # 载入玩家的飞机图片
    2. hero = pygame.image.load('./feiji/hero.png')
    3. # 初始化玩家的位置:
    4. x, y = 155, 450 # 玩家飞机hero大小:40×50;(155, 450)表示在窗口最下方居中显示的位置

    3、循环更新显示界面

    1. # 设定要显示的内容
    2. while True:
    3. screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
    4. screen.blit(hero, (x, y)) # 显示玩家飞机
    5. # 获取键盘事件
    6. eventlist = pygame.event.get()
    7. for event in eventlist:
    8. if event.type == QUIT:
    9. print('退出')
    10. exit()
    11. pass
    12. elif event.type == KEYDOWN: # 是否按下了键盘
    13. if event.key == K_a or event.key == K_LEFT: # 按下了左键
    14. print('left')
    15. if x > 0:
    16. x -= 5
    17. elif x < 0:
    18. x = 0
    19. pass
    20. elif event.key == K_d or event.key == K_RIGHT: # 按下了右键
    21. print('right')
    22. if x < 310:
    23. x += 5
    24. elif x > 310:
    25. x = 310
    26. pass
    27. elif event.key == K_SPACE:
    28. print('K_SPACE')
    29. # 更新显示内容
    30. pygame.display.update()
    31. pass
    32. if __name__ == '__main__':
    33. main()

    到这里发现,可以控制飞机移动,但是每按下一次键盘只能移动一次,好像不符合正常游戏要求

    所以添加

    pygame.key.set_repeat(10, 15) # 放到初始化中,这两个参数都是以ms为单位的

     函数即可实现,按下连续移动

    只需要将这段代码放到初始化中即可!(ps:)

    代码的具体意义:
    在pygame中对按键的连续检测是默认失能的,调用上述函数便可以使能按键的连续检测。按键的连续检测使能后,当按键按下时,将会以delay的延时去触发第一次的KEYDOWN事件,之后则会以interval的延时去触发接下来的KEYDOWN事件。通俗的讲,第一个参数影响着按键的灵敏度,第二个参数影响着按键的移动时间间隔。即:以上述(10,15)来说,每次按下键盘触发KEYDOWN事件后,延时10ms后再次检测是否有还在按下,若在10ms内有按下,则之后以15ms的延时连续触发接下来的KEYDOWN。

    二、面向对象

    1. import pygame # 引用pygame模块
    2. from pygame.locals import *
    3. import time
    4. import random
    5. # ---------------------------------- 面对对象 -------------------------------------
    6. '''
    7. 1:实现飞机的显示,并且可以控制飞机的移动【面向对象】
    8. '''
    9. # 抽象出来一个飞机的基类
    10. class BasePlane(object):
    11. def __init__(self, screen, imagePath):
    12. '''
    13. 初始化基类函数
    14. :param screen: 主窗体对象
    15. :param imageName: 加载的图片
    16. '''
    17. self.screen = screen
    18. self.image = pygame.image.load(imagePath)
    19. self.bulletlist = [] #存储所有的子弹
    20. pass
    21. def display(self):
    22. self.screen.blit(self.image, (self.x, self.y))
    23. # 完善子弹的展示逻辑,删除越界的子弹,释放内存
    24. needDelItemList = []
    25. for item in self.bulletlist:
    26. if item.judge():
    27. needDelItemList.append(item)
    28. pass
    29. pass
    30. # 重新遍历一遍
    31. for i in needDelItemList:
    32. self.bulletlist.remove(i)
    33. pass
    34. for bullet in self.bulletlist:
    35. bullet.display() # 显示子弹的位置
    36. bullet.move() # 让这个子弹移动,下次再显示的就会看到子弹在修改后的位置
    37. pass
    38. pass
    39. class CommonBullet(object):
    40. '''
    41. 公共的子弹类
    42. '''
    43. def __init__(self, x, y, screen, bullettype):
    44. self.type = bullettype
    45. self.screen = screen
    46. if self.type == "hero":
    47. self.x += 20
    48. self.y -= 20
    49. self.imagePath = './feiji/bullet.png'
    50. elif self.type == "enemy":
    51. self.x = x
    52. self.y += 10
    53. self.imagePath = './feiji/bullet1.png'
    54. self.image = pygame.image.load(self.imagePath)
    55. def move(self):
    56. '''
    57. 子弹的移动
    58. :return:
    59. '''
    60. if self.type == 'hero':
    61. self.y -= 2
    62. elif self.type == 'enemy':
    63. self.y += 2
    64. def display(self):
    65. self.screen.blit(self.image,(self.x, self.y))
    66. pass
    67. class HeroPlane(BasePlane):
    68. def __init__(self, screen):
    69. '''
    70. 初始化函数
    71. :param screen: 主窗体对象
    72. '''
    73. super().__init__(screen, './feiji/hero.png') # 调用父类的构造方法
    74. # 飞机的默认位置
    75. self.x = 155
    76. self.y = 450
    77. pass
    78. def moveleft(self):
    79. '''
    80. 左移动
    81. :return:
    82. '''
    83. if self.x > 0:
    84. self.x -= 5
    85. elif self.x <= 0:
    86. self.x = 0
    87. pass
    88. def moveright(self):
    89. '''
    90. 右移动
    91. :return:
    92. '''
    93. if self.x < 310:
    94. self.x += 5
    95. elif self.x >= 310:
    96. self.x = 310
    97. pass
    98. def moveup(self):
    99. '''
    100. 上移动
    101. :return:
    102. '''
    103. if self.y > 0:
    104. self.y -= 5
    105. elif self.y <= 0:
    106. self.y = 0
    107. pass
    108. def movedown(self):
    109. '''
    110. 下移动
    111. :return:
    112. '''
    113. if self.y < 450:
    114. self.y += 5
    115. elif self.y >= 450:
    116. self.y = 450
    117. pass
    118. # 发射子弹
    119. def ShotBullet(self):
    120. # 创建一个新的子弹对象
    121. newbullet = CommonBullet(self.x, self.y, self.screen, 'hero')
    122. self.bulletlist.append(newbullet)
    123. pass
    124. '''
    125. 创建敌机类
    126. '''
    127. class EnemyPlane(BasePlane):
    128. def __init__(self, screen):
    129. super().__init__(screen, './feiji/enemy0.png')
    130. # 默认设置一个方向
    131. self.direction = 'right'
    132. # 飞机的默认位置
    133. self.x = 0
    134. self.y = 0
    135. pass
    136. def shotenemybullet(self):
    137. '''
    138. 敌机随机发射
    139. :return:
    140. '''
    141. num = random.randint(1,50)
    142. if num == 3:
    143. newbullet = CommonBullet(self.x, self.y, self.screen, 'enemy')
    144. self.bulletlist.append(newbullet)
    145. pass
    146. def move(self):
    147. '''
    148. 敌机移动 随机进行
    149. :return:
    150. '''
    151. if self.direction == 'right':
    152. self.x += 2
    153. elif self.direction == 'left':
    154. self.x -= 2
    155. if self.x > 330:
    156. self.direction = 'left'
    157. elif self.x < 0:
    158. self.direction = 'right'
    159. pass
    160. def key_control(HeroObj):
    161. '''
    162. 定义普通的函数,用来实现键盘的检测
    163. :param HeroObj:可控制检测的对象
    164. :return:
    165. '''
    166. # 获取键盘事件
    167. eventlist = pygame.event.get()
    168. # pygame.key.set_repeat(10, 15)
    169. pygame.key.set_repeat(200, 15)
    170. # pygame.key.set_repeat(200, 200)
    171. for event in eventlist:
    172. if event.type == QUIT:
    173. print('退出')
    174. exit()
    175. pass
    176. elif event.type == KEYDOWN: # 是否按下了键盘
    177. if event.key == K_a or event.key == K_LEFT: # 按下了左键
    178. print('left')
    179. HeroObj.moveleft() # 调用函数实现左移动
    180. pass
    181. elif event.key == K_d or event.key == K_RIGHT: # 按下了右键
    182. print('right')
    183. HeroObj.moveright() # 调用函数实现右移动
    184. pass
    185. elif event.key == K_w or event.key == K_UP: # 按下了右键
    186. print('up')
    187. HeroObj.moveup() # 调用函数实现上移动
    188. pass
    189. elif event.key == K_s or event.key == K_DOWN: # 按下了右键
    190. print('down')
    191. HeroObj.movedown() # 调用函数实现下移动
    192. pass
    193. elif event.key == K_SPACE:
    194. print('K_SPACE')
    195. HeroObj.ShotBullet()
    196. def main():
    197. #----------------------------- 窗口、背景的基本设置 -------------------------
    198. # 首先创建一个窗口,用来显示内容
    199. screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
    200. # 创建一个背景图片对象
    201. background = pygame.image.load('./feiji/background.png') # 当前路径下的
    202. # 设置一个标题
    203. pygame.display.set_caption('阶段总结-飞机大战')
    204. # 添加背景音乐
    205. pygame.mixer.init() # 初始化这个函数
    206. pygame.mixer.music.load('./feiji/background.mp3')
    207. pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
    208. pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
    209. #函数原型:pygame.key.set_repeat(delay, interval)
    210. # 创建一个飞机对象
    211. hero = HeroPlane(screen)
    212. # 创建一个敌人
    213. enemyplane = EnemyPlane(screen)
    214. # 设定要显示的内容
    215. while True:
    216. screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
    217. hero.display()
    218. enemyplane.display() # 显示敌机
    219. enemyplane.move() # 敌机移动
    220. enemyplane.shotenemybullet() # 敌机随机发射子弹
    221. # 获取键盘事件
    222. key_control(hero)
    223. # 更新显示内容
    224. pygame.display.update()
    225. # time.sleep(1)
    226. pygame.time.Clock().tick(15) # 每秒发生15次
    227. pass
    228. if __name__ == '__main__':
    229. main()


      

  • 相关阅读:
    Linux 远程登录(Xshell7)
    穿越时空:未来云计算的奇妙世界
    数据库及ADO.NET学习(六)
    申报高企的条件你真的满足了吗?
    4. MongoDB部署
    Java后端接口幂等的方案
    Caputo 分数阶一维问题基于 L1 逼近的快速差分方法(附Matlab代码)
    鸿蒙 Harmony 初体验
    6.2 整合MongoDB
    Java 拷贝
  • 原文地址:https://blog.csdn.net/qq_47941078/article/details/125402461