Phaser — это игровая среда HTML5 для настольных и мобильных устройств. Это быстро, бесплатно и с открытым исходным кодом. Phaser в настоящее время находится в версии 2.0.7 . Он поддерживает как WebGL, так и Canvas. Он имеет множество функций, которые помогут вам в разработке игр. Это похоже на игровую инфраструктуру Flixel для ActionScript 3. В этой статье мы Phaser.State
игровой скелет с помощью Phaser, используя Phaser.State
. Для простоты мы не будем использовать игровые объекты Phaser, такие как спрайты или группы. Я также немного упомяну о подростках.
Установка Phaser
Phaser доступен через bower с помощью следующей команды:
bower install phaser-official --save
Кроме того, вы можете получить файлы непосредственно из GitHub . Полная версия Phaser находится в каталоге build
. Есть также настраиваемые сборки, такие как Phaser без физического движка, расположенные в каталоге build/custom
.
Есть много уроков и руководств по началу работы. Я предлагаю вам ознакомиться с некоторыми из них, чтобы познакомиться с Phaser. Один из моих любимых — серия из четырех частей о Flappy Bird . Обширная коллекция учебных пособий, примеров и документации доступна на официальном сайте Phaser .
Леса Фазер
Генератор Yeoman на базе Grunt для Phaser доступен для строительных лесов. Вы можете установить его с помощью следующих команд:
npm install -g generator-phaser-official yo phaser-official
Этот генератор отлично подходит для быстрой настройки и запуска, однако для целей данного руководства мы начнем с нуля.
Структура каталога Phaser
Наш проект 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
. Состояние Phaser заключает в себе различные состояния вашей игры. Примерами состояний игры являются предварительная загрузка, главное меню, уровень 1, уровень 2, помощь, пауза и т. Д. Когда состояние начинается, вы создаете игровые объекты, соответствующие этому состоянию. Позже вы можете переключиться в другое состояние, и Phaser очистит ваши старые игровые объекты, чтобы вы могли создавать новые игровые объекты и отображать их.
Вы определяете состояние, определяя объект с помощью некоторых методов подключения . Важными из них являются:
-
init
— метод, вызываемый при запуске состояния. Передается аргумент, позволяющий обмениваться данными между состояниями. -
preload
— метод, вызываемый при начале состояния. Он используется для загрузки активов прежде всего. -
create
— метод, вызываемый послеpreload
, используемый для создания игровых объектов. -
update
— метод, вызываемый для каждого кадра, который используется для опроса пользователей и обнаружения коллизий. -
shutdown
— метод, вызываемый при выключении состояния, который используется для очистки игровых объектов.
Организационный поток государства
Это диаграмма состояний для наших состояний фазера. Состояния Boot
и Preload являются состояниями defacto для настройки конфигурации и загрузки игровых ресурсов. Состояние MainMenu
предназначено для отображения главного меню. Другие состояния уровней предназначены для реального игрового процесса и переключения между различными уровнями и раундами. Уровни разбиты на раунды. Каждый уровень имеет несколько раундов, которые после игры позволяют перейти на следующий уровень.
Состояния игры
Состояние загрузки загружает ресурсы предварительного загрузчика в методе ловушки preload
и устанавливает параметры игры Phaser, такие как масштабирование и указатели ввода, через метод create
.
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
параметр 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
, передавая данные levelData
, полученные в первую очередь от level-master
.
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 ->
Вы можете выйти из этого цикла в состоянии level-round
с помощью действия, которое переключается в состояние main-menu
.
Фазер запуска
Теперь мы запустим игру Phaser. Поместите этот 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. Phaser предоставляет множество других вещей, таких как спрайты, анимация, звуки, физика, масштабирование и многое другое. Вы можете найти репозиторий для нашего примера на GitHub .