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

[复制链接]
发表于 2026-2-14 22:09:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、游戏运行效果

二、代码实现

坦克大战游戏

2.1 项目搭建

本游戏主要有两个对象:我方坦克和敌方坦克。玩家通过控制我方坦克摧毁敌方坦克、保护自己的"家",消灭所有敌方坦克即获胜;若我方坦克被敌方子弹击中则游戏结束。从面向对象角度分析,项目由以下类构成:




  • 主类:包含开始游戏、结束游戏功能。

  1. class MainGame():
  2.     def __init__(self):
  3.         pass
  4.     # 开始游戏
  5.     def startGame(self):
  6.         pass
  7.     # 结束游戏
  8.     def endGame(self):
  9.         pass
复制代码


  • 坦克类:包含坦克的创建、显示、移动及射击功能。

  1. class Tank():
  2.     def __init__(self):
  3.         pass
  4.     # 移动
  5.     def move(self):
  6.         pass
  7.     # 射击
  8.     def shot(self):
  9.         pass
  10.     # 展示坦克
  11.     def displayTank(self):
  12.         pass
复制代码


  • 我方坦克类继承坦克类,包含创建、与敌方坦克碰撞的方法。

  1. # 我方坦克
  2. class MyTank(Tank):
  3.     def __init__(self):
  4.         pass
复制代码


  • 敌方坦克类继承坦克类,包含创建、与我方坦克碰撞的方法。

  1. # 敌方坦克
  2. class EnemyTank(Tank):
  3.     def __init__(self):
  4.         pass
复制代码


  • 子弹类:包含子弹的创建、显示及移动功能。

  1. # 子弹类
  2. class Bullet():
  3.     def __init__(self):
  4.         pass
  5.     # 移动
  6.     def move(self):
  7.         pass
  8.     # 展示子弹
  9.     def displayBullet(self):
  10.         pass
复制代码


  • 墙壁类:包含墙壁的创建与显示功能。

  1. class Wall():
  2.     def __init__(self):
  3.         pass
  4.     # 展示果类:重要展示爆炸效果。
  5. [/list] [code]class Explode():
  6.     def __init__(self):
  7.         pass
  8.     # 展示爆炸效果的方法
  9.     def displayExplode(self):
  10.         pass
复制代码


  • 音效类:重要播放音乐。
  1. class Music():
  2.     def __init__(self):
  3.         pass
  4.     # 播放音乐
  5.     def play(self):
  6.         pass
复制代码
体现游戏窗口
在游戏设计的前期,要先创建游戏的界面,也就是要为所设计的游戏创建一个窗口。
【示例】:体现游戏窗口
  1. def startGame(self):
  2.     # 加载主窗口
  3.     # 初始化窗口
  4.     pygame.display.init()
  5.     # 设置窗口的大小及显示
  6.     MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
  7.     # 设置窗口的标题
  8.     pygame.display.set_caption('坦克大战1.03')
  9.     while True:
  10.         # 给窗口设置填充色
  11.         MainGame.window.fill(BG_COLOR)
  12.         pygame.display.update()
  13. MainGame().startGame()
复制代码
运行效果:

添加提示笔墨
在运行代码时会发现,创建的窗口没有任何提示。然而在现实中渴望窗口提示敌方坦克的数目,因此,需要在现有窗口进行必须的改进,添加敌方坦克数目提示。
  1. # 文字显示
  2. def getTextSuface(self, text):
  3.     pygame.font.init()  # 字体初始化
  4.     font = pygame.font.SysFont('kaiti', 16)
  5.     # 绘制文字信息
  6.     textSurface = font.render(text, True, TEXT_COLOR)
  7.     return textSurface
复制代码

2.2 加载我方坦克

