Phaser是适用于台式机和移动设备的HTML5游戏框架。 它是快速,免费和开源的。 Phaser当前版本为2.0.7 。 它同时支持WebGL和Canvas。 它具有许多功能,可帮助您进行游戏开发。 就像ActionScript 3的Flixel游戏框架一样。在本文中,我们将使用Phaser.State
使用Phaser构建游戏框架。 为简单起见,我们将不使用任何Phaser游戏对象,例如精灵或组。 我还将提到一些关于补间的内容。
安装相位器
使用以下命令,可以通过Bower使用Phaser:
bower install phaser-official --save
或者,您可以直接从GitHub抓取文件。 Phaser的完整版本在build
目录中。 在build/custom
目录中还有一些自定义的构建,例如不带物理引擎的Phaser。
有许多社区教程和入门指南。 我建议您检查其中的一些以便熟悉Phaser。 我的最爱之一是《 飞鸟》的四部分系列 。 在Phaser官方网站上可以找到大量的教程, 示例和文档 。
脚手架移相器
用于相位器的基于Grunt的Yeoman发电机可用于脚手架项目。 您可以使用以下命令进行安装:
npm install -g generator-phaser-official
yo phaser-official
该生成器非常适合快速启动和运行,但是,出于本教程的目的,我们将从头开始。
移相器目录结构
我们的Phaser项目将使用以下所示的目录结构。 main.js
开始游戏,而app.js
定义我们的Phaser应用程序。 prefabs
目录用于游戏对象,而states
目录用于游戏状态。
|-- app.js
|-- main.js
|-- prefabs
`-- states
|-- boot.js
|-- level_intro.js
|-- level_master.js
|-- level_round.js
|-- main_intro.js
|-- main_menu.js
`-- preload.js
如果要在这些文件中添加纯script
标记,则必须注意它们的包含顺序。 我更喜欢使用RequireJS,另一种替代方法是Browserify。
Phaser.State
本节将重点介绍Phaser.State
的使用。 移相器状态封装了游戏的不同状态。 游戏状态的示例包括预加载,主菜单,级别1,级别2,帮助,暂停等。状态开始时,您将创建与该状态相关的游戏对象。 稍后,您可以切换到其他状态,Phaser会清理您的旧游戏对象,以便您可以创建新游戏对象并显示它们。
您可以通过使用某些hook方法定义对象来定义状态。 重要的是:
-
init
–状态开始时调用的方法。 传递了一个参数以启用状态之间的数据共享。 -
preload
–状态开始时调用的方法。 它用于先加载资产。 -
create
–在preload
之后调用的方法,用于创建游戏对象。 -
update
–为每个帧调用的方法,用于用户轮询和冲突检测。 -
shutdown
–一种shutdown
状态时调用的方法,用于清理游戏对象。
组织状态流
这是我们相位器状态的状态图。 Boot
和Preload
状态是用于设置配置和加载游戏资产的实际状态。 MainMenu
状态用于显示主菜单。 其他关卡状态则用于实际游戏并在不同关卡和回合之间切换。 这些级别分为几轮。 每个关卡都有一些回合,一旦播放,您就可以进入下一个关卡。
游戏状态
引导状态通过preload
hook方法加载预加载器资产,并通过create
方法设置Phaser游戏设置,例如缩放比例和输入指针。
File: states/boot.js
function Boot() {};
Boot.prototype = {
preload: function() {
// load preloader assets
},
create: function() {
// setup game environment
// scale, input etc..
this.game.state.start('preload');
}
};
Preload状态将加载所有游戏资产,然后切换到main-intro
状态。
File: states/preload.js
Preload.prototype = {
preload: function() {
// load all game assets
// images, spritesheets, atlases, audio etc..
},
create: function() {
this.game.state.start('main-intro');
}
};
MainIntro状态显示游戏的简介,徽标,信用等。它不需要preload
方法,因为它会在对象之间补间两秒钟,然后切换到main-menu
状态。 我在此处添加了一个补间,只是为了让您了解,您可以使用淡入淡出,缩小和滑动等效果来过渡对象,以实现状态转换效果。
File: states/main_intro.js
function MainIntroState() {};
MainIntroState.prototype = {
create: function() {
// add main intro assets into the world
this.tweenFadeState();
},
tweenFadeState: function() {
this.game.add.tween({})
.to({alpha: 1}, 2000)
.onComplete.add(function() {
this.game.state.start('main-menu');
}, this);
}
};
MainMenu状态显示主菜单。 然后,用户可以与菜单中的项目进行交互。 为简单起见,我添加了一个键盘事件,该事件将触发一系列补间,最后切换到level-master
状态。 补间链接对于合并动画(如缩小菜单然后使显示淡入淡出)很有用。
File: states/main_menu.js
MainMenuState.prototype = {
create: function() {
this.enterKey = this.game.input.keyboard
.addKey(Phaser.Keyboard.ENTER);
this.enterKey.onDown.add(this.tweenPlayState, this);
},
tweenPlayState: function() {
var tweenMenuShrink = this.game.add.tween({})
.to({x: 0, y: 0}, 200);
var tweenFadeIn = this.game.add.tween({})
.to({alpha: 1}, 2000);
tweenFadeIn.onComplete.add(function() {
this.game.state.start('level-master');
}, this);
tweenMenuShrink.chain(tweenFadeIn);
tweenMenuShrink.start();
}
};
注意,在示例中,我没有补间任何有用的东西。 为简单起见,您应该在此处插入游戏对象。 另外,我不创建任何游戏对象,但是您可以在create
方法中进行操作。 有关更多信息,请查看Phaser示例和文档。
LevelMaster状态是无头状态,它决定要切换到哪个状态。 它不会在游戏世界上显示任何内容。 唯一的目的是决定是否应该切换到level-round
状态或level-intro
状态,最重要的是,它会在状态之间更新并传递游戏数据( this.levelData
)。
File: states/level_master.js
LevelMasterState.prototype = {
init: function(levelData) {
if (!levelData) {
levelData = {
level: 0,
round: 1,
players: [
{ score: 0, skill: 1 },
{ score: 0, skill: 1 }
]
};
}
this.levelData = levelData;
this.winScore = 2;
},
create: function() {
this.decideLevelState();
}
};
当新级别开始时, level-intro
状态开始。 level-intro
状态显示新级别的介绍,例如显示您所在的级别。 在level-intro
,它会切换到level-round
,这是实际玩游戏的地方。
一轮结束后,它是一个新的level-round
或一个新的水平。 这种逻辑发生在我们的decideLevelState
函数中。 如果是第一个级别,或者我们有一个级别的获胜者,我们将切换到下一个级别,否则我们将切换到下一个回合。
this.levelData
保存游戏数据,例如游戏级别,游戏回合和玩家得分。 我们按照逻辑更新它并传递状态。
File: states/level_master.js
LevelMasterState.prototype = {
decideLevelState: function() {
if (this.isFirstLevel() || this.getWinningPlayer() !== -1) {
this.nextLevel();
} else {
this.nextRound();
}
},
nextLevel: function() {
this.levelData.level++;
this.levelData.players.forEach(function(p) {
p.score = 0;
}, this);
this.levelData.round = 1;
this.game.state.start('level-intro', true, false, this.levelData);
},
nextRound: function() {
this.levelData.round++;
this.game.state.start('level-round', true, false, this.levelData);
}
};
LevelIntro状态显示关卡介绍信息,例如您所在的关卡以及一些介绍动画。 我们传递用于保存游戏数据的levelData
参数。 在create
方法中,如果是游戏的第一关,我们通过显示技能菜单来使用levelData
。 技能菜单是指玩家选择想要玩的技能的菜单,但这取决于您。 最后,它切换到level-round
状态。
File: states/level_intro.js
LevelIntroState.prototype = {
init: function(levelData) {
this.levelData = levelData;
},
create: function() {
var tweenIntro = this.tweenIntro();
if (this.levelData.level === 1) {
var tweenSkillMenuPop = this.tweenSkillMenuPop();
tweenIntro.chain(tweenSkillMenuPop);
tweenSkillMenuPop.onComplete.add(this.levelStart, this);
} else {
tweenIntro.onComplete.add(this.levelStart, this);
}
},
levelStart: function() {
this.game.state.start('level-round', true, false, this.levelData);
},
tweenIntro: function() {
var tween = this.game.add.tween({})
.to({alpha: 0}, 1000, Phaser.Easing.Linear.None, true);
return tween;
},
tweenSkillMenuPop: function() {
var tween = this.game.add.tween({})
.to({x: 1, y: 1}, 500, Phaser.Easing.Linear.None, true);
return tween;
}
};
最后, LevelRound状态是实际玩游戏的地方。 如果需要,可以使用其update
方法。 为简单起见,我添加了一个简单的按键交互操作,该交互操作在按Enter键时结束状态。 这里重要的一点是,它会切换回level-master
,首先传递它从level-master
获得的levelData
。
File: states/level_round.js
LevelRoundState.prototype = {
init: function(levelData) {
this.levelData = levelData;
},
create: function() {
this.enterKey = this.game.input.keyboard
.addKey(Phaser.Keyboard.ENTER);
this.enterKey.onDown.add(this.roundEnd, this);
},
roundEnd: function() {
this.nextRound();
},
nextRound: function() {
this.game.state.start('level-master', true, false, this.levelData);
}
};
这样就完成了状态流。 所有这些为我们提供了一个水平状态循环,看起来像这样:
Boot -> Preload ->
main-intro -> main-menu ->
level-master -> Level1 ->
level-master -> L1 Round1 ->
level-master -> L1 Round2 ->
level-master -> Level2 ->
level-master -> L2 Round1 ->
您可以通过切换到main-menu
状态的操作在level-round
状态中退出此循环。
启动相位器
现在,我们将开始“移相器”游戏。 将此div
放在您的页面内。 移相器会将画布放在那里。
File index.html
<div id="game-area"></div>
我们必须创建一个Phaser.Game
,将所有状态添加到StateManager
,然后启动启动状态。
File: app.js
function Game() {}
Game.prototype = {
start: function() {
var game = new Phaser.Game(640, 480, Phaser.AUTO, 'game-area');
game.state.add('boot', BootState);
game.state.add('preload', PreloadState);
game.state.add('main-intro', MainIntroState);
game.state.add('main-menu', MainMenuState);
game.state.add('level-master', LevelMasterState);
game.state.add('level-intro', MainIntroState);
game.state.add('level-round', LevelRoundState);
game.state.start('boot');
}
};
最后,使用以下代码启动游戏。
File: main.js
var game = new Game();
game.start();
结论
Phaser.State
我们的Phaser.State
文章结束了。 这只是Phaser游戏的骨架。 Phaser为您提供了许多其他功能,例如精灵,动画,声音,物理效果,缩放等。 您可以在GitHub上找到我们示例的存储库。
From: https://www.sitepoint.com/javascript-game-programming-using-phaser/