【Python的魅力】:利用Pygame实现游戏坦克大战——含完整源码

avatar
作者
筋斗云
阅读量:4

文章目录

一、游戏运行效果

二、代码实现

坦克大战游戏

2.1 项目搭建

本游戏主要分为两个对象,分别是我方坦克和敌方坦克。用户可以通过控制我方的坦克来摧毁敌方的坦克保护自己的“家”,把所有的敌方坦克消灭完达到胜利。敌方的坦克在初始的时候是默认 5 个的(这可以自己设置),当然,如果我方坦克被敌方坦克的子弹打中,游戏结束。从面向对象分析该项目有以下类组成:
在这里插入图片描述

  • 主类:主要包括开始游戏、结束游戏的功能。
class MainGame():     def __init__(self):         pass     # 开始游戏     def startGame(self):         pass     # 结束游戏     def endGame(self):         pass 
  • 坦克类:主要包括坦克的创建、显示、移动及射击的功能。
class Tank():     def __init__(self):         pass     # 移动     def move(self):         pass     # 射击     def shot(self):         pass     # 展示坦克的方法     def displayTank(self):         pass 
  • 我方坦克类继承坦克类,主要包括创建、与敌方坦克的碰撞方法。
# 我方坦克 class MyTank(Tank):     def __init__(self):         pass 
  • 敌方坦克类继承坦克类,主要包括创建、与我方坦克碰撞方法。
# 敌方坦克 class EnemyTank(Tank):     def __init__(self):         pass 
  • 子弹类:主要包括子弹的创建、显示及移动的功能。
# 子弹类 class Bullet():     def __init__(self):         pass     # 移动     def move(self):         pass     # 展示子弹的方法     def displayBullet(self):         pass 
  • 墙壁类:主要包括墙壁的创建、显示的功能。
class Wall():     def __init__(self):         pass     # 展示墙壁的方法     def displayWall(self):         pass 
  • 爆炸效果类:主要展示爆炸效果。
class Explode():     def __init__(self):         pass     # 展示爆炸效果的方法     def displayExplode(self):         pass 
  • 音效类:主要播放音乐。
class Music():     def __init__(self):         pass     # 播放音乐     def play(self):         pass 

显示游戏窗口

在游戏设计的前期,要先创建游戏的界面,也就是要为所设计的游戏创建一个窗口。
【示例】:显示游戏窗口

def startGame(self):     # 加载主窗口     # 初始化窗口     pygame.display.init()     # 设置窗口的大小及显示     MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])     # 设置窗口的标题     pygame.display.set_caption('坦克大战1.03')     while True:         # 给窗口设置填充色         MainGame.window.fill(BG_COLOR)         pygame.display.update() MainGame().startGame() 

运行效果:
在这里插入图片描述

添加提示文字
在运行代码时会发现,创建的窗口没有任何提示。然而在实际中希望窗口提示敌方坦克的数量,因此,需要在现有窗口进行必须的改进,添加敌方坦克数量提示。

# 文字显示 def getTextSuface(self, text):     pygame.font.init()  # 字体初始化     font = pygame.font.SysFont('kaiti', 16)     # 绘制文字信息     textSurface = font.render(text, True, TEXT_COLOR)     return textSurface 

在这里插入图片描述

2.2 加载我方坦克

通过加载一张图片来表示游戏中的坦克,此坦克代表我方坦克,完善坦克类。

class Tank():     # 添加距离左边left 距离上边top     def __init__(self, left, top):         # 保存加载的图片         self.images = {             'U': pygame.image.load('img/p1tankU.gif'),             'D': pygame.image.load('img/p1tankD.gif'),             'L': pygame.image.load('img/p1tankL.gif'),             'R': pygame.image.load('img/p1tankR.gif'),         }         # 方向         self.direction = 'L'         # 根据当前图片的方向获取图片 surface         self.image = self.images[self.direction]         # 根据图片获取区域         self.rect = self.image.get_rect()         # 设置区域的left 和top         self.rect.left = left         self.rect.top = top 