通过加载一张图片来体现游戏中的坦克,此坦克代表我方坦克,美满坦克类。
  1. class Tank():
  2.     # 添加距离左边left 距离上边top
  3.     def __init__(self, left, top):
  4.         # 保存加载的图片
  5.         self.images = {
  6.             'U': pygame.image.load('img/p1tankU.gif'),
  7.             'D': pygame.image.load('img/p1tankD.gif'),
  8.             'L': pygame.image.load('img/p1tankL.gif'),
  9.             'R': pygame.image.load('img/p1tankR.gif'),
  10.         }
  11.         # 方向
  12.         self.direction = 'L'
  13.         # 根据当前图片的方向获取图片 surface
  14.         self.image = self.images[self.direction]
  15.         # 根据图片获取区域
  16.         self.rect = self.image.get_rect()
  17.         # 设置区域的left 和top
  18.         self.rect.left = left
  19.         self.rect.top = top
复制代码

添加事件监听
上面创建的坦克还不能动,体现不是创建游戏的目标,因此,要给创建的坦克赋予“生命”。添加事件监听,控制上、下、左、右四个方向键,实现针对差别的键改变坦克的方向及移动功能,点击关闭退出游戏。
实现退出方法:
  1. # 结束游戏
  2.     def endGame(self):
  3.         print('游戏结束')
  4.         exit()  # 退出游戏
复制代码
坦克类中添加移动开关属性,按下上、下、左、右四个方向键修改坦克的方向及开关状态,按下关闭键,调用关闭方法退出游戏。
  1. # 获取程序期间所有事件(鼠标事件,键盘事件)
  2.     def getEvent(self):
  3.         # 获取所有事件
  4.         eventList = pygame.event.get()
  5.         # 遍历事件
  6.         for event in eventList:
  7.             # 判断按下的键是关闭还是键盘按下
  8.             # 如果按的是退出,关闭窗口
  9.             if event.type == pygame.QUIT:
  10.                 self.endGame()
  11.             # 如果是键盘的按下
  12.             if event.type == pygame.KEYDOWN:
  13.                 # 判断按下的是上、下、左、右
  14.                 if event.key == pygame.K_LEFT:
  15.                     print('按下左键,坦克向左移动')
  16.                 elif event.key == pygame.K_RIGHT:
  17.                     print('按下右键,坦克向右移动')
  18.                 elif event.key == pygame.K_UP:
  19.                     print('按下上键,坦克向上移动')
  20.                 elif event.key == pygame.K_DOWN:
  21.                     print('按下左键,坦克向下移动')
复制代码

按下上、下、左、右之后控制台上会打印对应的信息。
随机天生敌方坦克
初始化敌方坦克,随机在差别坐标天生敌方坦克。
  1. # 敌方坦克
  2. class EnemyTank(Tank):
  3.     def __init__(self, left, top, speed):
  4.         super(EnemyTank, self).__init__(left, top)
  5.         # 加载图片集
  6.         self.images = {
  7.             'U': pygame.image.load('img/enemy1U.gif'),
  8.             'D': pygame.image.load('img/enemy1D.gif'),
  9.             'L': pygame.image.load('img/enemy1L.gif'),
  10.             'R': pygame.image.load('img/enemy1R.gif'),
  11.         }
  12.         # 随机生成方向
  13.         self.direction = self.randDirection()
  14.         self.image = self.images[self.direction]  # 根据方向获取图片
  15.         self.rect = self.image.get_rect()  # 获取区域
  16.         self.rect.left, self.rect.top = left, top  # 对left和top赋值
  17.         self.speed = speed  # 速度
  18.         self.flag = True  # 坦克移动开关
  19.         self.step = 50  # 敌方坦克步数
复制代码
2.3 加载敌方坦克

在MainGame类中创建敌方坦克:
  1.     def createEnemyTank(self):  # 初始化敌方坦克, 将敌方坦克添加到列表中
  2.         top = 100
  3.         for i in range(self.enemyTankCount):  # 生成指定敌方坦克数量
  4.             left = random.randint(0, 600)
  5.             speed = random.randint(1, 4)
  6.             enemy = EnemyTank(left, top, speed)
  7.             MainGame.enemyTankList.append(enemy)
