从零到一:用Phaser.js写意地开发小游戏(Chapter 3

来源:互联网 发布:linux赋予用户组权限 编辑:程序博客网 时间:2024/06/08 19:25

上一节我们搭建了游戏的骨架,添加了四个游戏场景,分别是加载、开始、游戏、结束。那么这一节我们来介绍加载这个场景,顺带丰富一下各个场景的基本内容。

Phaser.Loader

Phaser框架自带的一个loader,支持加载多种类型的资源,下面是离线文档中的介绍的截图,详细的API可以查阅文档得知。

介绍几个常用的加载资源的方法:(下列代码中的game默认为Phaser实例,通过new Phaser.Game赋值)

加载图片
game.load.image('star''star.png');
加载音频
game.load.audio('bg''bg.mp3)');
加载图片序列

由于要指定帧的宽高,因此一般是动画的连续帧,例如行走动画的每一帧合成的图片。

game.load.spritesheet('walk''walk.png'8080);
加载资源集合

同样可以用作加载图片序列,但这种用法主要用于加载类似于TexturePacker打包出来的资源集合。相比于spritesheet一般是一连串的动画帧合成的图片,这种资源集合中的图片可以是各种各样的,和我们平常做网站会将icon、背景图片等合成sprites一个道理。
打包出来的资源一般包括一个json和一张合成的图片,json描述了合成图片中每张图片的宽高位置等信息。

game.load.altasJSONArray('fly''fly.png', 'fly.json');

正式开始

第一步:加载你需要的资源

上一节我们提过每个场景都有自己的生命周期,因此加载资源的操作应放在preload这个阶段执行。当preload中的资源加载完毕后,则preload场景将进入create阶段,示例代码如下:

// 加载场景preload: function() {    this.preload = function() {        // 设置背景为黑色        game.stage.backgroundColor = '#000000';        // 加载游戏资源        game.load.crossOrigin = 'anonymous'; // 设置跨域        game.load.image('bg', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bg.png');        game.load.image('dude', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/dude.png');        game.load.image('green', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/green.png');        game.load.image('red', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/red.png');        game.load.image('yellow', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/yellow.png');        game.load.image('bomb', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bomb.png');        game.load.image('five', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/five.png');        game.load.image('three', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/three.png');        game.load.image('one', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/one.png');        game.load.audio('bgMusic', '//24haowan-cdn.shanyougame.com/pickApple2/assets/audio/bgMusic.mp3');    },    this.create = function() {        alert('加载完毕!');    }}

示例代码:https://jsfiddle.net/Vincent_...

// 实际应用场景改为window.innerWidth和window.innerHeight。// 这里是为了方便查看示例。var width = 320;var height = 568;// 创建游戏实例var game = new Phaser.Game(width, height, Phaser.AUTO, '#game');// 定义场景var states = {// 加载场景    preload: function() {    this.preload = function() {            // 设置背景为黑色            game.stage.backgroundColor = '#000000';            // 加载游戏资源            game.load.crossOrigin = 'anonymous'; // 设置跨域            game.load.image('bg', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bg.png');            game.load.image('dude', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/dude.png');            game.load.image('green', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/green.png');            game.load.image('red', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/red.png');            game.load.image('yellow', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/yellow.png');            game.load.image('bomb', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bomb.png');            game.load.image('five', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/five.png');            game.load.image('three', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/three.png');            game.load.image('one', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/one.png');            game.load.audio('bgMusic', '//24haowan-cdn.shanyougame.com/pickApple2/assets/audio/bgMusic.mp3');        },        this.create = function() {            alert('加载完毕!');        }    },    // 开始场景    created: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#777';setTimeout(function() {game.state.start('play');}, 3000);        }    },    // 游戏场景    play: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#444';setTimeout(function() {game.state.start('over');}, 3000);        }    },    // 结束场景    over: function() {    this.create = function() {        // TO-DO            game.stage.backgroundColor = '#000';            alert('游戏结束!');        }    }};// 添加场景到游戏示例中Object.keys(states).map(function(key) {game.state.add(key, states[key]);});// 启动游戏game.state.start('preload');


第二步:监听加载完成的事件

通常来说我们都需要反馈加载进度,例如一个进度条,或者是一个百分比的数字。于是我们接下来就需要监听加载完成的事件了。

// 监听加载完毕事件game.load.onLoadComplete.add(function() {    alert('加载完毕!');});

如果我们需要监听到加载的进度,那么可以用下面的方法:

// 添加进度文字var progressText = game.add.text(game.world.centerX, game.world.centerY, '0%', {    fontSize: '60px',    fill: '#ffffff'});progressText.anchor.setTo(0.5, 0.5); // 设置锚点,用于居中// 监听加载完一个文件的事件game.load.onFileComplete.add(function(progress) {    progressText.text = progress + '%';});

示例代码: https://jsfiddle.net/Vincent_...

// 实际应用场景改为window.innerWidth和window.innerHeight。// 这里是为了方便查看示例。var width = 320;var height = 568;// 创建游戏实例var game = new Phaser.Game(width, height, Phaser.AUTO, '#game');// 定义场景var states = {// 加载场景    preload: function() {    this.preload = function() {            // 设置背景为黑色            game.stage.backgroundColor = '#000000';            // 加载游戏资源            game.load.crossOrigin = 'anonymous'; // 设置跨域            game.load.image('bg', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bg.png');            game.load.image('dude', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/dude.png');            game.load.image('green', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/green.png');            game.load.image('red', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/red.png');            game.load.image('yellow', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/yellow.png');            game.load.image('bomb', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bomb.png');            game.load.image('five', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/five.png');            game.load.image('three', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/three.png');            game.load.image('one', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/one.png');            game.load.audio('bgMusic', '//24haowan-cdn.shanyougame.com/pickApple2/assets/audio/bgMusic.mp3');            // 添加进度文字            var progressText = game.add.text(game.world.centerX, game.world.centerY, '0%', {                fontSize: '60px',                fill: '#ffffff'            });            progressText.anchor.setTo(0.5, 0.5);            // 监听加载完一个文件的事件            game.load.onFileComplete.add(function(progress) {                progressText.text = progress + '%';            });            // 监听加载完毕事件            game.load.onLoadComplete.add(function() {                alert('加载完毕!');            });        },        this.create = function() {            // game.state.start('created');        }    },    // 开始场景    created: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#777';setTimeout(function() {game.state.start('play');}, 3000);        }    },    // 游戏场景    play: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#444';setTimeout(function() {game.state.start('over');}, 3000);        }    },    // 结束场景    over: function() {    this.create = function() {        // TO-DO            game.stage.backgroundColor = '#000';            alert('游戏结束!');        }    }};// 添加场景到游戏示例中Object.keys(states).map(function(key) {game.state.add(key, states[key]);});// 启动游戏game.state.start('preload');


第三步:添加加载页的最小展示时间

一般而言,我们做游戏都会在loading界面放一个LOGO,作为展示宣传用,那么如果需要加载的资源体积很小的话,有可能加载界面就是一闪而过了。于是,根据我们开发的经验,会设置一个最小的展示时间(例如3秒),在未到最小的展示时间前,即便资源已经加载完毕,也不会离开加载场景。

// 监听加载完毕事件game.load.onLoadComplete.add(onLoad);// 最小展示时间,示例为3秒var deadLine = false;setTimeout(function() {    deadLine = true;}, 3000);// 加载完毕回调方法function onLoad() {    if (deadLine) {        // 已到达最小展示时间,可以进入下一个场景        game.state.start('created');    } else {        // 还没有到最小展示时间,1秒后重试        setTimeout(onLoad, 1000);    }}

示例代码:https://jsfiddle.net/Vincent_...

// 实际应用场景改为window.innerWidth和window.innerHeight。// 这里是为了方便查看示例。var width = 320;var height = 568;// 创建游戏实例var game = new Phaser.Game(width, height, Phaser.AUTO, '#game');// 定义场景var states = {// 加载场景    preload: function() {    this.preload = function() {            // 设置背景为黑色            game.stage.backgroundColor = '#000000';            // 加载游戏资源            game.load.crossOrigin = 'anonymous'; // 设置跨域            game.load.image('bg', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bg.png');            game.load.image('dude', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/dude.png');            game.load.image('green', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/green.png');            game.load.image('red', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/red.png');            game.load.image('yellow', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/yellow.png');            game.load.image('bomb', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bomb.png');            game.load.image('five', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/five.png');            game.load.image('three', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/three.png');            game.load.image('one', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/one.png');            game.load.audio('bgMusic', '//24haowan-cdn.shanyougame.com/pickApple2/assets/audio/bgMusic.mp3');            // 添加进度文字            var progressText = game.add.text(game.world.centerX, game.world.centerY, '0%', {                fontSize: '60px',                fill: '#ffffff'            });            progressText.anchor.setTo(0.5, 0.5);            // 监听加载完一个文件的事件            game.load.onFileComplete.add(function(progress) {                progressText.text = progress + '%';            });            // 监听加载完毕事件            game.load.onLoadComplete.add(onLoad);            // 最小展示时间,示例为3秒            var deadLine = false;            setTimeout(function() {                deadLine = true;            }, 3000);            // 加载完毕回调方法            function onLoad() {                if (deadLine) {                    // 已到达最小展示时间,可以进入下一个场景                    game.state.start('created');                } else {                    // 还没有到最小展示时间,1秒后重试                    setTimeout(onLoad, 1000);                }            }        }    },    // 开始场景    created: function() {    this.create = function() {            // 添加背景            var bg = game.add.image(0, 0, 'bg');            bg.width = game.world.width;            bg.height = game.world.height;        }    },    // 游戏场景    play: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#444';setTimeout(function() {game.state.start('over');}, 3000);        }    },    // 结束场景    over: function() {    this.create = function() {        // TO-DO            game.stage.backgroundColor = '#000';            alert('游戏结束!');        }    }};// 添加场景到游戏示例中Object.keys(states).map(function(key) {game.state.add(key, states[key]);});// 启动游戏game.state.start('preload');


顺带丰富一下开始场景吧
// 开始场景created: function() {    this.create = function() {        // 添加背景        var bg = game.add.image(0, 0, 'bg');        bg.width = game.world.width;        bg.height = game.world.height;        // 添加标题        var title = game.add.text(game.world.centerX, game.world.height * 0.25, '小恐龙接苹果', {            fontSize: '40px',            fontWeight: 'bold',            fill: '#f2bb15'        });        title.anchor.setTo(0.5, 0.5);        // 添加提示        var remind = game.add.text(game.world.centerX, game.world.centerY, '点击任意位置开始', {            fontSize: '20px',            fill: '#f2bb15'        });        remind.anchor.setTo(0.5, 0.5);        // 添加主角        var man = game.add.sprite(game.world.centerX, game.world.height * 0.75, 'dude');        var manImage = game.cache.getImage('dude');        man.width = game.world.width * 0.2;        man.height = man.width / manImage.width * manImage.height;        man.anchor.setTo(0.5, 0.5);        // 添加点击事件        game.input.onTap.add(function() {            game.state.start('play');        });    }}

示例代码中使用了input的onTap事件,那么input实际上还有其他事件,例如下图中框住的就是我们最常用的几个事件:

  • onDown - 对应touchstart/mousedown

  • onUp - 对应touchend/mouseup

  • onHold - 封装了长按事件的实现

  • onTap - 封装了点击事件的实现

另外还有滑动事件:

示例代码:https://jsfiddle.net/Vincent_...

// 实际应用场景改为window.innerWidth和window.innerHeight。// 这里是为了方便查看示例。var width = 320;var height = 568;// 创建游戏实例var game = new Phaser.Game(width, height, Phaser.AUTO, '#game');// 定义场景var states = {// 加载场景    preload: function() {    this.preload = function() {            // 设置背景为黑色            game.stage.backgroundColor = '#000000';            // 加载游戏资源            game.load.crossOrigin = 'anonymous'; // 设置跨域            game.load.image('bg', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bg.png');            game.load.image('dude', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/dude.png');            game.load.image('green', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/green.png');            game.load.image('red', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/red.png');            game.load.image('yellow', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/yellow.png');            game.load.image('bomb', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/bomb.png');            game.load.image('five', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/five.png');            game.load.image('three', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/three.png');            game.load.image('one', '//24haowan-cdn.shanyougame.com/pickApple2/assets/images/one.png');            game.load.audio('bgMusic', '//24haowan-cdn.shanyougame.com/pickApple2/assets/audio/bgMusic.mp3');            // 添加进度文字            var progressText = game.add.text(game.world.centerX, game.world.centerY, '0%', {                fontSize: '60px',                fill: '#ffffff'            });            progressText.anchor.setTo(0.5, 0.5);            // 监听加载完一个文件的事件            game.load.onFileComplete.add(function(progress) {                progressText.text = progress + '%';            });            // 监听加载完毕事件            game.load.onLoadComplete.add(onLoad);            // 最小展示时间,示例为3秒            var deadLine = false;            setTimeout(function() {                deadLine = true;            }, 3000);            // 加载完毕回调方法            function onLoad() {                if (deadLine) {                    // 已到达最小展示时间,可以进入下一个场景                    game.state.start('created');                } else {                    // 还没有到最小展示时间,1秒后重试                    setTimeout(onLoad, 1000);                }            }        }    },    // 开始场景    created: function() {    this.create = function() {            // 添加背景            var bg = game.add.image(0, 0, 'bg');            bg.width = game.world.width;            bg.height = game.world.height;            // 添加标题            var title = game.add.text(game.world.centerX, game.world.height * 0.25, '小恐龙接苹果', {                fontSize: '40px',                fontWeight: 'bold',                fill: '#f2bb15'            });            title.anchor.setTo(0.5, 0.5);            // 添加提示            var remind = game.add.text(game.world.centerX, game.world.centerY, '点击任意位置开始', {                fontSize: '20px',                fill: '#f2bb15'            });            remind.anchor.setTo(0.5, 0.5);            // 添加主角            var man = game.add.sprite(game.world.centerX, game.world.height * 0.75, 'dude');            var manImage = game.cache.getImage('dude');            man.width = game.world.width * 0.2;            man.height = man.width / manImage.width * manImage.height;            man.anchor.setTo(0.5, 0.5);            // 添加点击事件            game.input.onTap.add(function() {                game.state.start('play');            });        }    },    // 游戏场景    play: function() {    this.create = function() {            // TO-DOgame.stage.backgroundColor = '#444';setTimeout(function() {game.state.start('over');}, 3000);        }    },    // 结束场景    over: function() {    this.create = function() {        // TO-DO            game.stage.backgroundColor = '#000';            alert('游戏结束!');        }    }};// 添加场景到游戏示例中Object.keys(states).map(function(key) {game.state.add(key, states[key]);});// 启动游戏game.state.start('preload');


现在,开始界面是这样子的:

小结

这一节我们介绍了加载场景,分步骤介绍了加载资源、监听加载完成的事件以及添加一个最小的加载展示时间,其中“添加一个最小的加载展示时间”是偏实际应用的内容,非必须。

在文章的最后我们还向场景中加入了主角、背景、标题和开始提示等元素,来丰富开始场景。顺带一说,这次的示例是做一个接苹果的游戏,一句话说完就是控制主角接住每一个从天上掉下来的苹果,否则就算输。

那么如何利用这些资源构建出游戏的玩法,苹果怎么掉,怎么控制主角等等,将是下一节的内容。

未完待续

原创粉丝点击