小游戏播放背景音乐

玩游戏没有背景音乐添加气氛怎么可以呢?可惜的是 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) 的路径,本地文件路径或者代码包文件路径

重复播放背景音乐

但是这样普通的设置,我们的背景音乐不会自动重复,需要设置 looptrue

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);
})

运行演示如下

因为移动距离不是刚好等于图片高度,所以会闪屏

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.