学习 Python 之 Pygame 开发坦克大战(四)

  • 坦克大战添加音效
    • 1. 初始化音效
    • 2. 加入游戏开始音效和坦克移动音效
    • 3. 添加坦克开火音效
    • 4. 添加装甲削减音效
    • 5. 添加坦克爆炸音效
    • 6. 添加子弹击中边界音效

坦克大战添加音效

我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材

素材链接:百度网盘
链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz
提取码:tkdz

那我们就继续编写坦克大战吧

1. 初始化音效

现在已经完成了敌方坦克和我方坦克的对打了,我们把音效加入一下

创建音乐类

import pygameclass Sound:def __init__(self, filename):self.filename = filenamepygame.mixer.init()self.sound = pygame.mixer.Sound(self.filename)def play(self, loops = 0):self.sound.play(loops)def stop(self):self.sound.stop()def setVolume(self):self.sound.set_volume(0.2)return self

这些代码在 学习 Python 之 Pygame 开发坦克大战(一)中已经提前见过了

2. 加入游戏开始音效和坦克移动音效

坦克的移动是有音效的,在主类加入类成员

playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()
startingSound = Sound('../Sound/intro.wav')
class MainGame:...# 坦克移动音效playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()# 游戏开始音效startingSound = Sound('../Sound/intro.wav')...

在主函数中调用播放

def startGame(self):# 初始化展示模块pygame.display.init()# 设置窗口大小size = (SCREEN_WIDTH, SCREEN_HEIGHT)# 初始化窗口MainGame.window = pygame.display.set_mode(size)# 设置窗口标题pygame.display.set_caption('Tank Battle')# 初始化我方坦克MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)# 播放开始音乐MainGame.startingSound.play()...

修改getPlayingModeEvent()函数

def getPlayingModeEvent(self):# 获取所有事件eventList = pygame.event.get()for event in eventList:if event.type == pygame.QUIT:sys.exit()"""stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动"""if event.type == pygame.KEYDOWN:MainGame.playerTankMoveSound.play(-1)if event.key == pygame.K_w:MainGame.playerTank.direction = 'UP'MainGame.playerTank.stop = Falseelif event.key == pygame.K_s:MainGame.playerTank.direction = 'DOWN'MainGame.playerTank.stop = Falseelif event.key == pygame.K_a:MainGame.playerTank.direction = 'LEFT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_d:MainGame.playerTank.direction = 'RIGHT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_j:# 判断子弹数量是否超过指定的个数if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:bullet = MainGame.playerTank.shot()MainGame.playerBulletList.append(bullet)if event.type == pygame.KEYUP:MainGame.playerTankMoveSound.stop()if event.key == pygame.K_w:MainGame.playerTank.stop = Trueelif event.key == pygame.K_s:MainGame.playerTank.stop = Trueelif event.key == pygame.K_a:MainGame.playerTank.stop = Trueelif event.key == pygame.K_d:MainGame.playerTank.stop = True

完整的主类代码

