当前位置:   article > 正文

(保姆级教学)坦克大战游戏代码运行(附游戏完整代码)_append(etank)

append(etank)

 话不多说,先给我的美女们献上我的完整代码~

  1. import pygame, time, random
  2. _display = pygame.display
  3. COLOR_BLACK = pygame.Color(0, 0, 0)
  4. COLOR_RED = pygame.Color(255, 0, 0)
  5. version = 'v1.25'
  6. class MainGame():
  7. # 游戏主窗口
  8. window = None
  9. SCREEN_HEIGHT = 800
  10. SCREEN_WIDTH = 1300
  11. # 创建我方坦克
  12. TANK_P1 = None
  13. # 存储所有敌方坦克
  14. EnemyTank_list = []
  15. # 要创建的敌方坦克的数量
  16. EnemTank_count = 10
  17. # 存储我方子弹的列表
  18. Bullet_list = []
  19. # 存储敌方子弹的列表
  20. Enemy_bullet_list = []
  21. # 爆炸效果列表
  22. Explode_list = []
  23. # 墙壁列表
  24. Wall_list = []
  25. # 零食清单
  26. Classmate_list = ["糖炒板栗", "牛奶", "葡萄干", "巧克力", "芝士饼干", "肉松小贝"]
  27. # 开始游戏方法
  28. def startGame(self):
  29. _display.init()
  30. # 创建窗口加载窗口(借鉴官方文档)
  31. MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])
  32. self.creatMyTank()
  33. self.creatEnemyTank()
  34. self.creatWalls()
  35. # 设置一下游戏标题
  36. _display.set_caption("坦克大战" + version)
  37. # 让窗口持续刷新操作
  38. while True:
  39. # 给窗口完成一个填充颜色
  40. MainGame.window.fill(COLOR_BLACK)
  41. # 在循环中持续完成事件的获取
  42. self.getEvent()
  43. # 将绘制文字得到的小画布,粘贴到窗口中
  44. MainGame.window.blit(self.getTextSurface("剩余敌方坦克%d辆" % len(MainGame.EnemyTank_list)), (5, 5))
  45. #定制欢迎词
  46. number = 600
  47. for Classmate in MainGame.Classmate_list:
  48. MainGame.window.blit(self.getTextSurface("输了请我吃%s,好人一生平安~ " % Classmate), (500, number))
  49. number = number + 40
  50. # 调用展示墙壁的方法
  51. self.blitWalls()
  52. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  53. # 将我方坦克加入到窗口中
  54. MainGame.TANK_P1.displayTank()
  55. else:
  56. del MainGame.TANK_P1
  57. MainGame.TANK_P1 = None
  58. # 循环展示敌方坦克
  59. self.blitEnemyTank()
  60. # 根据坦克的开关状态调用坦克的移动方法
  61. if MainGame.TANK_P1 and not MainGame.TANK_P1.stop:
  62. MainGame.TANK_P1.move()
  63. # 调用碰撞墙壁的方法
  64. MainGame.TANK_P1.hitWalls()
  65. MainGame.TANK_P1.hitEnemyTank()
  66. # 调用渲染子弹列表的一个方法
  67. self.blitBullet()
  68. # 调用渲染敌方子弹列表的一个方法
  69. self.blitEnemyBullet()
  70. # 调用展示爆炸效果的方法
  71. self.displayExplodes()
  72. time.sleep(0.02)
  73. # 窗口的刷新
  74. _display.update()
  75. # 创建我方坦克的方法
  76. def creatMyTank(self):
  77. # 创建我方坦克
  78. MainGame.TANK_P1 = MyTank(400, 300)
  79. # 创建音乐对象
  80. music = Music('img/再见深海.wav')
  81. # 调用播放音乐方法
  82. music.play()
  83. # 创建敌方坦克
  84. def creatEnemyTank(self):
  85. top = 100
  86. for i in range(MainGame.EnemTank_count):
  87. speed = random.randint(3, 6)
  88. # 每次都随机生成一个left值
  89. left = random.randint(1, 7)
  90. eTank = EnemyTank(left * 100, top, speed)
  91. MainGame.EnemyTank_list.append(eTank)
  92. # 创建墙壁的方法
  93. def creatWalls(self):
  94. for i in range(10): # 创建墙壁的数量
  95. wall = Wall(130 * i, 240)
  96. MainGame.Wall_list.append(wall)
  97. def blitWalls(self):
  98. for wall in MainGame.Wall_list:
  99. if wall.live:
  100. wall.displayWall()
  101. else:
  102. MainGame.Wall_list.remove(wall)
  103. # 将敌方坦克加入到窗口中
  104. def blitEnemyTank(self):
  105. for eTank in MainGame.EnemyTank_list:
  106. if eTank.live:
  107. eTank.displayTank()
  108. # 坦克移动的方法
  109. eTank.randMove()
  110. # 调用敌方坦克与墙壁的碰撞方法
  111. eTank.hitWalls()
  112. # 敌方坦克是否撞到我方坦克
  113. eTank.hitMyTank()
  114. # 调用敌方坦克的射击
  115. eBullet = eTank.shot()
  116. # 如果子弹为None。不加入到列表
  117. if eBullet:
  118. # 将子弹存储敌方子弹列表
  119. MainGame.Enemy_bullet_list.append(eBullet)
  120. else:
  121. MainGame.EnemyTank_list.remove(eTank)
  122. # 将我方子弹加入到窗口中
  123. def blitBullet(self):
  124. for bullet in MainGame.Bullet_list:
  125. # 如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
  126. if bullet.live:
  127. bullet.displayBullet()
  128. # 让子弹移动
  129. bullet.bulletMove()
  130. # 调用我方子弹与敌方坦克的碰撞方法
  131. bullet.hitEnemyTank()
  132. # 调用判断我方子弹是否碰撞到墙壁的方法
  133. bullet.hitWalls()
  134. else:
  135. MainGame.Bullet_list.remove(bullet)
  136. # 将敌方子弹加入到窗口中
  137. def blitEnemyBullet(self):
  138. for eBullet in MainGame.Enemy_bullet_list:
  139. # 如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
  140. if eBullet.live:
  141. eBullet.displayBullet()
  142. # 让子弹移动
  143. eBullet.bulletMove()
  144. # 调用是否碰撞到墙壁的一个方法
  145. eBullet.hitWalls()
  146. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  147. eBullet.hitMyTank()
  148. else:
  149. MainGame.Enemy_bullet_list.remove(eBullet)
  150. # 新增方法: 展示爆炸效果列表
  151. def displayExplodes(self):
  152. for explode in MainGame.Explode_list:
  153. if explode.live:
  154. explode.displayExplode()
  155. else:
  156. MainGame.Explode_list.remove(explode)
  157. # 获取程序期间所有事件(鼠标事件,键盘事件)
  158. def getEvent(self):
  159. # 1.获取所有事件
  160. eventList = pygame.event.get()
  161. # 2.对事件进行判断处理(1、点击关闭按钮 2、按下键盘上的某个按键)
  162. for event in eventList:
  163. # 判断event.type 是否QUIT,如果是退出的话,直接调用程序结束方法
  164. if event.type == pygame.QUIT:
  165. self.endGame()
  166. # 判断事件类型是否为按键按下,如果是,继续判断按键是哪一个按键,来进行对应的处理
  167. if event.type == pygame.KEYDOWN:
  168. # 修改重生键
  169. if event.key == pygame.K_TAB and not MainGame.TANK_P1:
  170. # 调用创建我方坦克的方法
  171. self.creatMyTank()
  172. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  173. # 具体是哪一个按键的处理
  174. if event.key == pygame.K_LEFT:
  175. print("坦克向左调头,移动")
  176. # 修改坦克方向
  177. MainGame.TANK_P1.direction = 'L'
  178. MainGame.TANK_P1.stop = False
  179. elif event.key == pygame.K_RIGHT:
  180. print("坦克向右调头,移动")
  181. # 修改坦克方向
  182. MainGame.TANK_P1.direction = 'R'
  183. MainGame.TANK_P1.stop = False
  184. elif event.key == pygame.K_UP:
  185. print("坦克向上调头,移动")
  186. # 修改坦克方向
  187. MainGame.TANK_P1.direction = 'U'
  188. MainGame.TANK_P1.stop = False
  189. elif event.key == pygame.K_DOWN:
  190. print("坦克向下掉头,移动")
  191. # 修改坦克方向
  192. MainGame.TANK_P1.direction = 'D'
  193. MainGame.TANK_P1.stop = False
  194. # 修改攻击键
  195. elif event.key == pygame.K_END:
  196. print("发射子弹")
  197. if len(MainGame.Bullet_list) < 3:
  198. # 产生一颗子弹
  199. m = Bullet(MainGame.TANK_P1)
  200. # 将子弹加入到子弹列表
  201. MainGame.Bullet_list.append(m)
  202. music = Music('img/fire.wav')
  203. music.play()
  204. else:
  205. print("子弹数量不足")
  206. print("当前屏幕中的子弹数量为:%d" % len(MainGame.Bullet_list))
  207. # 结束游戏方法
  208. if event.type == pygame.KEYUP:
  209. # 松开的如果是方向键,才更改移动开关状态
  210. if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
  211. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  212. # 修改坦克的移动状态
  213. MainGame.TANK_P1.stop = True
  214. # 左上角文字绘制的功能
  215. def getTextSurface(self, text):
  216. # 初始化字体模块
  217. pygame.font.init()
  218. # 查看系统支持的所有字体
  219. # fontList = pygame.font.get_fonts()
  220. # print(fontList)
  221. # 选中一个合适的字体
  222. font = pygame.font.SysFont('kaiti', 18)
  223. # 使用对应的字符完成相关内容的绘制
  224. textSurface = font.render(text, True, COLOR_RED)
  225. return textSurface
  226. def endGame(self):
  227. print("菜鸡,你行不行啊?")
  228. # 结束python解释器
  229. exit()
  230. class BaseItem(pygame.sprite.Sprite):
  231. def __init__(self):
  232. pygame.sprite.Sprite.__init__(self)
  233. class Tank(BaseItem):
  234. def __init__(self, left, top):
  235. self.images = {
  236. 'U': pygame.image.load('img/p1tankU.gif'),
  237. 'D': pygame.image.load('img/p1tankD.gif'),
  238. 'L': pygame.image.load('img/p1tankL.gif'),
  239. 'R': pygame.image.load('img/p1tankR.gif')
  240. }
  241. self.direction = 'U'
  242. self.image = self.images[self.direction]
  243. # 坦克所在的区域 Rect->
  244. self.rect = self.image.get_rect()
  245. # 指定坦克初始化位置 分别距x,y轴的位置
  246. self.rect.left = left
  247. self.rect.top = top
  248. # 新增速度属性
  249. self.speed = 5
  250. # 新增属性: 坦克的移动开关
  251. self.stop = True
  252. # 新增属性 live 用来记录,坦克是否活着
  253. self.live = True
  254. # 新增属性: 用来记录坦克移动之前的坐标(用于坐标还原时使用)
  255. self.oldLeft = self.rect.left
  256. self.oldTop = self.rect.top
  257. # 坦克的移动方法
  258. def move(self):
  259. # 先记录移动之前的坐标
  260. self.oldLeft = self.rect.left
  261. self.oldTop = self.rect.top
  262. if self.direction == 'L':
  263. if self.rect.left > 0:
  264. self.rect.left -= self.speed
  265. elif self.direction == 'R':
  266. if self.rect.left + self.rect.height < MainGame.SCREEN_WIDTH:
  267. self.rect.left += self.speed
  268. elif self.direction == 'U':
  269. if self.rect.top > 0:
  270. self.rect.top -= self.speed
  271. elif self.direction == 'D':
  272. if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT:
  273. self.rect.top += self.speed
  274. def stay(self):
  275. self.rect.left = self.oldLeft
  276. self.rect.top = self.oldTop
  277. # 新增碰撞墙壁的方法
  278. def hitWalls(self):
  279. for wall in MainGame.Wall_list:
  280. if pygame.sprite.collide_rect(wall, self):
  281. self.stay()
  282. # 射击方法
  283. def shot(self):
  284. return Bullet(self)
  285. # 展示坦克(将坦克这个surface绘制到窗口中 blit())
  286. def displayTank(self):
  287. # 1.重新设置坦克的图片
  288. self.image = self.images[self.direction]
  289. # 2.将坦克加入到窗口中
  290. MainGame.window.blit(self.image, self.rect)
  291. class MyTank(Tank):
  292. def __init__(self, left, top):
  293. super(MyTank, self).__init__(left, top)
  294. # 新增主动碰撞到敌方坦克的方法
  295. def hitEnemyTank(self):
  296. for eTank in MainGame.EnemyTank_list:
  297. if pygame.sprite.collide_rect(eTank, self):
  298. self.stay()
  299. class EnemyTank(Tank):
  300. def __init__(self, left, top, speed):
  301. super(EnemyTank, self).__init__(left, top)
  302. # self.live = True
  303. self.images = {
  304. 'U': pygame.image.load('img/enemy1U.gif'),
  305. 'D': pygame.image.load('img/enemy1D.gif'),
  306. 'L': pygame.image.load('img/enemy1L.gif'),
  307. 'R': pygame.image.load('img/enemy1R.gif')
  308. }
  309. self.direction = self.randDirection()
  310. self.image = self.images[self.direction]
  311. # 坦克所在的区域 Rect->
  312. self.rect = self.image.get_rect()
  313. # 指定坦克初始化位置 分别距x,y轴的位置
  314. self.rect.left = left
  315. self.rect.top = top
  316. # 新增速度属性
  317. self.speed = speed
  318. self.stop = True
  319. # 新增步数属性,用来控制敌方坦克随机移动
  320. self.step = 30
  321. def randDirection(self):
  322. num = random.randint(1, 4)
  323. if num == 1:
  324. return 'U'
  325. elif num == 2:
  326. return 'D'
  327. elif num == 3:
  328. return 'L'
  329. elif num == 4:
  330. return 'R'
  331. # def displayEnemtTank(self):
  332. # super().displayTank()
  333. # 随机移动
  334. def randMove(self):
  335. if self.step <= 0:
  336. self.direction = self.randDirection()
  337. self.step = 50
  338. else:
  339. self.move()
  340. self.step -= 1
  341. def shot(self):
  342. num = random.randint(1, 1000)
  343. if num <= 20:
  344. return Bullet(self)
  345. def hitMyTank(self):
  346. if MainGame.TANK_P1 and MainGame.TANK_P1.live:
  347. if pygame.sprite.collide_rect(self, MainGame.TANK_P1):
  348. # 让敌方坦克停下来 stay()
  349. self.stay()
  350. class Bullet(BaseItem):
  351. def __init__(self, tank):
  352. # 子弹造型的图片
  353. self.image = pygame.image.load('img/enemymissile.gif')
  354. # 方向(坦克方向)
  355. self.direction = tank.direction
  356. # 位置
  357. self.rect = self.image.get_rect()
  358. if self.direction == 'U':
  359. self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  360. self.rect.top = tank.rect.top - self.rect.height
  361. elif self.direction == 'D':
  362. self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  363. self.rect.top = tank.rect.top + tank.rect.height
  364. elif self.direction == 'L':
  365. self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2
  366. self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  367. elif self.direction == 'R':
  368. self.rect.left = tank.rect.left + tank.rect.width
  369. self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  370. # 速度
  371. self.speed = 7
  372. # 用来记录子弹是否活着
  373. self.live = True
  374. # 子弹的移动方法
  375. def bulletMove(self):
  376. if self.direction == 'U':
  377. if self.rect.top > 0:
  378. self.rect.top -= self.speed
  379. else:
  380. # 修改状态值
  381. self.live = False
  382. elif self.direction == 'D':
  383. if self.rect.top < MainGame.SCREEN_HEIGHT - self.rect.height:
  384. self.rect.top += self.speed
  385. else:
  386. # 修改状态值
  387. self.live = False
  388. elif self.direction == 'L':
  389. if self.rect.left > 0:
  390. self.rect.left -= self.speed
  391. else:
  392. # 修改状态值
  393. self.live = False
  394. elif self.direction == 'R':
  395. if self.rect.left < MainGame.SCREEN_WIDTH - self.rect.width:
  396. self.rect.left += self.speed
  397. else:
  398. # 修改状态值
  399. self.live = False
  400. # 展示子弹的方法
  401. def displayBullet(self):
  402. MainGame.window.blit(self.image, self.rect)
  403. # 新增我方子弹碰撞敌方坦克的方法
  404. def hitEnemyTank(self):
  405. for eTank in MainGame.EnemyTank_list:
  406. if pygame.sprite.collide_rect(eTank, self):
  407. # 产生一个爆炸效果
  408. explode = Explode(eTank)
  409. # 将爆炸效果加入到爆炸效果列表
  410. MainGame.Explode_list.append(explode)
  411. self.live = False
  412. eTank.live = False
  413. # 新增敌方子弹与我方坦克的碰撞方法
  414. def hitMyTank(self):
  415. if pygame.sprite.collide_rect(self, MainGame.TANK_P1):
  416. # 产生爆炸效果,并加入到爆炸效果列表中
  417. explode = Explode(MainGame.TANK_P1)
  418. MainGame.Explode_list.append(explode)
  419. # 修改子弹状态
  420. self.live = False
  421. # 修改我方坦克状态
  422. MainGame.TANK_P1.live = False
  423. # 新增子弹与墙壁的碰撞
  424. def hitWalls(self):
  425. for wall in MainGame.Wall_list:
  426. if pygame.sprite.collide_rect(wall, self):
  427. # 修改子弹的live属性
  428. self.live = False
  429. wall.hp -= 1
  430. if wall.hp <= 0:
  431. wall.live = False
  432. class Explode():
  433. def __init__(self, tank):
  434. self.rect = tank.rect
  435. self.step = 0
  436. self.images = [
  437. pygame.image.load('img/blast0.gif'),
  438. pygame.image.load('img/blast1.gif'),
  439. pygame.image.load('img/blast2.gif'),
  440. pygame.image.load('img/blast3.gif'),
  441. pygame.image.load('img/blast4.gif')
  442. ]
  443. self.image = self.images[self.step]
  444. self.live = True
  445. # 展示爆炸效果
  446. def displayExplode(self):
  447. if self.step < len(self.images):
  448. MainGame.window.blit(self.image, self.rect)
  449. self.image = self.images[self.step]
  450. self.step += 1
  451. else:
  452. self.live = False
  453. self.step = 0
  454. class Wall():
  455. def __init__(self, left, top):
  456. self.image = pygame.image.load('img/steels.gif')
  457. self.rect = self.image.get_rect()
  458. self.rect.left = left
  459. self.rect.top = top
  460. # 用来判断墙壁是否应该在窗口中展示
  461. self.live = True
  462. # 墙壁的生命值
  463. self.hp = 30
  464. # 展示墙壁的方法
  465. def displayWall(self):
  466. MainGame.window.blit(self.image, self.rect)
  467. # 我方坦克出生
  468. class Music:
  469. def __init__(self, fileName):
  470. self.fileName = fileName
  471. # 先初始化混合器
  472. pygame.mixer.init()
  473. pygame.mixer.music.load(self.fileName)
  474. # 开始播放音乐
  475. def play(self):
  476. pygame.mixer.music.play()
  477. MainGame().startGame()

运行结果展示

代码里面是有完整注解的,还是有不明白的地方欢迎评论区留言~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/806258
推荐阅读
相关标签
  

闽ICP备14008679号