复制代码
在敌方坦克类中实现敌方坦克的随机移动
  1.     def randMove(self):  # 坦克的随机方向移动
  2.         if self.step < 0:  # 步数小于0, 随机改变方向
  3.             self.direction = self.randDirection()
  4.             self.step = 50  # 步数复位
  5.         else:
  6.             self.move()
  7.             self.step -= 1
复制代码
在开始游戏方法,加载敌方坦克
  1. self.creatEnemyTank()
复制代码

我方坦克发射子弹
在子弹类中初始化子弹,每个子弹在差别的方向发射会有差别的活动轨迹,每个子弹在坦克方向上的差别子弹发射的坐标也会有所差别。需要计算四个差别方向上的子弹发射坐标。
  1.     def __init__(self, tank):
  2.         self.image = pygame.image.load('img/enemymissile.gif')  # 图片加载
  3.         self.direction = tank.direction  # 子弹的方向
  4.         self.rect = self.image.get_rect()  # 获取区域
  5.         if self.direction == 'U':  # 子弹的left和top与方向有关
  6.             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  7.             self.rect.top = tank.rect.top - self.rect.height
  8.         elif self.direction == 'D':
  9.             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  10.             self.rect.top = tank.rect.top + tank.rect.height
  11.         elif self.direction == 'L':
  12.             self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2
  13.             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  14.         elif self.direction == 'R':
  15.             self.rect.left = tank.rect.left + tank.rect.width
  16.             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  17.         self.speed = 5   # 子弹的速度
  18.         self.live = True  # 子弹的状态
复制代码
敌方坦克随机发射子弹
  1. def shot(self):
  2.         num = random.randint(1,1000)
  3.         if num <= 20:
  4.                 return Bullet(self)
复制代码
我方法子弹与敌方坦克的碰撞检测
在游戏开发中,通常把体现图像的对象叫做精灵 Spire,精灵需要有两个属性 image 要
体现的图像,rect 图像要表如今屏幕的位置。
在 Pygame 框架中,使用 pygame. sprite 模块中的内置函数可以实现碰撞检测。代码如
下:
  1. pygame.sprite.collide_rect(first, second) #返回布尔值
复制代码
pygame.sprite.Sprite 是 pygame 精灵的基类,一样平常来说,总是需要写一个本身的精灵类继承 pygame.sprite.Sprite。让坦克类、子弹类都继承编写的精灵类。
在子弹类中增加我方子弹碰撞敌方坦克的方法,假如发生碰撞,修改我方子弹及敌方坦克 live 属性的状态值。
  1. #新增我方子弹碰撞敌方坦克的方法
  2. def hitEnemyTank(self):
  3.         for eTank in MainGame.EnemyTank_list:
  4.                 if pygame.sprite.collide_rect(eTank,self):
  5.                         self.live = False
  6.                         eTank.live = False
复制代码
2.4 添加爆炸效果

在我方子弹碰撞敌方坦克的方法中,假如检测到碰撞,产生爆炸类,并将爆炸效果添加到爆炸列表。
  1. #新增我方子弹碰撞敌方坦克的方法
  2. def hitEnemyTank(self):
  3.         for eTank in MainGame.EnemyTank_list:
  4.                 if pygame.sprite.collide_rect(eTank,self):
  5.                         #产生一个爆炸效果
  6.                         explode = Explode(eTank)
  7.                         #将爆炸效果加入到爆炸效果列表
  8.                         MainGame.Explode_list.append(explode)
  9.                         self.live = False
  10.                         eTank.live = False
复制代码
我方坦克的死亡
子弹类中,新增敌方子弹与我方坦克的碰撞。假如发生碰撞,修改敌方子弹、我方坦克的状态及产生爆炸效果。
添加敌方子弹到窗口中时间,假如子弹还在世,体现子弹、调用子弹移动并判断敌方子弹是否与我方�����克发生碰撞。
  1.     def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示
  2.         for enemyBullet in MainGame.enemyBulletList:
  3.             if enemyBullet.live:
  4.                 enemyBullet.displayBullet()
  5.                 enemyBullet.move()
  6.                 enemyBullet.enemyBullet_hit_myTank()
  7.                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞
  8.             else:
  9.                 MainGame.enemyBulletList.remove(enemyBullet)