import pygame
import sysfrom PlayerTank import PlayerTank
from EnemyTank import EnemyTank
from Sound import SoundSCREEN_WIDTH = 1100
SCREEN_HEIGHT = 600
BACKGROUND_COLOR = pygame.Color(0, 0, 0)
FONT_COLOR = (255, 255, 255)
PLAYER_TANK_POSITION = (325, 550)class MainGame:# 窗口Surface对象window = None# 玩家坦克playerTank = None# 玩家子弹playerBulletList = []playerBulletNumber = 3# 敌人坦克enemyTankList = []enemyTankTotalCount = 5# 用来给玩家展示坦克的数量enemyTankCurrentCount = 5# 敌人坦克子弹enemyTankBulletList = []# 爆炸列表explodeList = []# 坦克移动音效playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()# 游戏开始音效startingSound = Sound('../Sound/intro.wav')def __init__(self):passdef startGame(self):# 初始化展示模块pygame.display.init()# 设置窗口大小size = (SCREEN_WIDTH, SCREEN_HEIGHT)# 初始化窗口MainGame.window = pygame.display.set_mode(size)# 设置窗口标题pygame.display.set_caption('Tank Battle')# 初始化我方坦克MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)# 播放开始音乐MainGame.startingSound.play()while 1:# 设置背景颜色MainGame.window.fill(BACKGROUND_COLOR)# 获取窗口事件self.getPlayingModeEvent()# 展示敌方坦克self.drawEnemyTank()# 显示我方坦克MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])# 我方坦克移动if not MainGame.playerTank.stop:MainGame.playerTank.move()MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)# 显示我方坦克子弹self.drawPlayerBullet(MainGame.playerBulletList)# 展示敌方坦克子弹self.drawEnemyBullet()# 展示爆炸效果self.drawExplode()# 更新窗口pygame.display.update()def getPlayingModeEvent(self):# 获取所有事件eventList = pygame.event.get()for event in eventList:if event.type == pygame.QUIT:sys.exit()"""stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动"""if event.type == pygame.KEYDOWN:MainGame.playerTankMoveSound.play(-1)if event.key == pygame.K_w:MainGame.playerTank.direction = 'UP'MainGame.playerTank.stop = Falseelif event.key == pygame.K_s:MainGame.playerTank.direction = 'DOWN'MainGame.playerTank.stop = Falseelif event.key == pygame.K_a:MainGame.playerTank.direction = 'LEFT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_d:MainGame.playerTank.direction = 'RIGHT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_j:# 判断子弹数量是否超过指定的个数if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:bullet = MainGame.playerTank.shot()MainGame.playerBulletList.append(bullet)if event.type == pygame.KEYUP:MainGame.playerTankMoveSound.stop()if event.key == pygame.K_w:MainGame.playerTank.stop = Trueelif event.key == pygame.K_s:MainGame.playerTank.stop = Trueelif event.key == pygame.K_a:MainGame.playerTank.stop = Trueelif event.key == pygame.K_d:MainGame.playerTank.stop = Truedef drawPlayerBullet(self, playerBulletList):# 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除for bullet in playerBulletList:if not bullet.isDestroy:bullet.draw(MainGame.window)bullet.move(MainGame.explodeList)bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)else:playerBulletList.remove(bullet)def drawEnemyTank(self):# 如果当前坦克为0,那么就该重新生成坦克if len(MainGame.enemyTankList) == 0:# 一次性产生三个,如果剩余坦克数量超过三,那只能产生三个n = min(3, MainGame.enemyTankTotalCount)# 如果最小是0,就说明敌人坦克没有了,那么就赢了if n == 0:print('赢了')return# 没有赢的话,就产生n个坦克self.initEnemyTank(n)# 总个数减去产生的个数MainGame.enemyTankTotalCount -= n# 遍历坦克列表,展示坦克并且移动for tank in MainGame.enemyTankList:# 坦克还有生命值if tank.life > 0:tank.draw(MainGame.window)tank.move()tank.collidePlayerTank(MainGame.playerTank)tank.collideEnemyTank(MainGame.enemyTankList)bullet = tank.shot()if bullet is not None:MainGame.enemyTankBulletList.append(bullet)# 坦克生命值为0,就从列表中剔除else:MainGame.enemyTankCurrentCount -= 1MainGame.enemyTankList.remove(tank)def initEnemyTank(self, number):y = 0position = [0, 425, 850]index = 0for i in range(number):x = position[index]enemyTank = EnemyTank(x, y)MainGame.enemyTankList.append(enemyTank)index += 1def drawEnemyBullet(self):for bullet in MainGame.enemyTankBulletList:if not bullet.isDestroy:bullet.draw(MainGame.window)bullet.move(MainGame.explodeList)bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)else:bullet.source.bulletCount -= 1MainGame.enemyTankBulletList.remove(bullet)def drawExplode(self):for e in MainGame.explodeList:if e.isDestroy:MainGame.explodeList.remove(e)else:e.draw(MainGame.window)if __name__ == '__main__':MainGame().startGame()

3. 添加坦克开火音效

玩家坦克发射子弹是有音效的

修改getPlayingModeEvent()函数

def getPlayingModeEvent(self):# 获取所有事件eventList = pygame.event.get()for event in eventList:if event.type == pygame.QUIT:sys.exit()"""stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动"""if event.type == pygame.KEYDOWN:MainGame.playerTankMoveSound.play(-1)if event.key == pygame.K_w:MainGame.playerTank.direction = 'UP'MainGame.playerTank.stop = Falseelif event.key == pygame.K_s:MainGame.playerTank.direction = 'DOWN'MainGame.playerTank.stop = Falseelif event.key == pygame.K_a:MainGame.playerTank.direction = 'LEFT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_d:MainGame.playerTank.direction = 'RIGHT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_j:# 判断子弹数量是否超过指定的个数if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:bullet = MainGame.playerTank.shot()MainGame.playerBulletList.append(bullet)# 添加音效Sound('../Sound/shoot.wav').play(0)