在这里插入图片描述
添加事件监听

上面创建的坦克还不能动,显示不是创建游戏的目的,因此,要给创建的坦克赋予“生命”。添加事件监听,控制上、下、左、右四个方向键,实现针对不同的键改变坦克的方向及移动功能,点击关闭退出游戏。

实现退出方法:

# 结束游戏     def endGame(self):         print('游戏结束')         exit()  # 退出游戏 

坦克类中添加移动开关属性,按下上、下、左、右四个方向键修改坦克的方向及开关状态,按下关闭键,调用关闭方法退出游戏。

# 获取程序期间所有事件(鼠标事件,键盘事件)     def getEvent(self):         # 获取所有事件         eventList = pygame.event.get()         # 遍历事件         for event in eventList:             # 判断按下的键是关闭还是键盘按下             # 如果按的是退出,关闭窗口             if event.type == pygame.QUIT:                 self.endGame()             # 如果是键盘的按下             if event.type == pygame.KEYDOWN:                 # 判断按下的是上、下、左、右                 if event.key == pygame.K_LEFT:                     print('按下左键,坦克向左移动')                 elif event.key == pygame.K_RIGHT:                     print('按下右键,坦克向右移动')                 elif event.key == pygame.K_UP:                     print('按下上键,坦克向上移动')                 elif event.key == pygame.K_DOWN:                     print('按下左键,坦克向下移动') 

在这里插入图片描述
按下上、下、左、右之后控制台上会打印对应的信息。

随机生成敌方坦克

初始化敌方坦克,随机在不同坐标生成敌方坦克。

# 敌方坦克 class EnemyTank(Tank):     def __init__(self, left, top, speed):         super(EnemyTank, self).__init__(left, top)         # 加载图片集         self.images = {             'U': pygame.image.load('img/enemy1U.gif'),             'D': pygame.image.load('img/enemy1D.gif'),             'L': pygame.image.load('img/enemy1L.gif'),             'R': pygame.image.load('img/enemy1R.gif'),         }         # 随机生成方向         self.direction = self.randDirection()         self.image = self.images[self.direction]  # 根据方向获取图片         self.rect = self.image.get_rect()  # 获取区域         self.rect.left, self.rect.top = left, top  # 对left和top赋值         self.speed = speed  # 速度         self.flag = True  # 坦克移动开关         self.step = 50  # 敌方坦克步数 
2.3 加载敌方坦克

MainGame类中创建敌方坦克:

    def createEnemyTank(self):  # 初始化敌方坦克, 将敌方坦克添加到列表中         top = 100         for i in range(self.enemyTankCount):  # 生成指定敌方坦克数量             left = random.randint(0, 600)             speed = random.randint(1, 4)             enemy = EnemyTank(left, top, speed)             MainGame.enemyTankList.append(enemy) 

在敌方坦克类中实现敌方坦克的随机移动

    def randMove(self):  # 坦克的随机方向移动         if self.step < 0:  # 步数小于0, 随机改变方向             self.direction = self.randDirection()             self.step = 50  # 步数复位         else:             self.move()             self.step -= 1 

在开始游戏方法,加载敌方坦克

self.creatEnemyTank() 

在这里插入图片描述
我方坦克发射子弹
在子弹类中初始化子弹,每个子弹在不同的方向发射会有不同的运动轨迹,每个子弹在坦克方向上的不同子弹发射的坐标也会有所不同。需要计算四个不同方向上的子弹发射坐标。

    def __init__(self, tank):         self.image = pygame.image.load('img/enemymissile.gif')  # 图片加载         self.direction = tank.direction  # 子弹的方向         self.rect = self.image.get_rect()  # 获取区域         if self.direction == 'U':  # 子弹的left和top与方向有关             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top - self.rect.height         elif self.direction == 'D':             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top + tank.rect.height         elif self.direction == 'L':             self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2         elif self.direction == 'R':             self.rect.left = tank.rect.left + tank.rect.width             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2         self.speed = 5   # 子弹的速度         self.live = True  # 子弹的状态 