复制代码
子弹不能穿墙
子弹类中新增方法,子弹与墙壁的碰撞,假如子弹与墙壁碰撞,修改子弹的状态,墙壁的生命值减少,假如墙壁的生命值小于即是零时间修改墙壁的状态。
坦克不能穿墙
假如坦克与墙壁碰撞,则坦克不能继承移动,需要修改坦克的坐标为移动之前的。因此在坦克类中新增属性 oldLeft、oldTop 记录移动之前的坐标,新增 stay()、hitWalls()方法。
  1.     def hitWall(self):
  2.         for wall in MainGame.WallList:  # 循环遍历墙壁列表
  3.             if pygame.sprite.collide_rect(self, wall):  # 检测子弹是否碰撞墙壁
  4.                 self.live = False  # 修改子弹状态
  5.                 wall.hp -= 1  # 碰撞后墙壁生命值减少
  6.                 if wall.hp <= 0:
  7.                     wall.live = False
复制代码
双方坦克之间的碰撞检测
假如我方坦克碰撞到敌方坦克,则我方坦克再不能继承移动。同理假如敌方坦克碰撞到
我方坦克也不能继承移动。
在我方坦克类中新增我方坦克与敌方坦克碰撞的方法。
  1. class MyTank(Tank):
  2.     def __init__(self, left, top):
  3.         super(MyTank, self).__init__(left, top)
  4.     def myTank_hit_enemyTank(self):
  5.         for enemyTank in MainGame.enemyTankList:
  6.             if pygame.sprite.collide_rect(self, enemyTank):
  7.                 self.stay()
复制代码
我方坦克移动后,调用是否与敌方坦克发生碰撞。在敌方坦克类中,新增敌方坦克碰撞我方坦克的方法。敌方坦克添加到窗口时间,调用是否与我方坦克碰撞。
  1.     def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示
  2.         for enemyBullet in MainGame.enemyBulletList:
  3.             if enemyBullet.live:
  4.                 enemyBullet.displayBullet()
  5.                 enemyBullet.move()
  6.                 enemyBullet.enemyBullet_hit_myTank()
  7.                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞
  8.             else:
  9.                 MainGame.enemyBulletList.remove(enemyBullet)
复制代码
2.5 坦克大战之音效处理

music 是 pygame 中控制流音频的 pygame 模块,音乐模块与 pygame.mixer 精密相连,pygame.mixer 是一个用来处理声音的模块,其寄义为“混音器”。游戏中对声音的处理一样平常包括制造声音和播放声音两部门。使用 pygame.mixer.music.load()加载一个播放音乐的文件,pygame.mixer.music.play()
开始播放音乐流。
初始化音效类
  1. class Music():
  2.     def __init__(self, filename):
  3.         self.filename = filename
  4.         pygame.mixer.init()
  5.         pygame.mixer.music.load(self.filename)  # 加载音乐
  6.     # 音乐播放
  7.     def play(self):
  8.         pygame.mixer.music.play()
复制代码
  1. music.play()
复制代码
创建坦克时,添加音效和在我方坦克发射子弹时,添加音效。
三、完整代码