4. 添加装甲削减音效

当我方坦克击中时,如果有装甲,装甲较少时会有音效
当敌方坦克血量减少时,也会出现音效

修改子弹类中的playerBulletCollideEnemyTank()函数,增加敌方坦克血量减少音效

def playerBulletCollideEnemyTank(self, enemyTankList, explodeList):# 循环遍历坦克列表,检查是否发生了碰撞for tank in enemyTankList:if pygame.sprite.collide_rect(tank, self):tank.loseLife(self.damage)# 把子弹设置为销毁状态self.isDestroy = Trueif tank.life == 0:# 增加爆炸效果explode = Explode(tank, 50)explodeList.append(explode)else:Sound('../Sound/enemy.armor.hit.wav').play()

修改子弹类中的enemyBulletCollidePlayerTank()函数,增加我方坦克血量装甲音效

def enemyBulletCollidePlayerTank(self, playerTank, explodeList):
# 玩家坦克生命值为0,不用检测
if playerTank.life <= 0:return
# 检测是否发生碰撞
if pygame.sprite.collide_rect(playerTank, self):# 发生碰撞先减少护甲,护甲为0时扣减生命值if playerTank.armor > 0:playerTank.armor -= self.damageplayerTank.armor = max(0, playerTank.armor)Sound('../Sound/enemy.armor.hit.wav').play()else:playerTank.loseLife(self.damage)# 增加爆炸效果explode = Explode(playerTank, 50)explodeList.append(explode)playerTank.life = max(0, playerTank.life)if playerTank.life != 0:playerTank.isResurrecting = True# 让子弹销毁self.isDestroy = True

5. 添加坦克爆炸音效

修改子弹类中的下面两个函数

def playerBulletCollideEnemyTank(self, enemyTankList, explodeList):# 循环遍历坦克列表,检查是否发生了碰撞for tank in enemyTankList:if pygame.sprite.collide_rect(tank, self):tank.loseLife(self.damage)# 把子弹设置为销毁状态self.isDestroy = Trueif tank.life == 0:# 增加爆炸效果explode = Explode(tank, 50)explodeList.append(explode)Sound('../Sound/kill.wav').play()else:Sound('../Sound/enemy.armor.hit.wav').play()def enemyBulletCollidePlayerTank(self, playerTank, explodeList):# 玩家坦克生命值为0,不用检测if playerTank.life <= 0:return# 检测是否发生碰撞if pygame.sprite.collide_rect(playerTank, self):# 发生碰撞先减少护甲,护甲为0时扣减生命值if playerTank.armor > 0:playerTank.armor -= self.damageplayerTank.armor = max(0, playerTank.armor)Sound('../Sound/enemy.armor.hit.wav').play()else:playerTank.loseLife(self.damage)# 增加爆炸效果explode = Explode(playerTank, 50)explodeList.append(explode)playerTank.life = max(0, playerTank.life)Sound('../Sound/kill.wav').play()if playerTank.life != 0:playerTank.isResurrecting = True# 让子弹销毁self.isDestroy = True

6. 添加子弹击中边界音效

在子弹类中checkBullet()函数增加音效代码

def checkBullet(self, explodeList):toDestroy = False# 如果出界,就设置为销毁if self.rect.top < 0 or self.rect.top > 600:toDestroy = Trueif self.rect.left < 0 or self.rect.right > 900:toDestroy = Trueif toDestroy:explode = Explode(self, 25)explodeList.append(explode)self.isDestroy = TrueSound('../Sound/block.wav').play()

运行一下,看看整体的效果

完整的主类代码

