游戏开始的声音
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<link href="./src/style/minireset.min.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<div class="">
<audio src="/src/static/music/start.wav" id="aStart"></audio>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
增加声音播放的服务。
src/service/audio.ts
/**
* 服务
* 声音播放
*/
export default {
start() {
const el = document.querySelector<HTMLAudioElement>('#aStart')
el?.play()
}
}
src/app.ts
......
// 游戏开始
async gameStart() {
if (this.gameStatus != 'gameStart') {
this.gameStatus = 'gameStart'
//背景图片关闭
// @ts-ignore
app.style.backgroundImage = 'none';
audio.start()//游戏开始的声音
// console.log(promises)
//先加载各种贴图
await Promise.all(promises)
// console.log(image.get('straw'))
// 调用render方法渲染
canvasStraw.render() // 画布渲染:草地
canvasWallBrick.render() // 画布渲染:砖墙
canvasWallSteel.render() // 画布渲染:钢墙
canvasTank.render() // 画布渲染:敌方坦克
canvasWater.render() // 画布渲染:水域
bullet.render() // 画布渲染:子弹
boss.render() // 画布渲染:boss,老巢
player.render() // 画布渲染:玩家坦克
}
},
......
其他声音载入
同理。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="favicon.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Vite App</title>
<link href="./src/style/minireset.min.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<div class="">
<!-- 声音:游戏开始 -->
<audio src="/src/static/music/start.wav" id="aStart"></audio>
<!-- 声音:开火 -->
<audio src="/src/static/music/fire.wav" id="aBulletFire"></audio>
<!-- 声音:爆炸 -->
<audio src="/src/static/music/blast.wav" id="aBlast"></audio>
<!-- 声音:增加砖块 -->
<audio src="/src/static/music/add.wav" id="aAdd"></audio>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
src/service/audio.ts
/**
* 服务
* 声音播放
*/
export default {
getEl(id: string) {
return document.querySelector<HTMLAudioElement>(`#${id}`)
},
//声音:游戏开始
start() {
const el = this.getEl('aStart')
el?.play()
},
//声音:开火
bulletFire() {
const el = this.getEl('aBulletFire')
el?.play()
},
//声音:爆炸
blast() {
const el = this.getEl('aBlast')
el?.play()
},
//声音:增加砖块
add() {
const el = this.getEl('aAdd')
el?.play()
},
}
src/canvas/Bullet.ts
......
//自定义子弹的渲染函数:子弹创建
createModelsBullet() {
// 子弹的创建需要根据坦克的画布中的坦克模型数量来决定需要发送多少颗子弹
tank.models.forEach(tItem => {
// 查询是否存在同样名称的坦克的子弹,如果有,表示该坦克已经发射子弹了
const isExists = this.models.some(model => model.tank === tItem)
//如果子弹不存在,放置子弹
if (!isExists) {
this.models.push(new ModelBullet(tItem))
// 敌方坦克开火,发出声音
audio.bulletFire()
}
})
// console.log(this.models)
}
// 我方坦克发射子弹
addPlayerBullet() {
this.models.push(new ModelBullet(player.models[0]))
// 玩家坦克开火,发出声音
audio.bulletFire()
}
......
src/model/abstract/AbstractModel.ts
......
/**
* 爆炸效果实现
* 原理:8张gif图片依次切换显示。
* @param model 被打炸的模型
* @protected
*/
protected blast(model: IModel) {
// 爆炸的声音
audio.blast()
......
}
......
游戏结束时文字处理
优化一下贴图
src/canvas/abstract/AbstractCanvas.ts
......
// 绘制模型,生成模型实例,只负责创建实例
// protected:子类可以调用,外部不能调用
//num: 渲染多少个数量
// 初始化canvas,创建画布
protected createCanvas() {
// 元素的宽高就是全局canvas得到宽高
// @ts-ignore
this.el.width = config.canvas.width
// @ts-ignore
this.el.height = config.canvas.height
// 最终元素要放到我们的app的div中
// @ts-ignore
this.el.setAttribute('name', this.name)
// @ts-ignore
this.app.insertAdjacentElement('afterbegin', this.el)
// @ts-ignore
if (!(this.name === 'water' || this.name === 'WallSteel')) {
// @ts-ignore
this.app.appendChild(this.el)
}
}
......
src/app.ts
......
// 游戏结束
gameOver() {
//关闭游戏运行的定时器
clearInterval(this.gameInterval)
// 敌方坦克停止
tank.stop()
// 子弹停止
bullet.stop()
this.gameOverText()
},
async gameOverText() {
// @ts-ignore
const el = document.createElement<HTMLCanvasElement>('canvas');
// @ts-ignore
el.width = config.canvas.width
// @ts-ignore
el.height = config.canvas.height
// @ts-ignore
const ctx = el.getContext('2d')
ctx.fillStyle = '#fff'
ctx.font = '80px CascadiaMono'
ctx.textAlign='center'
ctx.textBaseline = 'middle'
ctx.fontWeight=900
ctx.fillText(this.gameStatus==='gameWin'?'游戏胜利':'游戏失败', config.canvas.width/2, config.canvas.height/2)
// @ts-ignore
app.appendChild(el)
}
......
![](https://img.haomeiwen.com/i16102290/71d206622c92b711.png)
网友评论