这一节我们来学习加载音频和视频文件,以及一些相关的操作。
首先说音频文件,其实就是一段音乐,想象一下与音乐有关的操作:播放、暂停、继续、停止、加大音量、减小音量,常规的操作也就这几个,那我们先来看一段代码,怎么实现这些操作,代码如下:
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.image('disk', 'assets/sprites/ra_dont_crack_under_pressure.png');
//这里要加载的元素支持数组格式
//官方的demo里说Firefox不支持mp3格式,所以要添加使用ogg格式的备选文件,不过我试了,mp3和ogg火狐都是支持的
game.load.audio('wizball', ['assets/audio/oedipus_wizball_highscore.mp3', 'assets/audio/oedipus_wizball_highscore.ogg']);
// game.load.audio('wizball', 'assets/audio/oedipus_wizball_highscore.ogg');
}
var s;
var music;
function create() {
game.stage.backgroundColor = '#182d3b';
//允许事件冒泡:避免点击到图片没反应
game.input.touch.preventDefault = false;
//添加音乐到游戏场景并播放
music = game.add.audio('wizball');
music.play();
//加载一张图片
s = game.add.sprite(game.world.centerX, game.world.centerY, 'disk');
s.anchor.setTo(0.5, 0.5);
//添加按键事件:上下方向键控制音量,空格键暂停和继续,左方向键停止,右方向键静音
upKey = game.input.keyboard.addKey(Phaser.Keyboard.UP);
upKey.onDown.add(volumeUp, this);
downKey = game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
downKey.onDown.add(volumeDown, this);
leftKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
leftKey.onDown.add(musicStop, this);
rightKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
rightKey.onDown.add(volumeMute, this);
oneKey = game.input.keyboard.addKey(Phaser.Keyboard.ONE);
oneKey.onDown.add(musicRestart, this);
spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
spaceKey.onDown.add(pause, this);
}
function volumeUp(){
music.volume += 0.1;
}
function volumeDown(){
music.volume -= 0.1;
}
function musicStop(){
music.stop();
}
function volumeMute(){
music.mute = !music.mute;
}
function musicRestart(){
music.play();
}
function pause(){
//或者使用music.paused来判断
if(music.isPlaying){
music.pause();
}
else{
music.resume();
}
}
function update() {
s.rotation += 0.01;
}
function render() {
game.debug.soundInfo(music, 20, 32);
}
上面的代码中,我定义了六个按键对音频实现不同的操作,并且输出了调试的信息,通过输出的信息,我们可以发现很多东西,比如文件的长度、是否暂停、音量等等。这里需要注意一点,音量的取值范围其实是0~1,当然你可以随意设置,就算是负值也没关系,Phaserjs可以帮你取绝对值,不过数值过大的话,声音虽然会更大,不过音效可能会失真。
其实在游戏中,除了背景音乐之外,我们很少使用过大的音频文件,使用的都是类似于音效、语音对白之类的小音频文件,这些文件虽然每个时间都不长,可数量不少,一个个加载不仅耗时,更需要写很多重复的代码,于是Phaserjs提供了一个音频截取的功能。
音频截取,其实很简单,类似于CSS Sprite,把许多小文件整合在一起,通过标记单独使用其中的某一部分,看下面这段代码:var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create });
function preload() {
game.load.image('title', 'assets/pics/catastrophi.png');
game.load.spritesheet('button', 'assets/buttons/flixel-button.png', 80, 20);
game.load.bitmapFont('nokia', 'assets/fonts/bitmapFonts/nokia16black.png', 'assets/fonts/bitmapFonts/nokia16black.xml');
// game.load.audio('sfx', [ 'assets/audio/SoundEffects/fx_mixdown.mp3', 'assets/audio/SoundEffects/fx_mixdown.ogg' ]);
game.load.audio('sfx', 'assets/audio/SoundEffects/fx_mixdown.ogg');
}
var fx;
function create() {
game.add.image(0, 0, 'title');
//注册音频文件
fx = game.add.audio('sfx');
//是否允许同时播放多段音乐
fx.allowMultiple = false;
//定义标记:关键字、开始时间、持续时间(单位:秒)
fx.addMarker('alien death', 1, 1.0);
fx.addMarker('boss hit', 3, 0.5);
fx.addMarker('escape', 4, 3.2);
fx.addMarker('meow', 8, 0.5);
fx.addMarker('numkey', 9, 0.1);
fx.addMarker('ping', 10, 1.0);
fx.addMarker('death', 12, 4.2);
fx.addMarker('shot', 17, 1.0);
fx.addMarker('squit', 19, 0.3);
//定义按钮关键字和位置
makeButton('alien death', 600, 100);
makeButton('boss hit', 600, 140);
makeButton('escape', 600, 180);
makeButton('meow', 600, 220);
makeButton('numkey', 600, 260);
makeButton('ping', 600, 300);
makeButton('death', 600, 340);
makeButton('shot', 600, 380);
makeButton('squit', 600, 420);
}
//添加按钮
function makeButton(name, x, y) {
var button = game.add.button(x, y, 'button', click, this, 0, 1, 2);
button.name = name;
button.scale.set(2, 1.5);
button.smoothed = false;
//添加按钮文字
var text = game.add.bitmapText(x, y + 7, 'nokia', name, 16);
text.x += (button.width / 2) - (text.textWidth / 2);
}
//点击按钮时触发相应标记的音效
function click(button) {
fx.play(button.name);
}
这段代码就实现了添加标记的功能,通过addMarker方法将音频文件分割成多个小段,分别定义一个关键字,点击按钮时就触发事件,播放该段时间内的音效。
这里需要注意allowMultiple这个属性,简单来说,这个属性就是设定你在播放一段音效的时候,是否允许同时播放另一段音效,你可以尝试先点击escape或death这两个按钮,然后再点击其他按钮来查看效果。
另外,还有一种通过json设置标记时间的方法,我这里就不贴出代码了,请自行查看audio/ audio sprite json.js这个js里面的代码。
接下来来说说加载视频文件,视频文件的基本操作跟音频也差不多,无外乎那么几种,不过也是有区别的,比如,视频是有图像的,我们也要把图像添加到窗口中,其次,操作的方法名称略有不同,查看这段代码:var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update});
function preload() {
game.load.video('countryroad', 'assets/video/z0011j50w5k.p302.1.mp4');
game.load.bitmapFont('desyrel', 'assets/fonts/bitmapFonts/desyrel.png', 'assets/fonts/bitmapFonts/desyrel.xml');
}
var video;
var text;
function create() {
game.stage.backgroundColor = '#182d3b';
//允许事件冒泡:避免点击到图片没反应
game.input.touch.preventDefault = false;
//注册视频并播放
video = game.add.video('countryroad');
video.play(true);
//将视频添加到游戏窗口中:x,y,anchorX,anchorY,scaleX,scaleY
video.addToWorld(400, 250, 0.5, 0.5);
video.volume = 0.1;
console.log(video);
//添加文字
text = game.add.bitmapText(400, 500, 'desyrel', 'Phaser\nAlpha Videos', 24);
text.anchor.set(0.5);
text.align = 'center';
//添加按键事件:上下方向键控制音量,空格键暂停和继续,左方向键停止,右方向键静音
upKey = game.input.keyboard.addKey(Phaser.Keyboard.UP);
upKey.onDown.add(volumeUp, this);
downKey = game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
downKey.onDown.add(volumeDown, this);
leftKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
leftKey.onDown.add(videoStop, this);
rightKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
rightKey.onDown.add(volumeMute, this);
oneKey = game.input.keyboard.addKey(Phaser.Keyboard.ONE);
oneKey.onDown.add(videoRestart, this);
spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
spaceKey.onDown.add(pause, this);
}
function volumeUp(){
video.volume += 0.1;
}
function volumeDown(){
video.volume -= 0.1;
}
function videoStop(){
video.stop();
}
function volumeMute(){
video.mute = !video.mute;
}
function videoRestart(){
video.play();
}
function pause(){
//或者使用video.paused来判断
if(video._paused){
video.setResume();
}
else{
video.setPause();
}
}
function update() {
text.text = 'Phaser kicking\nAlpha Video Channels\n' + Math.round(video.progress * 100) + '%';
}
上面的代码中,需要注意两点:一个是addToWorld方法,这个方法就是把对象添加到游戏窗口中,以后会经常遇到,另外一个是就是暂停、播放这些属性和方法名和音频文件是不一样的,仔细查看下。
另外,这段代码中,使用了一个名叫z0011j50w5k.p302.1.mp4的视频文件,这个是因为官方提供的视频文件中,几乎都没有背景音乐,所以我在QQ音乐中下载了这个Country Road的MV测试使用,各位可以随意找一个带音乐的视频文件替换。
好了,这一节就到这里,下一节我们讲元素的位移和补间动画。