import pygame
import sysfrom PlayerTank import PlayerTank
from EnemyTank import EnemyTank
from Sound import SoundSCREEN_WIDTH = 1100
SCREEN_HEIGHT = 600
BACKGROUND_COLOR = pygame.Color(0, 0, 0)
FONT_COLOR = (255, 255, 255)
PLAYER_TANK_POSITION = (325, 550)class MainGame:# 窗口Surface对象window = None# 玩家坦克playerTank = None# 玩家子弹playerBulletList = []playerBulletNumber = 3# 敌人坦克enemyTankList = []enemyTankTotalCount = 5# 用来给玩家展示坦克的数量enemyTankCurrentCount = 5# 敌人坦克子弹enemyTankBulletList = []# 爆炸列表explodeList = []# 坦克移动音效playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()# 游戏开始音效startingSound = Sound('../Sound/intro.wav')def __init__(self):passdef startGame(self):# 初始化展示模块pygame.display.init()# 设置窗口大小size = (SCREEN_WIDTH, SCREEN_HEIGHT)# 初始化窗口MainGame.window = pygame.display.set_mode(size)# 设置窗口标题pygame.display.set_caption('Tank Battle')# 初始化我方坦克MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)# 播放开始音乐MainGame.startingSound.play()while 1:# 设置背景颜色MainGame.window.fill(BACKGROUND_COLOR)# 获取窗口事件self.getPlayingModeEvent()# 展示敌方坦克self.drawEnemyTank()# 显示我方坦克MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])# 我方坦克移动if not MainGame.playerTank.stop:MainGame.playerTank.move()MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)# 显示我方坦克子弹self.drawPlayerBullet(MainGame.playerBulletList)# 展示敌方坦克子弹self.drawEnemyBullet()# 展示爆炸效果self.drawExplode()# 更新窗口pygame.display.update()def getPlayingModeEvent(self):# 获取所有事件eventList = pygame.event.get()for event in eventList:if event.type == pygame.QUIT:sys.exit()"""stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动"""if event.type == pygame.KEYDOWN:MainGame.playerTankMoveSound.play(-1)if event.key == pygame.K_w:MainGame.playerTank.direction = 'UP'MainGame.playerTank.stop = Falseelif event.key == pygame.K_s:MainGame.playerTank.direction = 'DOWN'MainGame.playerTank.stop = Falseelif event.key == pygame.K_a:MainGame.playerTank.direction = 'LEFT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_d:MainGame.playerTank.direction = 'RIGHT'MainGame.playerTank.stop = Falseelif event.key == pygame.K_j:# 判断子弹数量是否超过指定的个数if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:bullet = MainGame.playerTank.shot()MainGame.playerBulletList.append(bullet)# 添加音效Sound('../Sound/shoot.wav').play(0)if event.type == pygame.KEYUP:MainGame.playerTankMoveSound.stop()if event.key == pygame.K_w:MainGame.playerTank.stop = Trueelif event.key == pygame.K_s:MainGame.playerTank.stop = Trueelif event.key == pygame.K_a:MainGame.playerTank.stop = Trueelif event.key == pygame.K_d:MainGame.playerTank.stop = Truedef drawPlayerBullet(self, playerBulletList):# 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除for bullet in playerBulletList:if not bullet.isDestroy:bullet.draw(MainGame.window)bullet.move(MainGame.explodeList)bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)else:playerBulletList.remove(bullet)def drawEnemyTank(self):# 如果当前坦克为0,那么就该重新生成坦克if len(MainGame.enemyTankList) == 0:# 一次性产生三个,如果剩余坦克数量超过三,那只能产生三个n = min(3, MainGame.enemyTankTotalCount)# 如果最小是0,就说明敌人坦克没有了,那么就赢了if n == 0:print('赢了')return# 没有赢的话,就产生n个坦克self.initEnemyTank(n)# 总个数减去产生的个数MainGame.enemyTankTotalCount -= n# 遍历坦克列表,展示坦克并且移动for tank in MainGame.enemyTankList:# 坦克还有生命值if tank.life > 0:tank.draw(MainGame.window)tank.move()tank.collidePlayerTank(MainGame.playerTank)tank.collideEnemyTank(MainGame.enemyTankList)bullet = tank.shot()if bullet is not None:MainGame.enemyTankBulletList.append(bullet)# 坦克生命值为0,就从列表中剔除else:MainGame.enemyTankCurrentCount -= 1MainGame.enemyTankList.remove(tank)def initEnemyTank(self, number):y = 0position = [0, 425, 850]index = 0for i in range(number):x = position[index]enemyTank = EnemyTank(x, y)MainGame.enemyTankList.append(enemyTank)index += 1def drawEnemyBullet(self):for bullet in MainGame.enemyTankBulletList:if not bullet.isDestroy:bullet.draw(MainGame.window)bullet.move(MainGame.explodeList)bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)else:bullet.source.bulletCount -= 1MainGame.enemyTankBulletList.remove(bullet)def drawExplode(self):for e in MainGame.explodeList:if e.isDestroy:MainGame.explodeList.remove(e)else:e.draw(MainGame.window)if __name__ == '__main__':MainGame().startGame()

