本文中phaser具体版本 phaser2:2.8.1
phaser3:3.17.0html
这个demo实际上是以前学习phaser2的时候作的,如今用来改为phaser3,恰好能够接触一下新的API变更有多大。
按照游戏实现的逻辑顺序,下面捋一捋用到的Phaser3 API,同时也与Phaser2 API进行简单对比。git
new Phaser.Game
初始化画布参数,包括画布宽高,渲染方式,并将其插入dom结构中。phaser3中用scenes替代了phaser2中的states,为了不与state machines概念混淆。
游戏中的一个scene是一个独立的场景,拥有本身的独立资源,包括相机系统、显示列表、更新步骤、事件处理、物理系统等等。游戏一次只能执行一个scene,一个场景经过多个钩子函数来维护,包括init、preload、create、update等。github
// phaser 3:https://photonstorm.github.io/phaser3-docs/Phaser.Types.Core.html#.GameConfig
conf = {
width: 750,
height: 750/window.innerWidth*window.innerHeight,
type: Phaser.AUTO, // 渲染方法
parent: 'container', // 将包含游戏画布的dom元素
backgroundColor: '#f9c04c',
scale: {
mode: Phaser.Scale.FIT // 缩放模式,此处按比例调整画布大小,至关于contain
},
scene: { // 初始化场景,游戏最开始状态
init: function(){
// 当场景开始时第一个执行,能够用于初始化变量或重定向到其余场景
},
preload: function(){
// 第二个执行的函数,预加载游戏资源,不会在这里建立对象
},
create: function(){
// 当preload完成以后执行,preload的资源加载完成,能够在这里建立对象
},
update: function(){
// 画布更新,在游戏的每一帧都执行
},
// ...... 其余函数
}
}
game = new Phaser.Game(conf);
// phaser 2:http://phaser.io/docs/2.6.2/Phaser.Game.html
game = new Phaser.Game(750, 750/window.innerWidth*window.innerHeight, Phaser.AUTO, 'container',
{ // 初始化场景,游戏最开始状态
init: function(){
// 当场景开始时第一个执行,能够用于初始化变量或重定向到其余场景
},
preload: function(){
// 第二个执行的函数,预加载游戏资源,不会在这里建立对象
},
create: function(){
// 当preload完成以后执行,preload的资源加载完成,能够在这里建立对象
},
update: function(){
// 画布更新,在游戏的每一帧都执行
},
// ...... 其余函数
})
复制代码
预加载资源操做通常在preload
函数中执行,这一部分的API,phaser2和phaser3基本一致,不过phaser3对游戏对象结构进行了修改,phaser2中是树状结构,游戏中全部对象都来自于根对象Phaser.Game
,对象也拥有本身的子对象。phaser3中将这些对象拆解出来,游戏对象Phaser.Game
不包含其余对象组,且对象组不具备任何的位置或者属性。json
// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Loader.LoaderPlugin.html
preload: function () {
console.log("start loading ...");
this.numbersJson = require('../json/numbers.json');
// loader挂载在Phaser.Scene下
this.load.image('bg', './img/holes-bg.png');
this.load.image('hamster', './img/hamster.png');
this.load.image('hammer', './img/hammer.png');
this.load.image('lightning', './img/lightning.png');
this.load.atlas('sprite_numbers', './img/numbers.png', this.numbersJson);
this.load.on('complete', loadProgress);
function loadProgress(loader, finishedNum) {
console.log(`${finishedNum}个资源加载完毕,能够开始游戏了!`);
$(".cjy_panel .start_btn").click(function () {
// 移除开始界面
$(".cjy_panel").hide();
customGame.scene.start('play');
})
}
}
// phaser2: http://phaser.io/docs/2.6.2/Phaser.Loader.html
preload: function () {
console.log("start loading ...");
this.numbersJson = require('../json/numbers.json');
console.log(window.customGame)
// 这些属性在Phaser3中已被移除,须要经过初始化配置
window.customGame.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
window.customGame.stage.backgroundColor = '#f9c04c';
// loader挂载在Phaser.game下
window.customGame.load.image('bg', './img/holes-bg.png');
window.customGame.load.image('hamster', './img/hamster.png');
window.customGame.load.image('hammer', './img/hammer.png');
window.customGame.load.image('lightning', './img/lightning.png');
window.customGame.load.atlasJSONHash('sprite_numbers', './img/numbers.png', '', this.numbersJson);
window.customGame.load.onLoadComplete.add(loadProgress, this);
function loadProgress() {
console.log('资源加载完毕,能够开始游戏啦!')
$(".cjy_panel .start_btn").click(function () {
console.log("开始游戏!");
// 移除开始界面
$(".cjy_panel").hide();
customGame.state.start('play');
})
}
}
复制代码
建立对象操做通常在create
函数中执行,这一部分的API基本一致,差异与load
类似,都是因为修改了总体数据结构致使的。bash
// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.GameObjectCreator.html
// 对象的建立
this.hammer = this.add.sprite(hammerx, hammery, 'hammer').setOrigin(0, 0.8);
// phaser2: http://phaser.io/docs/2.6.2/Phaser.GameObjectFactory.html
this.hammer = customGame.add.sprite(hammerx, hammery, 'hammer');
this.hammer.anchor.setTo(0, 0.8);
复制代码
phaser2和phaser3都提供了内置tween动画供开发者使用,相比较于phaser2,phaser3中的tween动画配置更加灵活丰富,具体完整的配置项列表能够参照官方文档。数据结构
// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Tweens.TweenManager.html
this.tweens.add({
targets: [this.hammer],
angle: 45,
duration: 50,
callbackScope: this,
ease: 'Linear'
})
// phaser2: http://phaser.io/docs/2.6.2/Phaser.Tween.html
var rotateTween = customGame.add.tween(this.hammer);
rotateTween.to({
angle: 45
}, 50, Phaser.Easing.Cubic.In, true);
复制代码
phaser自己没有dom概念,全部的交互都须要依赖phaser自身的API,经过Phaser.Input
统一管理全部的input事件。当交互发生时,与之交互的Phaser.Game
对象将向下分发事件,phaser3能够在scene/gameObject中监听该事件,不一样的位置监听事件其做用域不一样,优先级也不一样,优先级较高的事件处理器可阻止向低优先级事件传递(stop propagation)。dom
// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Input.Events.html
this.input.on('pointerdown', onTap, this);
function onTap(pointer,currentlyOver) { ... }
// phaser2: http://phaser.io/docs/2.6.2/Phaser.Input.html
customGame.input.onTap.add(onTap, this);
function onTap(pointer, doubleTap) { ... }
复制代码
// phaser3: https://photonstorm.github.io/phaser3-docs/Phaser.Time.TimerEvent.html
this.time.addEvent({
loop: true,
delay: 1000,
callback: timerFn,
callbackScope: this
})
// phaser2: http://phaser.io/docs/2.6.2/Phaser.Timer.html#loop
customGame.time.events.loop(Phaser.Timer.SECOND, this.timerFn, this); //利用时钟对象来重复产生管道
customGame.time.events.start();
复制代码
一些能够改进优化的细节:ide
phaser2上手较快,API简单,官方文档示例比较丰富,值得继续探索,后续会试水一下物理引擎。phaser3是正在开发的版本,相较于phaser2 API变化较多,文档完善度不够,基本上是查源码猜API。试水过程能够感觉到phaser3对API设计从新考量,好比用对象来代替原有的基本数据类型做为函数参数,可读性和灵活性更佳。另外,phaser3加强了camera的功能,新增了对Matter.js物理引擎的支持,对2D骨骼动画的支持等等,此处不进行赘述,详细的能够查看phaser官网的具体公告,或者是参考文章 全新Phaser3游戏引擎特性一览(来自凹凸实验室) 。
关于自学:我的以为phaser API的学习方法最直观的是在控制台打印一下,尤为是对于初学者来讲,对于其中的结构没有清晰的认识,直接看文档容易混乱,具体使用也能够参照官方示例。 彩虹屁结束以后,不得不说,若是是项目实际使用,建议仍是使用稳定版本phaser2,简单的小游戏仍是够用的。函数