Оглавление
0. Подготовка к работе
1. Введение [Вы тут
]
2. Загрузка ресурсов
3. Создание игрового мира
4. (wip) Группы
5. (wip) Мир физики
6. (wip) Управление
7. (wip) Добавление целей
8. (wip) Последние штрихи
Добро пожаловать в наш первый урок по созданию игр на Phaser. Здесь я расскажу вам, как создать небольшую игру — платформер, которая познакомит вас с основными функциями данного фремворка и работу с ним в нынешних реалиях (ES6 / TypeScript + WebPack).
Что такое Phaser?
Phaser — это HTML5 (JavaScript / TypeScript) игровой фреймворк, который призван помочь разработчикам создавать крутые, кросс-браузерные HTML5 игры в короткие сроки и, в отличии от других фреймворков, phaser изначально затачивался под мобильные устройства. Единственное требование выдвигаемое данным фреймворком — поддержка тега <canvas />
. Он также много чего унаследовал от Flixel.
Требование
Исходный код данного урока и ресурсы игры лежат в этом Github репозитории с тегом part-1
(каджый тег соответствует номеру урока). Если вы уже склонировали этот репозиторый себе, начните изучение с src/index.ts
.
Вам потребуются базовые знания TypeScript'а (или ES6), а также установленный Node.js для сборки проекта (я рекомендую, на момент публикации данной статьи, ставить 6
'ую версию).
Когда вы склонируете себе репозиторий, не забудьте установить NPM
пакеты:
npm i
# Или через Yarn
npm i -g yarn
yarn
npm rebuild # в некоторых случаях Yarn не собирает C++ пакеты, и нужно их собрать с помощью данной команды
После установки, запустите Webpack Dev Server (сервер будет слушать на http://127.0.0.1:8080):
npm start
Откройте src/index.ts
в вашем любимом редакторе, и давайте ознакомимся с кодом.
Каркас приложения выглядит так:
'use strict';
/** Imports */
// Подключение глобальных зависимостей. (Напомню, они будут собраны webpack'ом в отдельный файл).
require('pixi'); // Из-за структуры кода Phaser'а, PIXI и p2 должны быть глобальными объектами
require('p2');
require('phaser'); // Так-же, в моем случае, TypeScript ломается, если подключить эту библиотеку как `import 'phaser';`
import 'styles/style.styl'; // Регистрация стилей для страницы; добавятся автоматически
// Главное состояни ("стейт") нашей игры
export class MainState extends Phaser.State {
preload(): void { }
create(): void { }
update(): void { }
}
// Основной класс нашего приложения
export default class App extends Phaser.Game {
constructor(config: Phaser.IGameConfig) {
super(config);
this.state.add('main', MainState); // Регистрируем "состояние" игры
this.state.start('main'); // Инициализируем и запуск это состояния
}
}
// Аля python'овский `__name__ == "__main__"`, нужен для проверки является ли
// данный модуль частью другой программы или он исполняемый.
if (!module.parent) {
window.onload = () => {
const config: Phaser.IGameConfig = {
width: 800, // Выста canvas'а
height: 600, // Ширина canvas'а
renderer: Phaser.AUTO, // Движок отрисовки, рекомендуется оставить AUTO
parent: '',
resolution: 1,
forceSetTimeOut: false // насильственное использование setTimeout
};
new App(config); // инициализация приложения. Оно автоматически вставит Canvas в корень разметки
};
}
На строках 4-6
мы регистрируем глобальные зависимости для нашего приложения. Как уже было сказано выше, из-за архитектуры Phaser'а (на момент написания статьи v2.6.2), эти 3 библиотеки должны быть именно глобальными (глобальными мы их делаем на этапе сборки, в Webpack). Также TypeScript (v2.2.1) почему-то ломается если их подключить через import
, а не через require
, ну и черт с ним.
На 22
'ой строке, мы наследуем класс Phaser.Game
, и регистрируем в его конструкторе состояние main
нашей игры.
Сам же конструктор main
стейта мы создаем на 12
'ой строке, и наследуем его от Phaser.State
. У этого класса есть 3 основных публичных метода (на деле гораздо больше, но эти самые часто используемые):
preload(): void
— нужен для загрузки ресурсов игры: спрайты, звуки, json-данные и т.д.create(): void
— в нем инициализируются стартовые (и неизменяемые) параметры игры: установка фона, генерация карты, создание объектов и пр.update(): void
— метод, вызываемый при каждом тике игры (т.е. фактически на каждую смену кадра).
В дальнейшем, именно в них мы будем создавать основную логику нашей игры.
И наконец, 36
'ая строка, на ней мы создаем объект конфигурации для нашего приложения, и на 45
'ой строки запускаем его.
Основные свойства:
width
— высота игрового мира.height
— ширина игрового мира.renderer
— движок отрисовки. Выбор метода рендера изображения (Canvas
илиWebGL
), мы же выбралиPhaser.AUTO
, что-бы фреймворк сам выбрал доступный движок для браузера. В случае, если браузер не поддерживаетWebGL
, произойдет fallback доCanvas
.parent
— HTML элемент или селектор элемента, куда будет вставлен<canvas />
. По умолчанию (при''
), canvas вставится в<body />
.resolution
— разрешение игры.forceSetTimeOut
— заставит Phaser использоватьsetTimeout
вместоrequestAnimationFrame
. В нашем случае это не нужно.
Остальные свойства вы найдете тут.
Если вы все сделали верно, вы увидите следующее:
И судя по данной строке, браузер поддерживает WebGL
и WebAudio
:
Github Repo: https://github.com/SuperPaintman/phaser-typescript-tutorial