完整的敌方坦克类代码

import random
import pygame
import pygame.imagefrom ParentObject import ParentObject
from Bullet import Bulletclass EnemyTank(ParentObject):def __init__(self, x, y):super().__init__()types = [(1, 3), (2, 1), (3, 2), (4, 10)]# 随机产生一种坦克self.type = types[random.randint(0, len(types) - 1)]up = []down = []left = []right = []for i in range(1, self.type[1] + 1):up.append(pygame.image.load('../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank'+ str(self.type[0]) + 'Lv' + str(i) + '(UP).png'))down.append(pygame.image.load('../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank'+ str(self.type[0]) + 'Lv' + str(i) + '(DOWN).png'))left.append(pygame.image.load('../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank' + str(self.type[0]) + 'Lv' + str(i) + '(LEFT).png'))right.append(pygame.image.load('../Image/Enemy/EnemyTank' + str(self.type[0]) + '/EnemyTank' + str(self.type[0]) + 'Lv' + str(i) + '(RIGHT).png'))self.images = {'UP': up,'DOWN': down,'LEFT': left,'RIGHT': right}# 生命self.life = self.type[1]# 方向self.direction = 'DOWN'self.image: pygame.Surface = self.images[self.direction][self.life - 1]self.rect = self.image.get_rect()self.rect.left = xself.rect.top = y# 碰撞前的坐标self.prvX = self.rect.leftself.prvY = self.rect.top# 速度self.accumulationMax: float = 0self.accumulation = 0.1speed = 0maxBulletCount = 0damage = 1# 每种坦克都有不同的属性if self.type[0] == 1:speed = 3self.level = 1maxBulletCount = 1elif self.type[0] == 2:speed = 5self.level = 2maxBulletCount = 1damage = 3elif self.type[0] == 3:speed = 7self.level = 1maxBulletCount = 3damage = 2elif self.type[0] == 4:speed = 6self.level = 2maxBulletCount = 3damage = 1self.speed = speed# 移动开关self.stop = True# 开火开关self.fire = True# 步数self.step = 30# 伤害self.damage = damage# 子弹个数self.bulletCount = 0self.maxBulletCount = maxBulletCountdef loseLife(self, value = 1):self.life -= valuedef move(self):"""新增步数变量, 当坦克移动时, 步数进行减少, 当步数小于等于0的时候, 修改地方坦克的方向:return: None"""if self.stop:if self.step <= 0:self.direction = self.randDirection()self.step = 30else:if self.accumulationMax >= 1:self.accumulationMax = 0# 记录上一次的位置self.prvX = self.rect.leftself.prvY = self.rect.topif self.direction == 'LEFT':if self.rect.left > 0:self.rect.left -= self.speedelif self.direction == 'UP':if self.rect.top > 0:self.rect.top -= self.speedelif self.direction == 'DOWN':if self.rect.top < 555:self.rect.top += self.speedelif self.direction == 'RIGHT':if self.rect.left < 855:self.rect.left += self.speedself.step -= 1else:self.accumulationMax += self.accumulationdef shot(self):if self.fire:if self.bulletCount < self.maxBulletCount:num = random.randint(0, 100)if num == 5 or num == 6:self.bulletCount += 1return Bullet(self)return Nonedef draw(self, window):# 获取展示的对象self.image = self.images[self.direction][self.life - 1]window.blit(self.image, self.rect)def randDirection(self):directions = ['UP', 'DOWN', 'LEFT', 'RIGHT']index = random.randint(0, 3)return directions[index]def collidePlayerTank(self, playerTank):# 遍历全部敌方坦克,检查有没有碰撞if pygame.sprite.collide_rect(self, playerTank):# 如果碰撞了,就保持原来的位置self.rect.left = self.prvXself.rect.top = self.prvYdef collideEnemyTank(self, enemyTankList):for tank in enemyTankList:if pygame.sprite.collide_rect(self, tank) and tank != self:self.rect.left = self.prvXself.rect.top = self.prvY

完整的我方坦克类代码

