小游戏播放背景音乐
玩游戏没有背景音乐添加气氛怎么可以呢?可惜的是 Canvas
并没有播放声音的功能
但,这难不倒我们,在 HTML Canvas 中可以使用 <audio>
元素来播放声音
但是微信小游戏里面,连 document
对象都没有,就更不用说使用 document.createElement('audio')
来播放声音了
但这个功能有如此的重要,所以微信小游戏提供了一个函数 wx.createInnerAudioContext()
来播放声音
这个函数可以看成是对 document.createElement('audio')
的封装,为啥,因为创建了一个 Audio
对象之后,它们的使用方法竟然一模一样
有关更多微信小游戏播放音频的介绍,可以访问 https://developers.weixin.qq.com/minigame/dev/tutorial/ability/audio.html
wx.createInnerAudioContext()
wx.createInnerAudioContext()
用于创建一个音频对象,使用方式很简单
我们先创建一个文件夹 audio
,然后把打飞机小游戏里的 audio/bgm.mp3 拷贝到 audio
目录
或者点击 https://www.twle.cn/static/i/minigame/bgm.mp3 下载并保存到 audio
目录
然后我们就可以写一个范例来试一试了
对了,先把你的音量调小,不然打搅到邻居就不好了
var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.play()
运行一下,就能听到那熟悉的声音了
src 可以设置 http(s) 的路径,本地文件路径或者代码包文件路径
重复播放背景音乐
但是这样普通的设置,我们的背景音乐不会自动重复,需要设置 loop
为 true
game.js
var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.loop = true; bgm.play()
恢复播放
当我们临时有事,可能需要把小游戏切换到后台,然后回来一看,声音竟然没播放了
好吧,翻了下微信的文档,它说如果要恢复播放,就要在 wx.onShow()
事件里恢复播放
wx.onShow(function () { bgm.play() })
演示如下
var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.loop = true; bgm.play() wx.onShow(function () { bgm.play() })
perfect !
中断事件
如果我们在玩游戏的时候接到电话、闹钟响起、系统提醒、收到微信好友的语音/视频通话请求
这时候背景音乐又被中断了,而且在中断结束之前都不能再播放成功
等等,中断的时候我们要暂停游戏对吧,翻了下文档,微信小游戏够意思,竟然提供了 wx.onAudioInterruptionBegin
事件来处理中断事件
wx.onAudioInterruptionBegin(function () { // 暂停音乐 bgm.stop(); // 中断动画 //cancelAnimationFrame(animate_it); })
演示如下
var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.loop = true; bgm.play() wx.onShow(function () { bgm.play() }) wx.onAudioInterruptionBegin(function () { // 暂停音乐 bgm.stop(); // 中断动画 //cancelAnimationFrame(animate_it); })
中断恢复
更坑的是,中断结束回到游戏,背景音乐又不会自动播放了,好吧,翻了下文档,有看到需要监听一个事件 onAudioInterruptionEnd
wx.onAudioInterruptionEnd(function () { bgm.play() })
演示如下
var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.loop = true; bgm.play() wx.onShow(function () { bgm.play() }) wx.onAudioInterruptionBegin(function () { // 暂停音乐 bgm.stop(); // 中断动画 //cancelAnimationFrame(animate_it); }) wx.onAudioInterruptionEnd(function () { bgm.play() // 恢复动画 //cancelAnimationFrame(animate_it); })
范例
好吧, 播放声音的总算是处理完了,我们可以在往背景动画里添加背景音乐了
game.js
var c = wx.createCanvas(); var ctx = c.getContext('2d'); var img = wx.createImage(); var bgCanvas = null; var offset = 0; var w = 0; var h = 0; var screenWidth = c.width; var screenHeight = c.height; function init_bg() { bgCanvas = wx.createCanvas(); bgCanvas.width = screenWidth; bgCanvas.height = screenHeight + h; var bgctx = bgCanvas.getContext('2d'); var y = 0; var x = 0; // 底部多绘制一张图片 while (y < screenHeight + h) { x = 0; while (x < screenWidth) { bgctx.drawImage(img, x, y, w, h); x += w; } y += h; } } function reset() { ctx.save(); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, c.width, c.height); ctx.restore(); } function draw_copy() { ctx.save(); ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.fillStyle = "#aaa"; ctx.font = "16px Arial" // 字体大小 16 像素 ctx.fillText("简单教程,简单编程", c.width / 2, (c.height - 36)) ctx.fillText(" © 2015-2018 www.twle.cn", c.width / 2, (c.height - 18)); ctx.restore(); } function animate_it() { reset(ctx); ctx.drawImage(bgCanvas, 0, offset, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight); draw_copy(); offset++; if (offset % h == 0) { offset = 0; } requestAnimationFrame(animate_it); } reset(ctx); img.onload = function () { w = screenWidth > img.width ? img.width : screenWidth; h = img.height * (w / img.width); init_bg(); requestAnimationFrame(animate_it); } img.src = "images/bg.jpg"; var bgm = wx.createInnerAudioContext(); bgm.src = 'audio/bgm.mp3' bgm.loop = true; bgm.play() wx.onShow(function () { bgm.play() }) wx.onAudioInterruptionBegin(function () { // 暂停音乐 bgm.stop(); // 中断动画 //cancelAnimationFrame(animate_it); }) wx.onAudioInterruptionEnd(function () { bgm.play() // 恢复动画 cancelAnimationFrame(animate_it); })
运行演示如下
因为移动距离不是刚好等于图片高度,所以会闪屏