敌方坦克随机发射子弹

def shot(self): 	num = random.randint(1,1000) 	if num <= 20: 		return Bullet(self) 

我方法子弹与敌方坦克的碰撞检测
在游戏开发中,通常把显示图像的对象叫做精灵 Spire,精灵需要有两个属性 image 要
显示的图像,rect 图像要显示在屏幕的位置。
在 Pygame 框架中,使用 pygame. sprite 模块中的内置函数可以实现碰撞检测。代码如
下:

pygame.sprite.collide_rect(first, second) #返回布尔值 

pygame.sprite.Sprite 是 pygame 精灵的基类,一般来说,总是需要写一个自己的精灵类继承 pygame.sprite.Sprite。让坦克类、子弹类都继承编写的精灵类。
在子弹类中增加我方子弹碰撞敌方坦克的方法,如果发生碰撞,修改我方子弹及敌方坦克 live 属性的状态值。

#新增我方子弹碰撞敌方坦克的方法 def hitEnemyTank(self): 	for eTank in MainGame.EnemyTank_list: 		if pygame.sprite.collide_rect(eTank,self): 			self.live = False 			eTank.live = False 
2.4 添加爆炸效果

在我方子弹碰撞敌方坦克的方法中,如果检测到碰撞,产生爆炸类,并将爆炸效果添加到爆炸列表。

#新增我方子弹碰撞敌方坦克的方法 def hitEnemyTank(self): 	for eTank in MainGame.EnemyTank_list: 		if pygame.sprite.collide_rect(eTank,self): 			#产生一个爆炸效果 			explode = Explode(eTank) 			#将爆炸效果加入到爆炸效果列表 			MainGame.Explode_list.append(explode) 			self.live = False 			eTank.live = False 

我方坦克的消亡
子弹类中,新增敌方子弹与我方坦克的碰撞。如果发生碰撞,修改敌方子弹、我方坦克的状态及产生爆炸效果。
添加敌方子弹到窗口中时候,如果子弹还活着,显示子弹、调用子弹移动并判断敌方子弹是否与我方坦克发生碰撞。

    def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示         for enemyBullet in MainGame.enemyBulletList:             if enemyBullet.live:                 enemyBullet.displayBullet()                 enemyBullet.move()                 enemyBullet.enemyBullet_hit_myTank()                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞             else:                 MainGame.enemyBulletList.remove(enemyBullet) 

子弹不能穿墙
子弹类中新增方法,子弹与墙壁的碰撞,如果子弹与墙壁碰撞,修改子弹的状态,墙壁的生命值减少,如果墙壁的生命值小于等于零时候修改墙壁的状态。

坦克不能穿墙
如果坦克与墙壁碰撞,则坦克不能继续移动,需要修改坦克的坐标为移动之前的。因此在坦克类中新增属性 oldLeft、oldTop 记录移动之前的坐标,新增 stay()、hitWalls()方法。

    def hitWall(self):         for wall in MainGame.WallList:  # 循环遍历墙壁列表             if pygame.sprite.collide_rect(self, wall):  # 检测子弹是否碰撞墙壁                 self.live = False  # 修改子弹状态                 wall.hp -= 1  # 碰撞后墙壁生命值减少                 if wall.hp <= 0:                     wall.live = False 

双方坦克之间的碰撞检测
如果我方坦克碰撞到敌方坦克,则我方坦克再不能继续移动。同理如果敌方坦克碰撞到
我方坦克也不能继续移动。
在我方坦克类中新增我方坦克与敌方坦克碰撞的方法。

class MyTank(Tank):     def __init__(self, left, top):         super(MyTank, self).__init__(left, top)      def myTank_hit_enemyTank(self):         for enemyTank in MainGame.enemyTankList:             if pygame.sprite.collide_rect(self, enemyTank):                 self.stay() 