import pygame
import pygame.image
from ParentObject import ParentObject
from Bullet import Bulletclass PlayerTank(ParentObject):def __init__(self, x, y, order, amour):""":param x: 坦克横坐标:param y: 坦克纵坐标:param order: 玩家坦克序号,1表示一号玩家,2表示二号玩家:param amour: 坦克初始护甲"""super().__init__()self.images = []if order == 1:self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP1.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN1.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT1.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT1.png')})self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP2.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN2.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT2.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT2.png')})self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP3.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN3.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT3.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT3.png')})self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP4.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN4.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT4.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT4.png')})self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP5.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN5.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT5.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT5.png')})self.images.append({'UP': pygame.image.load('../Image/Player1/45x45/UP6.png'),'DOWN': pygame.image.load('../Image/Player1/45x45/DOWN6.png'),'LEFT': pygame.image.load('../Image/Player1/45x45/LEFT6.png'),'RIGHT': pygame.image.load('../Image/Player1/45x45/RIGHT6.png')})# 生命self.life = 3# 装甲self.armor = amour# 方向self.direction = 'UP'# 根据护甲选择坦克的样子self.image: pygame.Surface = self.images[max(self.armor - 1, 0)][self.direction]self.rect = self.image.get_rect()self.rect.left = xself.rect.top = y# 速度self.accumulation: float = 0self.speed = 2# 移动开关self.stop = True# 重生self.isResurrecting = False# 碰撞前的坐标self.prvX = self.rect.leftself.prvY = self.rect.top# 等级self.level = 1# 伤害self.damage = 1def move(self):if self.accumulation >= 1:self.accumulation = 0# 记录上一次的位置self.prvX = self.rect.leftself.prvY = self.rect.topif self.direction == 'LEFT':if self.rect.left > 0:self.rect.left -= self.speedelif self.direction == 'UP':if self.rect.top > 0:self.rect.top -= self.speedelif self.direction == 'DOWN':if self.rect.top < 555:self.rect.top += self.speedelif self.direction == 'RIGHT':if self.rect.left < 855:self.rect.left += self.speedelse:self.accumulation += 0.20def shot(self):return Bullet(self)def draw(self, window, x, y):# 坦克生命中为0,表示已经死亡,不再展示坦克if self.life <= 0:return# 判断坦克是否复合if self.isResurrecting:# 把坦克位置设置为指定的重生位置self.rect.left = xself.rect.top = yself.isResurrecting = Falseself.direction = 'UP'# 获取展示的对象self.image = self.images[max(self.armor - 1, 0)][self.direction]# 画出图片window.blit(self.image, self.rect)def collideEnemyTank(self, enemyTankList):# 遍历全部敌方坦克,检查有没有碰撞for enemyTank in enemyTankList:if pygame.sprite.collide_rect(self, enemyTank):# 如果碰撞了,就保持原来的位置self.rect.left = self.prvXself.rect.top = self.prvYdef loseLife(self, value = 1):self.life -= value

完整的子弹类代码

