javascript

Создание вашей первой игры на Phaser. Часть 1 — Введение

  • вторник, 28 марта 2017 г. в 03:15:02
https://habrahabr.ru/post/324896/
  • Разработка игр
  • WebGL
  • JavaScript
  • HTML
  • Canvas


Phaser


Оглавление


0. Подготовка к работе
1. Введение [Вы тут]
2. (wip) Загрузка ресурсов
3. (wip) Создание игрового мира
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. В нашем случае это не нужно.

Остальные свойства вы найдете тут.


Если вы все сделали верно, вы увидите следующее:


Screenshot 1


И судя по данной строке, браузер поддерживает WebGL и WebAudio:


Screenshot 2


Github Repo: https://github.com/SuperPaintman/phaser-typescript-tutorial


К содержанию