我方坦克移动后,调用是否与敌方坦克发生碰撞。在敌方坦克类中,新增敌方坦克碰撞我方坦克的方法。敌方坦克添加到窗口时候,调用是否与我方坦克碰撞。

    def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示         for enemyBullet in MainGame.enemyBulletList:             if enemyBullet.live:                 enemyBullet.displayBullet()                 enemyBullet.move()                 enemyBullet.enemyBullet_hit_myTank()                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞             else:                 MainGame.enemyBulletList.remove(enemyBullet) 
2.5 坦克大战之音效处理

music 是 pygame 中控制流音频的 pygame 模块,音乐模块与 pygame.mixer 紧密相连,pygame.mixer 是一个用来处理声音的模块,其含义为“混音器”。游戏中对声音的处理一般包括制造声音和播放声音两部分。使用 pygame.mixer.music.load()加载一个播放音乐的文件,pygame.mixer.music.play() 开始播放音乐流。

初始化音效类

class Music():     def __init__(self, filename):         self.filename = filename         pygame.mixer.init()         pygame.mixer.music.load(self.filename)  # 加载音乐     # 音乐播放     def play(self):         pygame.mixer.music.play() 
music.play() 

创建坦克时,添加音效和在我方坦克发射子弹时,添加音效。

三、完整代码

注意因为代码过长,且含音频和图片,不方便复制,可使用下方码云链接直接下载就好啦
https://gitee.com/bow-elongation/tank-battle.git
在这里插入图片描述
在这里插入图片描述