import pygame
from ParentObject import ParentObject
from Explode import Explode
from Sound import Soundclass Bullet(ParentObject):def __init__(self, tank):super().__init__()self.images = {'UP': pygame.image.load('../Image/Bullet/Bullet(UP).png'),'DOWN': pygame.image.load('../Image/Bullet/Bullet(DOWN).png'),'LEFT': pygame.image.load('../Image/Bullet/Bullet(LEFT).png'),'RIGHT': pygame.image.load('../Image/Bullet/Bullet(RIGHT).png')}# 方向self.direction = tank.directionself.image: pygame.Surface = self.images[self.direction]self.rect = self.image.get_rect()# 坦克发射子弹的位置if self.direction == 'UP':self.rect.left = tank.rect.left + 17.5self.rect.top = tank.rect.top - 25elif self.direction == 'DOWN':self.rect.left = tank.rect.left + 17.5self.rect.top = tank.rect.top + 25elif self.direction == 'LEFT':self.rect.left = tank.rect.left - 25self.rect.top = tank.rect.top + 17.5elif self.direction == 'RIGHT':self.rect.left = tank.rect.left + 25self.rect.top = tank.rect.top + 17.5# 速度self.accumulationMax: float = 0self.accumulation = 0.25self.speed = 10# 销毁开关self.isDestroy = False# 发射源self.source = tank# 伤害self.damage = tank.damagedef move(self, explodeList):if self.accumulation >= 1:self.accumulation = 0if self.direction == 'LEFT':self.rect.left -= self.speedelif self.direction == 'UP':self.rect.top -= self.speedelif self.direction == 'DOWN':self.rect.top += self.speedelif self.direction == 'RIGHT':self.rect.left += self.speed# 检查子弹是否出界self.checkBullet(explodeList)else:self.accumulation += 0.20def checkBullet(self, explodeList):toDestroy = False# 如果出界,就设置为销毁if self.rect.top < 0 or self.rect.top > 600:toDestroy = Trueif self.rect.left < 0 or self.rect.right > 900:toDestroy = Trueif toDestroy:explode = Explode(self, 25)explodeList.append(explode)self.isDestroy = TrueSound('../Sound/block.wav').play()def draw(self, window):window.blit(self.image, self.rect)def playerBulletCollideEnemyTank(self, enemyTankList, explodeList):# 循环遍历坦克列表,检查是否发生了碰撞for tank in enemyTankList:if pygame.sprite.collide_rect(tank, self):tank.loseLife(self.damage)# 把子弹设置为销毁状态self.isDestroy = Trueif tank.life == 0:# 增加爆炸效果explode = Explode(tank, 50)explodeList.append(explode)Sound('../Sound/kill.wav').play()else:Sound('../Sound/enemy.armor.hit.wav').play()def enemyBulletCollidePlayerTank(self, playerTank, explodeList):# 玩家坦克生命值为0,不用检测if playerTank.life <= 0:return# 检测是否发生碰撞if pygame.sprite.collide_rect(playerTank, self):# 发生碰撞先减少护甲,护甲为0时扣减生命值if playerTank.armor > 0:playerTank.armor -= self.damageplayerTank.armor = max(0, playerTank.armor)Sound('../Sound/enemy.armor.hit.wav').play()else:playerTank.loseLife(self.damage)# 增加爆炸效果explode = Explode(playerTank, 50)explodeList.append(explode)playerTank.life = max(0, playerTank.life)Sound('../Sound/kill.wav').play()if playerTank.life != 0:playerTank.isResurrecting = True# 让子弹销毁self.isDestroy = True

完整的音乐类代码

import pygameclass Sound:def __init__(self, filename):self.filename = filenamepygame.mixer.init()self.sound = pygame.mixer.Sound(self.filename)def play(self, loops = 0):self.sound.play(loops)def stop(self):self.sound.stop()def setVolume(self):self.sound.set_volume(0.2)return self

完整的爆炸效果类代码

import pygame.imageclass Explode:def __init__(self, object, size):# 获取爆炸对象的位置self.rect = object.rectself.images = []self.images.append([pygame.image.load('../Image/Explode/Explode50x50.png'),pygame.image.load('../Image/Explode/Explode50x50.png'),pygame.image.load('../Image/Explode/Explode50x50.png'),pygame.image.load('../Image/Explode/Explode50x50.png'),pygame.image.load('../Image/Explode/Explode50x50.png')])self.images.append([pygame.image.load('../Image/Explode/Explode25x25.png'),pygame.image.load('../Image/Explode/Explode25x25.png'),pygame.image.load('../Image/Explode/Explode25x25.png'),pygame.image.load('../Image/Explode/Explode25x25.png'),pygame.image.load('../Image/Explode/Explode25x25.png')])self.mode = 0if size == 25:self.mode = 1self.index = 0self.image = self.images[self.mode][self.index]self.isDestroy = Falsedef draw(self, window):# 根据索引获取爆炸对象, 添加到主窗口if self.index < len(self.images):self.image = self.images[self.mode][self.index]self.index += 1window.blit(self.image, self.rect)else:self.isDestroy = Trueself.index = 0

至此,坦克大战出了地图中的固定景物外,都有音效和动作,下面就为地图添加墙之类的物体了

