学习 Python 之 Pygame 开发坦克大战
Posted _DiMinisH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习 Python 之 Pygame 开发坦克大战相关的知识,希望对你有一定的参考价值。
学习 Python 之 Pygame 开发坦克大战(四)
坦克大战添加音效
我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材
素材链接:百度网盘
链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz
提取码:tkdz
那我们就继续编写坦克大战吧
1. 初始化音效
现在已经完成了敌方坦克和我方坦克的对打了,我们把音效加入一下
创建音乐类
import pygame
class Sound:
def __init__(self, filename):
self.filename = filename
pygame.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 = False
elif event.key == pygame.K_s:
MainGame.playerTank.direction = 'DOWN'
MainGame.playerTank.stop = False
elif event.key == pygame.K_a:
MainGame.playerTank.direction = 'LEFT'
MainGame.playerTank.stop = False
elif event.key == pygame.K_d:
MainGame.playerTank.direction = 'RIGHT'
MainGame.playerTank.stop = False
elif 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 = True
elif event.key == pygame.K_s:
MainGame.playerTank.stop = True
elif event.key == pygame.K_a:
MainGame.playerTank.stop = True
elif event.key == pygame.K_d:
MainGame.playerTank.stop = True
完整的主类代码
import pygame
import sys
from PlayerTank import PlayerTank
from EnemyTank import EnemyTank
from Sound import Sound
SCREEN_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):
pass
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()
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 = False
elif event.key == pygame.K_s:
MainGame.playerTank.direction = 'DOWN'
MainGame.playerTank.stop = False
elif event.key == pygame.K_a:
MainGame.playerTank.direction = 'LEFT'
MainGame.playerTank.stop = False
elif event.key == pygame.K_d:
MainGame.playerTank.direction = 'RIGHT'
MainGame.playerTank.stop = False
elif 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 = True
elif event.key == pygame.K_s:
MainGame.playerTank.stop = True
elif event.key == pygame.K_a:
MainGame.playerTank.stop = True
elif event.key == pygame.K_d:
MainGame.playerTank.stop = True
def 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 -= 1
MainGame.enemyTankList.remove(tank)
def initEnemyTank(self, number):
y = 0
position = [0, 425, 850]
index = 0
for i in range(number):
x = position[index]
enemyTank = EnemyTank(x, y)
MainGame.enemyTankList.append(enemyTank)
index += 1
def 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 -= 1
MainGame.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 = False
elif event.key == pygame.K_s:
MainGame.playerTank.direction = 'DOWN'
MainGame.playerTank.stop = False
elif event.key == pygame.K_a:
MainGame.playerTank.direction = 'LEFT'
MainGame.playerTank.stop = False
elif event.key == pygame.K_d:
MainGame.playerTank.direction = 'RIGHT'
MainGame.playerTank.stop = False
elif 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 = True
if 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.damage
playerTank.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 = True
if 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.damage
playerTank.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 != 学习 Python 之 Pygame 开发坦克大战