# 导入模块 import pygame, time, random from pygame.sprite import Sprite SCREEN_WIDTH = 800  # 宽度 SCREEN_HEIGHT = 500  # 高度 BG_COLOR = pygame.Color(0, 0, 0)  # 颜色 TEXT_COLOR = pygame.Color(255, 0, 0)  # 字体颜色   class Baseitem(Sprite):     def __init__(self, color, width, height):         pygame.sprite.Sprite.__init__(self)  # 坦克类 class MainGame():     window = None     my_tank = None     enemyTankList = []  # 敌方坦克列表     enemyTankCount = 5  # 敌方坦克数量     myBulletList = []  # 我方坦克子弹列表     enemyBulletList = []  # 敌方坦克子弹列表     explodeList = []  # 爆炸效果列表     WallList = []  # 墙壁列表      def __init__(self):         pass      # 开始游戏     def startGame(self):         pygame.display.init()  # 加载主窗口         MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])  # 设置窗口大小并显示         self.createMytank()         self.createEnemyTank()  # 初始化敌方坦克         self.createWall()  # 初始化墙壁         # 窗口标题设置         pygame.display.set_caption('坦克大战')         while True:             time.sleep(0.02)             # 颜色填充             MainGame.window.fill(BG_COLOR)             # 获取事件             self.getEvent()             # 绘制文字             MainGame.window.blit(self.getTextSuface('敌方坦克剩余数量%d' % len(MainGame.enemyTankList)), (10, 10))             if MainGame.my_tank and MainGame.my_tank.live:                 MainGame.my_tank.displayTank()  # 展示我方坦克             else:                 del MainGame.my_tank  # 删除我方坦克                 MainGame.my_tank = None             self.blitEnemyTank()  # 展示敌方坦克             self.blitMyBullet()  # 我方坦克子弹             self.blitEnemyBullet()  # 展示敌方子弹             self.blitExplode()  # 爆炸效果展示             self.blitWall()  # 展示墙壁             if MainGame.my_tank and MainGame.my_tank.live:                 if not MainGame.my_tank.stop:                     MainGame.my_tank.move()  # 调用坦克移动方法                     MainGame.my_tank.hitWall()                     MainGame.my_tank.myTank_hit_enemyTank()             pygame.display.update()      def blitWall(self):         for wall in MainGame.WallList:             if wall.live:                 wall.displayWall()             else:                 MainGame.WallList.remove(wall)      def createWall(self):  # 初始化墙壁         for i in range(6):             wall = Wall(i * 145, 220)             MainGame.WallList.append(wall)      def createMytank(self):  # 初始化我方坦克         MainGame.my_tank = MyTank(350, 300)         music = Music('img/start.wav')  # 创建音乐对象         music.play()  # 播放音乐      def createEnemyTank(self):  # 初始化敌方坦克, 将敌方坦克添加到列表中         top = 100         for i in range(self.enemyTankCount):  # 生成指定敌方坦克数量             left = random.randint(0, 600)             speed = random.randint(1, 4)             enemy = EnemyTank(left, top, speed)             MainGame.enemyTankList.append(enemy)      def blitEnemyTank(self):         for enemyTank in MainGame.enemyTankList:             if enemyTank.live:  # 判断敌方坦克状态                 enemyTank.displayTank()                 enemyTank.randMove()  # 调用子弹移动                 enemyTank.hitWall()                 if MainGame.my_tank and MainGame.my_tank.live:                     enemyTank.enemyTank_hit_myTank()                 enemyBullet = enemyTank.shot()  # 敌方坦克射击                 if enemyBullet:  # 判断敌方坦克子弹是否为None                     MainGame.enemyBulletList.append(enemyBullet)  # 存储敌方坦克子弹             else:                 MainGame.enemyTankList.remove(enemyTank)      def blitExplode(self):         for expolde in MainGame.explodeList:             if expolde.live:                 expolde.displayExplode()             else:                 MainGame.explodeList.remove(expolde)      def blitMyBullet(self):  # 循环我方子弹列表, 并展示         for myBullet in MainGame.myBulletList:             if myBullet.live:  # 判断子弹的状态                 myBullet.displayBullet()                 myBullet.move()                 myBullet.myBullet_hit_enemyTank()                 myBullet.hitWall()  # 检测我方坦克子弹是否碰撞             else:                 MainGame.myBulletList.remove(myBullet)      def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示         for enemyBullet in MainGame.enemyBulletList:             if enemyBullet.live:                 enemyBullet.displayBullet()                 enemyBullet.move()                 enemyBullet.enemyBullet_hit_myTank()                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞             else:                 MainGame.enemyBulletList.remove(enemyBullet)      # 结束游戏     def endGame(self):         print('游戏结束')         exit()  # 退出游戏      # 文字显示     def getTextSuface(self, text):         pygame.font.init()  # 字体初始化         font = pygame.font.SysFont('kaiti', 16)         # 绘制文字信息         textSurface = font.render(text, True, TEXT_COLOR)         return textSurface      # 事件获取     def getEvent(self):         # 获取所有事件         for event in pygame.event.get():             if event.type == pygame.QUIT:                 # 退出游戏                 self.endGame()             # 键盘按键             if event.type == pygame.KEYDOWN:                 if not MainGame.my_tank:  # 当我方坦克不存在时, 按下Esc键重生                     if event.key == pygame.K_ESCAPE:                         self.createMytank()                 if MainGame.my_tank and MainGame.my_tank.live:                     # 上、下、左、右键的判断                     if event.key == pygame.K_LEFT:                         MainGame.my_tank.direction = 'L'                         MainGame.my_tank.stop = False                         print('左键, 坦克向左移动')                     elif event.key == pygame.K_RIGHT:                         MainGame.my_tank.direction = 'R'                         MainGame.my_tank.stop = False                         print('右键, 坦克向右移动')                     elif event.key == pygame.K_UP:                         MainGame.my_tank.direction = 'U'                         MainGame.my_tank.stop = False                         print('上键, 坦克向上移动')                     elif event.key == pygame.K_DOWN:                         MainGame.my_tank.direction = 'D'                         MainGame.my_tank.stop = False                         print('下键, 坦克向下移动')                     elif event.key == pygame.K_SPACE:                         print('发射子弹')                         if len(MainGame.myBulletList) < 3:  # 可以同时发射子弹数量的上限                             myBullet = Bullet(MainGame.my_tank)                             MainGame.myBulletList.append(myBullet)                             music = Music('img/fire.wav')                             music.play()             # 松开键盘, 坦克停止移动             if event.type == pygame.KEYUP:                 # 只有松开上、下、左、右键时坦克才停止, 松开空格键坦克不停止                 if event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:                     if MainGame.my_tank and MainGame.my_tank.live:                         MainGame.my_tank.stop = True   # 坦克类 class Tank(Baseitem):     def __init__(self, left, top):         # 保存加载的图片         self.images = {             'U': pygame.image.load('img/p1tankU.gif'),             'D': pygame.image.load('img/p1tankD.gif'),             'L': pygame.image.load('img/p1tankL.gif'),             'R': pygame.image.load('img/p1tankR.gif'),         }         self.direction = 'L'  # 方向         self.image = self.images[self.direction]  # 根据图片方向获取图片         self.rect = self.image.get_rect()  # 根据图片获取区域         self.rect.left, self.rect.top = left, top         self.speed = 5  # 移动速度         self.stop = True  # 坦克移动开关         self.live = True         self.OldLeft = self.rect.left         self.OldTop = self.rect.top      # 移动     def move(self):         self.OldLeft = self.rect.left         self.OldTop = self.rect.top         # 判断坦克方向进行移动         if self.direction == 'L':             if self.rect.left > 0:                 self.rect.left -= self.speed         elif self.direction == 'U':             if self.rect.top > 0:                 self.rect.top -= self.speed         elif self.direction == 'D':             if self.rect.top + self.rect.height < SCREEN_HEIGHT:                 self.rect.top += self.speed         elif self.direction == 'R':             if self.rect.left + self.rect.height < SCREEN_WIDTH:                 self.rect.left += self.speed      # 射击     def shot(self):         return Bullet(self)      def stay(self):         self.rect.left = self.OldLeft         self.rect.top = self.OldTop      def hitWall(self):         for wall in MainGame.WallList:             if pygame.sprite.collide_rect(self, wall):                 self.stay()      # 展示坦克的方法     def displayTank(self):         # 获取展示对象         self.image = self.images[self.direction]         # 调用blit展示         MainGame.window.blit(self.image, self.rect)   # 我方坦克 class MyTank(Tank):     def __init__(self, left, top):         super(MyTank, self).__init__(left, top)      def myTank_hit_enemyTank(self):         for enemyTank in MainGame.enemyTankList:             if pygame.sprite.collide_rect(self, enemyTank):                 self.stay()   # 敌方坦克 class EnemyTank(Tank):     def __init__(self, left, top, speed):         super(EnemyTank, self).__init__(left, top)         # 加载图片集         self.images = {             'U': pygame.image.load('img/enemy1U.gif'),             'D': pygame.image.load('img/enemy1D.gif'),             'L': pygame.image.load('img/enemy1L.gif'),             'R': pygame.image.load('img/enemy1R.gif'),         }         # 随机生成方向         self.direction = self.randDirection()         self.image = self.images[self.direction]  # 根据方向获取图片         self.rect = self.image.get_rect()  # 获取区域         self.rect.left, self.rect.top = left, top  # 对left和top赋值         self.speed = speed  # 速度         self.flag = True  # 坦克移动开关         self.step = 50  # 敌方坦克步数      def enemyTank_hit_myTank(self):         if pygame.sprite.collide_rect(self, MainGame.my_tank):             self.stay()      def randDirection(self):         nums = random.randint(1, 4)  # 生成1~4的随机整数         if nums == 1:             return "U"         elif nums == 2:             return "D"         elif nums == 3:             return "L"         elif nums == 4:             return "R"      def randMove(self):  # 坦克的随机方向移动         if self.step < 0:  # 步数小于0, 随机改变方向             self.direction = self.randDirection()             self.step = 50  # 步数复位         else:             self.move()             self.step -= 1      def shot(self):  # 重写shot方法         num = random.randint(1, 100)         if num < 10:             return Bullet(self)   # 子弹类 class Bullet(Baseitem):     def __init__(self, tank):         self.image = pygame.image.load('img/enemymissile.gif')  # 图片加载         self.direction = tank.direction  # 子弹的方向         self.rect = self.image.get_rect()  # 获取区域         if self.direction == 'U':  # 子弹的left和top与方向有关             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top - self.rect.height         elif self.direction == 'D':             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top + tank.rect.height         elif self.direction == 'L':             self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2         elif self.direction == 'R':             self.rect.left = tank.rect.left + tank.rect.width             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2         self.speed = 5   # 子弹的速度         self.live = True  # 子弹的状态      # 移动     def move(self):         if self.direction == 'U':             if self.rect.top > 0:                 self.rect.top -= self.speed             else:                 self.live = False  # 修改子弹的状态         elif self.direction == 'R':             if self.rect.left + self.rect.width < SCREEN_WIDTH:                 self.rect.left += self.speed             else:                 self.live = False  # 修改子弹的状态         elif self.direction == 'D':             if self.rect.top + self.rect.height < SCREEN_HEIGHT:                 self.rect.top += self.speed             else:                 self.live = False  # 修改子弹的状态         elif self.direction == 'L':             if self.rect.left > 0:                 self.rect.left -= self.speed             else:                 self.live = False  # 修改子弹的状态      def hitWall(self):         for wall in MainGame.WallList:  # 循环遍历墙壁列表             if pygame.sprite.collide_rect(self, wall):  # 检测子弹是否碰撞墙壁                 self.live = False  # 修改子弹状态                 wall.hp -= 1  # 碰撞后墙壁生命值减少                 if wall.hp <= 0:                     wall.live = False      # 子弹展示     def displayBullet(self):         # 将图片加载到窗口         MainGame.window.blit(self.image, self.rect)      def myBullet_hit_enemyTank(self):         for enemyTank in MainGame.enemyTankList:             if pygame.sprite.collide_rect(enemyTank, self):                 enemyTank.live = False                 self.live = False                 explode = Explode(enemyTank)                 MainGame.explodeList.append(explode)      def enemyBullet_hit_myTank(self):         if MainGame.my_tank and MainGame.my_tank.live:             if pygame.sprite.collide_rect(MainGame.my_tank, self):                 explode = Explode(MainGame.my_tank)  # 爆炸对象                 MainGame.explodeList.append(explode)  # 将爆炸对象添加到爆炸列表中                 self.live = False  # 修改敌方子弹的状态                 MainGame.my_tank.live = False  # 我方坦克的状态   # 墙壁类 class Wall():     def __init__(self, left, top):         self.image = pygame.image.load('img/steels.gif')  # 加载墙壁图片         self.rect = self.image.get_rect()  # 获取区域         self.rect.left, self.rect.top = left, top  # 设置left, top         self.live = True  # 存活状态         self.hp = 3  # 设置墙壁生命值      # 展示墙壁     def displayWall(self):         MainGame.window.blit(self.image, self.rect)   # 爆炸类 class Explode():     def __init__(self, tank):         self.rect = tank.rect         self.images = [             pygame.image.load('img/blast0.gif'),             pygame.image.load('img/blast1.gif'),             pygame.image.load('img/blast2.gif'),             pygame.image.load('img/blast3.gif'),             pygame.image.load('img/blast4.gif'),         ]         self.step = 0         self.image = self.images[self.step]         self.live = True      # 爆炸效果     def displayExplode(self):         if self.step < len(self.images):             self.image = self.images[self.step]             self.step += 1             MainGame.window.blit(self.image, self.rect)  # 添加到主窗口         else:             self.live = False             self.step = 0   # 音效类 class Music():     def __init__(self, filename):         self.filename = filename         pygame.mixer.init()         pygame.mixer.music.load(self.filename)  # 加载音乐      # 音乐播放     def play(self):         pygame.mixer.music.play()   if __name__ == '__main__':     MainGame().startGame() 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!