Advertisement
  1. Game Development
  2. 3D

Создание космического шутера с помощью PlayCanvas: часть 2

by
Read Time:14 minsLanguages:
This post is part of a series called Create a Space Shooter with PlayCanvas.
Create a Space Shooter With PlayCanvas: Part 1

Russian (Pусский) translation by Dmitriy Sirosh (you can also view the original English article)

Это вторая часть нашего квеста по созданию трехмерного космического шутера. В первой части мы посмотрели, как настроить базовую PlayCanvas игру с физикой и столкновениями, нашими собственными моделями и камерой.

Для справки ниже приведена демо-версия нашего окончательного результата.

В этой части мы сосредоточимся на динамическом создании объектов с помощью скриптов (генерации пуль и астероидов), а также как добавить такие штуки, как счетчик FPS и текст в игре. Если вы уже проработали предыдущую часть и довольны тем, что у вас есть, вы можете продолжать создавать игру из этой части и пропустить следующий раздел минимальной настройки. В противном случае, вам нужно начать с самого начала:

Минимальные настройки

  1. Начните новый проект.
  2. Удалите все объекты на сцене, за исключением Camera, Box и Light.
  3. Поместите свет (Light) и камеру (Camera) внутрь объекта Box на панели Hierarchy.
  4. Установите камеру в положение Position (0,1,5,2) и вращение Rotation (-20,0,0).
  5. Убедитесь, что объект Light помещен в подходящее положение, которое хорошо смотрится (я перенес его поверх объекта Box).
  6. Прикрепите к объекту Box компонент Rigid Body. Установите для него тип значения Dynamic. И установите его значение Damping равным 0,95 (как линейное, так и угловое).
  7. Прикрепите компонент Collision к объекту Box.
  8. Установите значение Gravity в 0 (из параметров сцены).
  9. Поместите компонент Sphere со значением (0,0,0), чтобы отметить это положение в пространстве.
  10. Создайте и прикрепите этот скрипт к объекту Box и назовите его Fly.js:

Проверьте, всё ли работает. Вы должны теперь уметь летать вперед используя клавишу Z и с помощью клавиш со стрелками вращаться!

8. Генерирование астероидов

Динамическое создание объектов имеет решающее значение для практически любого типа игр. В демонстрации, которую я создал, генерируются два вида астероидов. Первый вид - астероиды просто плавают и действуют как пассивные препятствия. Они возрождаются, когда находятся слишком далеко, чтобы создать постоянно густое астероидное поле вокруг игрока. Второй вид - они появляются издалека и двигаются к игроку (чтобы создать ощущение опасности, даже если игрок не двигается).

Для появления астероидов нам нужно три вещи:

  1. Объект AsteroidModel, из которого можно клонировать все остальные астероиды.
  2. Скрипт AsteroidSpawner, прикрепленный к корневому объекту, который будет выполнять функции фабрики/клонирования.
  3. Скрипт Asteroid для определения поведения каждого астероида.

Создание модели астероида

Создайте новый объект из выбранной вами модели. Это может быть модель из магазина PlayCanvas или что-то из BlendSwap или просто элементарная форма. (Если вы используете собственные модели, рекомендуется сначала открыть их в программе Blender, чтобы проверить количество используемых граней и, при необходимости, оптимизировать их.)

Добавьте соответствующую форму столкновения Collision и компонент Rigid Body (убедитесь, что тип значения Dynamic). Если вас все устраивает нужно снять флажок Enabled:

Where to toggle the Enabled propertyWhere to toggle the Enabled propertyWhere to toggle the Enabled property

Когда вы отключите объект, подобный этому, что эквивалентно удалению его из игрового мира, по отношению к игроку. Это полезно для временного удаления объектов или, в нашем случае, для хранения объекта со всеми его свойствами, но без его отображения в игре.

Создание скрипта генерации астероидов

Создайте новый скрипт под названием AsteroidSpawner.js и присоедините его к Root (корневому) объекту на панели Hierarchy. (Обратите внимание, что Root - это обычный объект, к которому могут быть прикреплены любые компоненты, точно так же, как и камера).

Теперь откройте только что созданный скрипт.

Общий способ клонирования объекта и добавления его в игровой мир с помощью скрипта выглядит следующим образом:

Так вы бы клонировали объект, если бы у вас уже был объект "oldEntity". Это оставляет один вопрос без ответа: как мы получаем доступ к созданной нами модели AsteroidModel?

Есть два способа сделать это. Более гибким способом является создание атрибута скрипта, который содержит объект для клонирования, поэтому можно легко поменять модели не изменяя скрипт. (Именно так мы сделали скрипт lookAt для камеры на шаге 7 в предыдущей части.)

Другой способ - использовать функцию findByName. Вы можете вызвать этот метод для любого объекта, чтобы найти любого из его потомков. Поэтому мы можем вызвать его в корневом объекте:

И это дополнит наш код сверху. Весь скрипт AsteroidSpawner теперь выглядит следующим образом:

Проверьте, что это сработало, запустив и посмотрев, существует ли ваша модель астероида.