学习 Python 之 Pygame 开发坦克大战(四)相关推荐

  1. 学习 Python 之 Pygame 开发坦克大战(五)

    学习 Python 之 Pygame 开发坦克大战(五) 坦克大战完善地图 1. 创建砖墙 2. 给砖墙增加子弹击中的碰撞效果 3. 给砖墙添加坦克不能通过的碰撞效果 4. 添加石墙 5. 添加玩家基 ...

  2. 学习 Python 之 Pygame 开发魂斗罗(一)

    学习 Python 之 Pygame 开发魂斗罗(一) Pygame 回忆Pygame 1. 使用pygame创建窗口 2. 设置窗口背景颜色 3. 获取窗口中的事件 4. 在窗口中展示图片 (1). ...

  3. 学习 Python 之 Pygame 开发魂斗罗(四)

    学习 Python 之 Pygame 开发魂斗罗(四) 继续编写魂斗罗 1. 创建子弹类 2. 根据玩家方向和状态设置子弹发射的位置 (1). 站立向右发射子弹 (2). 站立向左发射子弹 (3). ...

  4. 学习 Python 之 Pygame 开发魂斗罗(十四)

    学习 Python 之 Pygame 开发魂斗罗(十四) 继续编写魂斗罗 1. 创建桥类 2. 在主类中加入一些类变量 3. 显示桥 4. 解决玩家与桥的碰撞体问题 5. 解决敌人与桥的碰撞体问题 继 ...

  5. 学习 Python 之 Pygame 开发魂斗罗(二)

    学习 Python 之 Pygame 开发魂斗罗(二) 魂斗罗的需求 开始编写魂斗罗 1. 搭建主类框架 2. 设置游戏运行遍历和创建窗口 3. 获取窗口中的事件 4. 创建角色 5. 完成角色更新函 ...

  6. 学习 Python 之 Pygame 开发魂斗罗(九)

    学习 Python 之 Pygame 开发魂斗罗(九) 继续编写魂斗罗 1. 在子弹类中修改敌人发射子弹的位置 2. 创建显示敌人子弹的函数 3. 解决敌人不会向下掉落的问题 4. 给敌人碰撞体组增加 ...

  7. 学习 Python 之 Pygame 开发魂斗罗(八)

    学习 Python 之 Pygame 开发魂斗罗(八) 继续编写魂斗罗 1. 创建敌人类 2. 增加敌人移动和显示函数 3. 敌人开火 4. 修改主函数 5. 产生敌人 6. 使敌人移动 继续编写魂斗 ...

  8. 学习 Python 之 Pygame 开发魂斗罗(十一)

    学习 Python 之 Pygame 开发魂斗罗(十一) 继续编写魂斗罗 1. 改写主类函数中的代码顺序 2. 修改玩家初始化 3. 显示玩家生命值 4. 设置玩家碰到敌人死亡 5. 设置敌人子弹击中 ...

  9. 运用Python+Pygame开发坦克大战游戏_版本V1.01

    这里写目录标题 一.项目整体说明 二.pygame下载方式 三.项目文件 1.坦克大战_框架_1.py 2.坦克大战_开始游戏_窗口设置_2.py 3.坦克大战_事件检测_3.py 4.坦克大战_基本 ...

最新文章

  1. 博士最“惨”能到什么程度?
  2. flex Scroller
  3. h.264的POC计算
  4. Java基础——JVM内存结构
  5. 《c专家编程》笔记--define和typedef的区别
  6. SpringCloud Netflix Hystrix
  7. 8个树莓派超级计算机_6 个可以尝试的树莓派教程
  8. Socket编程 涵盖代码和函数参数介绍
  9. oracle通信通道的文件结尾_【移民】加拿大安省发放优才计划移民邀请函;NS省干掉特快通道直申种类的申请通道...
  10. Spring入门系列之Spring概述
  11. Eclipse中文显示乱码问题
  12. 开启手机新时代,智领5G未来:中国电信首款5G定制高端机震撼登场
  13. 【NLP免费系列直播】图卷积神经网络, BERT,知识图谱, 对话生成
  14. (Python)计算器的设计与实现
  15. TCP|IP+WIFI无线远程网络RFID|NFC读卡器HX530-Q-A系列Server网络模式与 Client网络模式设置说明
  16. Gson解析json数据
  17. 北京车辆过户外迁,北京车辆外迁流程
  18. 如何将图片批量转换成PDF
  19. SqlServer2008操作总结
  20. 制作一个简单的Chrome extensions并发布到应用商店

热门文章

  1. 第12章 Docker 中 MySQL 的安装与配置
  2. 读《像google一样开会》
  3. 线性代数及其应用(第三版)1.8节习题解答
  4. 结构优化软件SolidThinking Inspire的自学攻略
  5. DevExpress DXperience Universal 2011 vol 1.6 安装与内存注册
  6. 到底是做后台还是前台呢?
  7. 全球免费下载高程DEM数据整理
  8. .NET 6 实现敏感词过滤
  9. android手写签名android-signaturepad
  10. 【物联网】施密特辞任谷歌母公司董事长!他非常直接地说,互联网将消失!