留意:由于代码过长,且含音频和图片,不方便复制,可使用下方码云链接直接下载就好啦
https://gitee.com/bow-elongation/tank-battle.git


  1. # 导入模块import pygame, time, randomfrom pygame.sprite import SpriteSCREEN_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()
  2.   # 播放音乐    def createEnemyTank(self):  # 初始化敌方坦克, 将敌方坦克添加到列表中
  3.         top = 100
  4.         for i in range(self.enemyTankCount):  # 生成指定敌方坦克数量
  5.             left = random.randint(0, 600)
  6.             speed = random.randint(1, 4)
  7.             enemy = EnemyTank(left, top, speed)
  8.             MainGame.enemyTankList.append(enemy)
  9.     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):  # 循环敌方子弹列表, 并展示
  10.         for enemyBullet in MainGame.enemyBulletList:
  11.             if enemyBullet.live:
  12.                 enemyBullet.displayBullet()
  13.                 enemyBullet.move()
  14.                 enemyBullet.enemyBullet_hit_myTank()
  15.                 enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞
  16.             else:
  17.                 MainGame.enemyBulletList.remove(enemyBullet)
  18.     # 结束游戏
  19.     def endGame(self):
  20.         print('游戏结束')
  21.         exit()  # 退出游戏
  22.     # 笔墨体现    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()
  23.             # 松开键盘, 坦克避免移动            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):
  24.     def __init__(self, left, top):
  25.         super(MyTank, self).__init__(left, top)
  26.     def myTank_hit_enemyTank(self):
  27.         for enemyTank in MainGame.enemyTankList:
  28.             if pygame.sprite.collide_rect(self, enemyTank):
  29.                 self.stay()
  30. # 敌方坦克
  31. class EnemyTank(Tank):
  32.     def __init__(self, left, top, speed):
  33.         super(EnemyTank, self).__init__(left, top)
  34.         # 加载图片集
  35.         self.images = {
  36.             'U': pygame.image.load('img/enemy1U.gif'),
  37.             'D': pygame.image.load('img/enemy1D.gif'),
  38.             'L': pygame.image.load('img/enemy1L.gif'),
  39.             'R': pygame.image.load('img/enemy1R.gif'),
  40.         }
  41.         # 随机生成方向
  42.         self.direction = self.randDirection()
  43.         self.image = self.images[self.direction]  # 根据方向获取图片
  44.         self.rect = self.image.get_rect()  # 获取区域
  45.         self.rect.left, self.rect.top = left, top  # 对left和top赋值
  46.         self.speed = speed  # 速度
  47.         self.flag = True  # 坦克移动开关
  48.         self.step = 50  # 敌方坦克步数
  49.     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):  # 坦克的随机方向移动
  50.         if self.step < 0:  # 步数小于0, 随机改变方向
  51.             self.direction = self.randDirection()
  52.             self.step = 50  # 步数复位
  53.         else:
  54.             self.move()
  55.             self.step -= 1
  56.     def shot(self):  # 重写shot方法        num = random.randint(1, 100)        if num < 10:            return Bullet(self)# 子弹类class Bullet(Baseitem):    def __init__(self, tank):
  57.         self.image = pygame.image.load('img/enemymissile.gif')  # 图片加载
  58.         self.direction = tank.direction  # 子弹的方向
  59.         self.rect = self.image.get_rect()  # 获取区域
  60.         if self.direction == 'U':  # 子弹的left和top与方向有关
  61.             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  62.             self.rect.top = tank.rect.top - self.rect.height
  63.         elif self.direction == 'D':
  64.             self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
  65.             self.rect.top = tank.rect.top + tank.rect.height
  66.         elif self.direction == 'L':
  67.             self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2
  68.             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  69.         elif self.direction == 'R':
  70.             self.rect.left = tank.rect.left + tank.rect.width
  71.             self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
  72.         self.speed = 5   # 子弹的速度
  73.         self.live = True  # 子弹的状态
  74.     # 移动    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):
  75.         for wall in MainGame.WallList:  # 循环遍历墙壁列表
  76.             if pygame.sprite.collide_rect(self, wall):  # 检测子弹是否碰撞墙壁
  77.                 self.live = False  # 修改子弹状态
  78.                 wall.hp -= 1  # 碰撞后墙壁生命值减少
  79.                 if wall.hp <= 0:
  80.                     wall.live = False
  81.     # 子弹展示    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():
  82.     def __init__(self, filename):
  83.         self.filename = filename
  84.         pygame.mixer.init()
  85.         pygame.mixer.music.load(self.filename)  # 加载音乐
  86.     # 音乐播放
  87.     def play(self):
  88.         pygame.mixer.music.play()
  89. if __name__ == '__main__':    MainGame().startGame()
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表