Примечание: Я использовал newEntity.rigidbody.teleport вместо newEntity.setPosition. Если у объекта есть Rigid Body (твердое тело), тогда компонент Rigid Body будет переопределять положение и вращение объекта, поэтому не забудьте установить эти свойства для Rigid Body, а не для самого объекта.

Прежде чем перейти к следующему шагу, попробуйте сделать так, чтобы создавалось десять или более астероидов вокруг игрока, либо случайным образом, либо каким-то систематическим образом (возможно, даже по кругу?). Это поможет поместить весь код генератора в функцию, чтобы она могла выглядеть примерно так:

Создание скрипта астероида

Вам должно быть комфортно добавлять новые скрипты. Создайте новый скрипт (назовите его Asteroid.js) и добавьте его к объекту AsteroidModel. Поскольку все наши созданные астероиды являются клонами, все они будут использовать один и тот же сценарий.

Если мы создаем много астероидов, было бы неплохо убедиться, что они уничтожаются, когда они нам больше не понадобятся или когда находятся достаточно далеко. Вот один из способов сделать это:

Совет по отладке: Если вы хотите вывести отладочную информацию, вы всегда можете использовать консоль браузера, как если бы это было обычное приложение JavaScript. Так что можно сделать что-то вроде console.log(distance.toString()); чтобы вывести длину вектора, и он отобразится в консоли.

Перед тем, как двигаться дальше, убедитесь, что астероид исчезает при удалении от него.

9. Генерирование пуль

Для генерации пуль будет использоваться та же идея, что и генерирование астероидов, с одной новой концепцией: Мы хотим обнаруживать, когда пуля попала в какой-либо объект и удалять ее. Для создания пулевой системы необходимо:

  1. Модель пули для клонирования
  2. Скрипт Shoot.js для создания пуль при нажатии X.
  3. Скрипт Bullet.js для определение поведения каждой пули.

Создание модели пули

Можно использовать любую фигуру для пули. Я использовал Capsule (капсулу) только для того, чтобы иметь представление о том, в каком направлении улетела пуля. Как и прежде, создайте объект, уменьшите его масштаб и задайте для Rigid Body значение Dynamic и соответственно для Collision значение Box. Присвойте ему имя "Bullet", так чтобы было легко найти.

Когда все будет готово, обязательно отключите его (флажок Enabled).

Создаем скрипт выстрела

Создайте новый скрипт и прикрепите его к кораблю игрока. На этот раз мы собираемся использовать атрибут для получения ссылки на наш объект bullet:

Вернитесь к редактору и нажмите "Parse" для отображения нового атрибута и выберите созданный объект Bullet.

Теперь в функции обновления мы хотим:

  1. Клонировать объект и добавить в игровой мир.
  2. Применение силы в направлении, с которым сталкивается игрок.
  3. Поместить объект перед игроком.

Вы уже знакомы со всеми этими концепциями. Вы видели, как клонировать астероиды, как применять силу в направлении, чтобы заставить корабль двигаться, и как позиционировать объекты. Я оставлю реализацию этой части как вызов. (Но если вы застряли, вы всегда можете посмотреть, как я реализовал свой собственный скрипт Shoot.js в своем проекте).

Вот несколько советов, которые избавят вас от лишней головной боли.

  1. Используйте keyboard.wasPressed вместо keyboard.isPressed. При обнаружении, когда нажата клавиша X для выстрела, первый код является удобным способом срабатывания только при нажатии кнопки в противоположном случае, если кнопка удерживается.

  2. Используйте rotateLocal вместо задания абсолютного вращения. Чтобы убедиться, что пуля всегда появляется параллельно кораблю, было бы сложно правильно рассчитать углы. Гораздо проще просто установить вращение пули на вращение корабля, а затем повернуть пулю в ее локальном пространстве на 90 градусов по оси X.

Создание скрипта поведения пули

На этом этапе ваши пули должны генерироваться, попадать в астероиды и просто рикошетить в пустоту. Количество пуль может быстро стать огромным и знание того, как обнаружить столкновение, полезно для всякого рода вещей (Например вы могли заметить,что можно создавать объекты, которые имеют только компонент Сollision, но не Rigid Body. Они действовали бы как триггеры, но не реагировали бы физически.)

Создайте новый скрипт под названием Bullet и присоедините его к вашей модели Bullet, которая будет клонирована. PlayCanvas имеет три типа событий контакта. Мы будем слушать collisionend, который срабатывает, когда объекты разделяются (иначе пуля будет уничтожена до того, как астероид сможет отреагировать).

Чтобы слушать событие контакта, введите его в свою функцию init:

А затем создайте сам слушатель:

Именно здесь имя, которое вы дали своим астероидам, когда их генерировали, становится актуальным. Мы хотим, чтобы пуля разрушалась только при столкновении с астероидом. Result объект, с которым она столкнулась.

Кроме того, вы можете удалить эту проверку и просто уничтожить ее при столкновении с чем угодно.

Это правда, что нет других объектов в игровом мире, которые могли бы столкнуться, но у меня было несколько проблем раньше, с игроком, который вызвал столкновение пули в одном кадре и исчезал до того, прежде чем был запуск. Если у вас есть более сложные потребности в столкновении, PlayCanvas поддерживает группы столкновений и маски, но в момент написания статьи это не очень хорошо документировано.

10. Добавление счетчика FPS

На данный момент мы закончили с самой игрой. Конечно, есть много мелких допиленных нюансов, которые я добавил в финальное демо, но там нет ничего, что вы не сможете сделать.

Я хотел показать, как создать измеритель FPS (у PlayCanvas уже есть профилировщик; вы можете навести курсор на кнопку воспроизведения и проверить компонент), потому что это хороший пример добавления элемента DOM, который находится за пределами движка PlayCanvas.

Мы собираемся использовать эту библиотеку FPSMeter. Первое, что нужно сделать - это перейти на сайт библиотеки и загрузить урезанную версию.

Вернитесь в свой редактор PlayCanvas, создайте новый скрипт и скопируйте код fpsMeter.min.js. Прикрепите этот скрипт к объекту Root.

Теперь, когда библиотека загружена, создайте новый скрипт, который инициализирует и использует библиотеку. Назовите его meter.js и возьмем пример на веб-сайте библиотеки:

Добавьте скрипт счетчика также к объекту Root и запустите его. Вы должны увидеть счетчик FPS в левом верхнем углу экрана!

11. Добавление текста

Наконец, давайте добавим текст в наш игровой мир. Это немного связано с тем, что есть различные способы сделать это. Если вы просто хотите добавить статический UI, один из способов сделать это - работать с DOM напрямую, накладывая элементы пользовательского интерфейса поверх элемента Canvas в PlayCanvas. Другой способ - использовать SVG. В этой статье обсуждаются разные способы.

Поскольку это все стандартные способы обработки текста в Интернете, я решил вместо этого посмотреть, как создать текст, который существует в пространстве игрового мира. Так что думайте о нем, как о тексте, который будет при входе в среду или объекте в игре.

Мы делаем это путем создания материала для каждого фрагмента текста, который мы хотим отобразить. Затем мы создадим невидимый холст, который будет рендерить текст, используя привычный Canvas метод fillText. Наконец, мы рендерим холст на материале, чтобы он появился в игре.

Обратите внимание, что этот метод может использоваться не только для текста. Вы можете динамически рисовать текстуры или делать то, что может сделать холст.

Создание текстового материала

Создайте новый материал и назовите его "TextMaterial". Установите цвет diffuse черный, так как наш текст будет белым.

Создайте плоскость и присоедините к ней этот материал.

Создание текстового скрипта

Вы можете найти полный текст text.js здесь:

https://gist.github.com/OmarShehata/e016dc219da36726e65cedb4ab9084bd

Можно увидеть, как настраивается текстура для использования холста в качестве источника, в частности в строке: this.texture.setSource(this.canvas);

Создайте этот скрипт и прикрепите его к своей плоскости. Обратите внимание, как он создает два атрибута: текст и размер шрифта. Таким образом, вы можете использовать один и тот же скрипт для любого текстового объекта в вашей игре.

Запустите симуляцию и вы увидите большой текст "Hello World" где-то поблизости. Если вы этого не видите, убедитесь, что: а) рядом с ним есть источник света, и б) вы смотрите на его правильную сторону. Текст не будет отображаться, если вы будете смотреть на него сзади. (Это также позволяет разместить физический объект рядом с плоскостью, чтобы сначала найти его.)

12. Публикация

Как только вы соберете свой удивительный прототип, вы можете нажать на значок PlayCanvas в верхнем левом углу экрана и выбрать "Publishing". Здесь вы можете публиковать новые билды, размещенные на PlayCanvas, и делиться ими со всем миром!

Dialog box for publishing on PlayCanvasDialog box for publishing on PlayCanvasDialog box for publishing on PlayCanvas

Заключение

Это всё для этого демо. В PlayCanvas есть много нового, но, надеюсь, этот обзор поможет вам разобраться с основами, чтобы начать создавать собственные игры. Это действительно хороший движок, и я думаю, что больше людей должны его использовать. Многое из того, что было создано, это технические демо, а не полные игры, но нет причин, по которым вы не можете построить и опубликовать что-то потрясающее.

Одна особенность, о которой я действительно не говорил, но, возможно, было очевидно, что редактор PlayCanvas позволяет вам обновлять свою игру в реальном времени. Это относится к дизайну, поскольку вы можете перемещать объекты в редакторе, и они будут обновляться в окне запуска, если вы его открываете, а также для кода, с его горячей перезагрузкой.

В заключение, хотя редактор действительно удобен, все, что можно сделать с ним, можно сделать с помощью чистого кода. Поэтому, если необходимо использовать PlayCanvas и у вас небольшой бюджет, есть хорошие примеры на GitHub. (начать можно с простого примера вращающегося куба.)

Если что-то непонятно, пожалуйста, дайте мне знать в комментариях! Или просто, если вы создали что-то классное и хотите поделиться, или придумали более простой способ сделать что-то, я бы с удовольствием посмотрел!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.