Создать игру в браузере

Обновлено: 03.07.2024

Создавайте игры с помощью GDevelop, бесплатного и простого приложения с открытым исходным кодом, не требующего кода.

Простой, интуитивный способ создания игр

Что делает GDevelop уникальным и таким простым в использовании, так это система событий. События — это мощный способ выразить логику вашей игры без необходимости изучения языка программирования.

Легко публиковать свои игры на Android, iOS, Steam и других платформах

Игры, созданные с помощью GDevelop, запускаются где угодно и могут быть экспортированы одним щелчком мыши. В Интернете, как мобильное приложение для iOS и Android, публикуйте в Steam, Facebook Gaming, Itch.io, Newgrounds, Microsoft Store.

Создавать потрясающие, успешные игры

С GDevelop вы можете делать простые проекты для развлечения, создавать амбициозные инди-игры, такие как HELLO EARTH Lil BUB, Hyperspace Dogfights, или даже создавать следующий хит, который собрал 1 миллион загрузок, таких как Vai Juliette!

Неограниченные возможности

Выражайте свои идеи, большие и малые: вы можете создавать прототипы новых функций в своих играх за считанные минуты и улучшать их без ограничений. Создание игр еще никогда не было таким простым и быстрым благодаря визуальным редакторам, предоставляемым GDevelop. Хотите пойти еще дальше? Вы можете расширить игровой движок с помощью JavaScript.

Узнайте, как использовать GDevelop шаг за шагом, или получите помощь по конкретной функции. У нас есть учебные пособия по созданию игр для начинающих, а на вики есть полная документация по приложению.

Введение: Общий вид

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

Введение: типы объектов

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

Введение: система событий

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

Введение: быстрый старт

В этом видео рассказывается о системах и инструментах, поставляемых с GDevelop, которые помогут вам ускорить процесс создания игры.

Введение: переменные

В этом видео мы познакомимся с переменными. Мы изучим разницу между переменными сцены, глобальными и объектными переменными, а также узнаем, когда их использовать. Здесь основное внимание уделяется конкретным примерам, так что вы можете уйти с некоторыми реальными идеями о том, как применять переменные в вашей собственной игре!

Введение: Конструктор выражений

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

Введение: поведение и функции (расширения)

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

Промежуточный уровень: внешние события, внешние макеты и глобальные объекты

Вы создали уровень для своей игры, но теперь нужно создать второй уровень. Как вы можете сделать это без копирования и вставки всего в новую сцену? На самом деле, GDevelop предлагает набор инструментов для решения подобных проблем, которые сэкономят вам время как создателю игры.

Средний уровень: сохранение и загрузка (хранение)

Поскольку вы освоите основы GDevelop, вам захочется, чтобы все оставалось неизменным каждый раз, когда кто-то открывает вашу игру. В этом видео мы рассмотрим, как именно это сделать!

Средний уровень: растровый текст и мозаичная карта

Чтобы завершить рассмотрение типов объектов в GDevelop, мы рассмотрим два экспериментальных типа: Bitmap Text и Tiled!

Учебное пособие для среднего уровня: расширенные переменные (логические значения, массивы и структуры)

Узнайте, для чего нужны различные типы переменных и как их использовать. Логические значения, массивы и структуры больше не будут хранить для вас никаких секретов!

Учебник среднего уровня: меню выбора уровня

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

Учебник среднего уровня: выбор объектов

В этом руководстве мы рассмотрим систему выбора объектов, которая является неотъемлемой частью некоторых видов игрового поведения, таких как, например, системы контрольных точек! Эти руководства предназначены для того, чтобы научить вас создавать игры в GDevelop — бесплатном и простом приложении с открытым исходным кодом, не требующем кода.

Расширенное руководство: сохранение и загрузка (хранилище)

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

Экспорт вашей игры в Itch.io — из GDevelop

В этом видео мы будем экспортировать игру из GDevelop. Мы будем экспортировать как файл игры в формате html, так и сборку для ПК. В этом видео также показано, как загрузить эту экспортированную игру на itch.io, а также приведены рекомендации по обеспечению того, чтобы вашу игру можно было найти при поиске игр, созданных с помощью движка GDevelop.

Бесплатная и простая программа для создания игр

Создавайте и публикуйте свои игры с помощью GDevelop. Начните с наших руководств и откройте для себя множество примеров внутри приложения.

мобильный телефон

Phaser использует внутренние средства визуализации Canvas и WebGL и может автоматически переключаться между ними в зависимости от поддержки браузера. Это обеспечивает молниеносную визуализацию на ПК и мобильных устройствах.

Мы упростили загрузку ресурсов с помощью одной строки кода. Изображения, звуки, таблицы спрайтов, тайловые карты, данные JSON, XML — все анализируется и обрабатывается автоматически, готово к использованию в игре и сохраняется в глобальном кэше для совместного использования игровыми объектами.

Phaser поставляется с поддержкой трех физических систем: Arcade Physics, очень легкая библиотека AABB, идеально подходящая для маломощных устройств. Impact Physics для расширенной поддержки тайлов и Matter.js — система всего тела с пружинами, ограничениями и поддержкой полигонов.

Спрайты — это кровь вашей игры. Размещайте их, анимируйте, вращайте, масштабируйте, анимируйте, сталкивайте, рисуйте на пользовательских текстурах и многое другое!

Спрайты также имеют полную поддержку ввода: нажмите на них, прикоснитесь к ним, перетащите их, прикрепите их - даже при необходимости определение кликов с точностью до пикселя.

Группируйте наборы спрайтов вместе для удобства объединения и повторного использования, избегая постоянного создания объектов. Группы также могут конфликтовать: например, группа "Пули" проверяет наличие столкновения с группой "Чужие" с настраиваемым обратным вызовом столкновения для обработки результата.

Phaser поддерживает классические листы спрайтов с фиксированным размером кадра, а также несколько распространенных форматов текстурных атласов, включая Texture Packer, Starling и Unity YAML. Все это можно использовать для простого создания анимации.

Встроенная система частиц позволяет легко создавать забавные эффекты частиц. Создавайте взрывы или постоянные потоки для таких эффектов, как дождь или огонь. Или прикрепите излучатель к спрайту, чтобы получить реактивный след.

Phaser поддерживает расширенную поддержку нескольких камер. Легко создавайте дополнительные камеры, а затем размещайте и масштабируйте их в любом месте экрана. Камеры можно прокручивать, а также использовать специальные эффекты, такие как дрожание, вспышка и исчезновение. С легкостью перемещайтесь по спрайтам и следите за ними.

Поговорите с Phaser Pointer, и неважно, был ли ввод с сенсорного экрана или с мыши, он может даже измениться в середине игры, не теряя ритма. Сенсорный ввод, мышь, клавиатура, геймпад и множество полезных функций позволяют создать любую систему ввода, которая вам нужна.

Phaser поддерживает как веб-аудио, так и устаревшее HTML-аудио. Он автоматически обрабатывает блокировку мобильного устройства, простое создание аудиоспрайтов, зацикливание, потоковую передачу, громкость, скорость воспроизведения и расстройку. Мы знаем, как сложно работать со звуком на мобильных устройствах, поэтому сделали все возможное, чтобы решить эту проблему!

Phaser может загружать, отображать и сталкиваться с тайловой картой, написав всего пару строк кода. Мы поддерживаем форматы данных карты CSV и Tiled с несколькими слоями листов. Существует множество мощных функций манипулирования тайлами: меняйте местами тайлы, заменяйте их, удаляйте, добавляйте и обновляйте карту в реальном времени.

Phaser 2 имеет встроенный диспетчер масштабирования, который позволяет вам масштабировать игру под размер экрана любого размера. Управление соотношением сторон, минимальным и максимальным масштабами и поддержкой полноэкранного режима (скоро появится в Phaser 3)

Мы прилагаем все усилия, чтобы ядро ​​Phaser ограничивалось только основными классами, поэтому мы создали интеллектуальную систему подключаемых модулей для обработки всего остального. Легко создавайте собственные плагины и делитесь ими с сообществом.

Phaser был создан специально для мобильных веб-браузеров. Конечно, он работает невероятно быстро и на десктопе, но, в отличие от многих фреймворков, мы уделяли основное внимание мобильным платформам. Если он плохо работает на мобильных устройствах, мы не добавляем его в ядро.

Мы используем Phaser каждый день в наших многочисленных клиентских проектах. В результате он постоянно развивается и улучшается, и мы быстро исправляем ошибки и запросы на вытягивание.Это живая, дышащая структура, поддерживаемая коммерческой компанией с доступными пакетами разработки и поддержки пользовательских функций. Мы живем и дышим играми HTML5.

Phaser существует в экосистеме веб-браузера. Он был создан, чтобы позволить вам создавать веб-игры, и именно на этом он всегда будет сосредоточен. Это быстро меняющаяся среда, и мы следим за этими изменениями, чтобы обеспечить быструю поддержку новых браузерных API.

Для разработки игр не требуется совершенно новый набор навыков. Фактически, ваши нынешние навыки веб-разработки в HTML, JavaScript, CSS и т. д. вполне подходят для широкого круга игр. Когда вы создаете игру с использованием веб-технологий, она будет работать практически на любом устройстве с браузером.

Чтобы доказать это, я продемонстрирую создание игры с нуля с использованием веб-технологий и всего двух внешних библиотек, и я сделаю это менее чем за час. Я расскажу о различных темах разработки игр, от базового дизайна и компоновки, элементов управления и спрайтов до искусственного интеллекта (ИИ) для простого противника. Я даже собираюсь разработать игру, чтобы она работала на ПК, планшетах и ​​смартфонах. Если у вас есть некоторый опыт программирования в качестве веб-разработчика или другой области разработки, но нет опыта написания игр, эта статья поможет вам начать работу. Если вы дадите мне один час, я обещаю показать вам веревки.

Приступайте к работе

Все разработки я буду выполнять в Visual Studio, что позволит быстро запускать веб-приложение по мере внесения изменений. Убедитесь, что у вас установлена ​​последняя версия Visual Studio (скачайте по адресу bit.ly/1xEjEnX), чтобы вы могли следить за ней. Я использовал Visual Studio 2013 Pro, но обновил код с помощью Visual Studio 2013 Community.

Для HTML-файла индекса требуется всего три ресурса: jQuery, основная таблица стилей и основной файл JavaScript. Я добавляю в проект пустой файл CSS с именем style.css и пустой файл JavaScript с именем ping.js, чтобы избежать ошибок при загрузке страницы:

Базовый дизайн

Игра, которую я создаю, представляет собой разновидность Pong, которую я называю Ping. В пинге действуют те же правила, что и в понге, за исключением того, что любой игрок захватывает мяч, когда он до него доходит, а затем может выстрелить мячом в ответ либо прямо, либо под углом вверх или вниз. Часто лучше нарисовать, как вы хотите, чтобы игра выглядела, прежде чем создавать ее. Общий макет этой игры, который я хочу видеть, показан на рис. 1.

Общий дизайн Ping


Рис. 1. Общий дизайн Ping

После того, как я разработал макет игрового дизайна, для создания игры достаточно добавить каждый элемент в HTML. Однако следует отметить одну вещь: я сгруппирую табло и элементы управления, чтобы они были вместе. Итак, вы можете видеть, что я добавил элементы один за другим, как показано на рис. 2.

Рис. 2. Исходный макет HTML

Играйте со стилем

Если бы вы загрузили эту страницу, вы бы ничего не увидели, потому что к ней не был применен стиль. Я уже настроил ссылку на файл main.css в своем HTML, поэтому я помещу весь свой CSS в новый файл с таким именем. Первое, что я сделаю, это расположим все на экране. Тело страницы должно занимать весь экран, поэтому сначала я настрою его:

Во-вторых, мне нужно, чтобы арена занимала весь экран с применением фонового изображения арены (см. рис. 3):

Фоновое изображение арены


Рис. 3. Фоновое изображение арены

Далее я размещу табло. Я хочу, чтобы это отображалось сверху и по центру над другими элементами. Команда position: absolute позволяет мне разместить его там, где я хочу, и left: 50% помещает его посередине верхней части окна, но начиная с самой левой стороны элемента табло. Чтобы обеспечить идеальное центрирование, я использую свойство transform, а свойство z-index гарантирует, что оно всегда находится вверху:

Теперь баллы находятся в теге h1, поэтому я могу установить шрифт для всех тегов h1. На всякий случай, если шрифт отсутствует, я предоставлю несколько резервных вариантов:

Для других элементов я буду использовать лист изображений спрайтов. Лист спрайтов содержит все изображения, которые мне нужны для игры, в одном файле (см. рис. 4).

Лист спрайтов для проверки связи


Рис. 4. Лист спрайтов для проверки связи

Любому элементу, имеющему изображение на этом листе, будет назначен класс спрайта. Затем для каждого элемента я буду использовать background-position, чтобы определить, какую часть листа спрайтов я хочу показать:

Далее я добавлю класс спрайтов ко всем элементам, которые будут использовать лист спрайтов.Чтобы сделать это, мне придется ненадолго вернуться к HTML:

Теперь мне нужно указать позиции каждого спрайта на листе для каждого элемента. Опять же, я сделаю это с помощью background-position, как показано на рис. 5.

Рис. 5. Добавление смещений для листа спрайтов

Позиция: абсолютное свойство игрока, соперника и мяча позволит мне перемещать их с помощью JavaScript. Если вы сейчас посмотрите на страницу, то увидите, что к элементам управления и мячу прикреплены ненужные элементы. Это связано с тем, что размеры спрайтов меньше, чем стандартные 128 пикселей, поэтому я откорректирую их до нужного размера. Мяч всего один, поэтому я сразу укажу его размер:

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

После добавления этого класса управление в игре стало намного лучше:

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

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

Следуйте за прыгающим мячом

Теперь я заставлю мяч двигаться. Для кода JavaScript я ссылался на файл с именем ping.js в HTML, как и в случае с CSS. Я добавлю этот код в новый файл с таким именем. Я собираюсь сделать объекты для мяча и каждого из игроков, но для объектов я буду использовать фабричный шаблон.

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

Структура этого шаблона в том виде, в котором я создаю простой класс Ball, показана на рис. 6.

Рис. 6. Класс Ball

Чтобы создать новый мяч, я просто вызываю определенную функцию:

Теперь я хочу, чтобы мяч двигался и прыгал по экрану. Во-первых, мне нужно вызывать функцию обновления с некоторым интервалом, чтобы создать анимацию мяча. Современные браузеры предоставляют функцию, предназначенную для этой цели, которая называется requestAnimationFrame. Это принимает функцию в качестве аргумента и вызовет эту переданную функцию при следующем запуске цикла анимации. Это позволяет мячу плавно двигаться, когда браузер готов к обновлению. Когда он вызывает переданную функцию, он сообщает ей время в секундах с момента загрузки страницы. Это очень важно для обеспечения согласованности анимации во времени. В игре использование requestAnimationFrame выглядит следующим образом:

Обратите внимание, что requestAnimationFrame снова вызывается в функции, поскольку мяч закончил обновление. Это обеспечивает непрерывную анимацию.

Хотя этот код будет работать, может возникнуть проблема, когда скрипт запустится до того, как страница будет полностью загружена. Чтобы избежать этого, я буду запускать код при загрузке страницы с помощью jQuery:

Поскольку я знаю скорость мяча (velocity) и время, прошедшее с момента его последнего обновления, я могу применить простую физику, чтобы переместить мяч вперед:

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

Рис. 7. Простая физика отскока мяча

Подвижный игрок

Теперь пришло время создать объекты Player. Первым шагом в уточнении класса игрока будет заставить функцию перемещения изменять положение игрока. Переменная side будет указывать, на какой стороне корта будет находиться игрок, что будет определять, как расположить игрока по горизонтали. Значение y, переданное в функцию перемещения, будет означать, насколько вверх или вниз переместится игрок:

На рис. 8 показано движение игрока. Движение останавливается, если спрайт игрока достигает верхней или нижней части окна.

Теперь я могу создать двух игроков и заставить их перемещаться в соответствующую сторону экрана:

Рис. 8. Элементы управления движением спрайта игрока

Ввод с клавиатуры

Теоретически вы можете перемещать проигрыватель, но он не будет двигаться без инструкции. Добавьте некоторые элементы управления в проигрыватель слева. Вам нужны два способа управления этим проигрывателем: с помощью клавиатуры (на ПК) и касанием элементов управления (на планшетах и ​​телефонах).

На рис. 9 показано использование Hand.js и jQuery для управления проигрывателем при нажатии клавиш A и Z на клавиатуре или при касании элементов управления.

Рис. 9. Добавление сенсорного управления и клавиатуры

Поймай мяч

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

Рис. 10. Заставьте мяч следовать за своим владельцем

В настоящее время нет способа получить позицию объекта Player, поэтому я добавлю методы доступа getPosition и getSide к объекту Player:

Теперь, если у мяча есть владелец, он будет следовать за ним. Но как определить владельца? Кто-то должен поймать мяч. На рис. 11 показано, как определить, когда один из спрайтов игрока касается мяча. Когда это произойдет, я назначу владельца мяча этому игроку.

Рис. 11. Обнаружение столкновений мяча и игроков

Если вы попробуете сыграть в игру сейчас, вы обнаружите, что мяч отскакивает от верхней части экрана, и вы можете переместить игрока, чтобы поймать его. Теперь, как вы его бросаете? Для этого и предназначены правые элементы управления — прицеливание мяча. На рис. 12 игроку добавлена ​​функция «огонь», а также свойство прицеливания.

Рис. 12. Прицельтесь и выстрелите мячом

На рис. 13 показаны дополнительные функции клавиатуры, позволяющие игроку задавать функции прицеливания и стрельбы. Прицеливание будет работать немного по-другому. Когда клавиша прицеливания будет отпущена, прицел вернется в исходное положение.

Рис. 13. Настройка функции прицеливания проигрывателя

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

Ведение счета

Когда мяч проходит мимо игрока, я хочу изменить счет и передать мяч этому игроку. Я буду использовать настраиваемые события, чтобы отделить оценку от любого из существующих объектов. Функция обновления становится длинной, поэтому я добавлю новую приватную функцию под названием checkScored:

На рис. 14 показан код, который реагирует на эти события, чтобы обновить счет и передать мяч. Добавьте этот код в конец документа JavaScript.

Рис. 14. Обновление таблицы результатов

Теперь, когда мяч проходит мимо вашего противника (что не так сложно, поскольку противник не двигается), ваш счет будет увеличиваться, и мяч будет передан противнику. Однако противник будет просто удерживать мяч.

Стать умнее

У вас почти есть игра. Лишь бы было с кем играть. В качестве последнего шага я покажу, как управлять противником с помощью простого ИИ. Противник будет стараться оставаться параллельно мячу, когда он движется. Если противник поймает мяч, он будет двигаться случайным образом и выстреливать мячом в случайном направлении. Чтобы ИИ казался немного более человечным, я добавлю задержки во все, что делается. Имейте в виду, что это не очень интеллектуальный ИИ, но с ним можно будет сыграть в игру.

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

В зависимости от состояния ИИ я хочу, чтобы он выполнял другое действие. Как и в случае с мячом, я создам функцию обновления, которую я могу вызывать в requestAnimationFrame, чтобы ИИ действовал в соответствии со своим состоянием:

Состояние FOLLOWING не вызывает затруднений. Противник движется в вертикальном направлении мяча, и ИИ переходит в состояние ОЖИДАНИЯ, чтобы немного замедлить реакцию. На рис. 15 показаны эти два состояния.

Рис. 15. Простое СЛЕДОВАНИЕ ИИ

В коде на рис. 15 ИИ попеременно должен следовать за мячом и ждать доли секунды. Теперь добавьте код в функцию обновления всей игры:

Когда вы запустите игру, вы увидите, что противник следует за движениями мяча — неплохой ИИ менее чем из 30 строк кода. Конечно, если соперник поймает мяч, он ничего не сделает. Итак, последняя хитрость часа, пришло время обработать действия для состояния AIMING. Я хочу, чтобы ИИ двигался случайным образом несколько раз, а затем стрелял мячом в произвольном направлении. На рис. 16 показана приватная функция, которая делает именно это. Добавление функции aimAndFire к оператору case AIMING делает полностью функциональный ИИ, против которого можно играть.

Рис. 16. Прицеливание и стрельба ИИ

Подведение итогов

К настоящему моменту у вас есть полноценная веб-игра, которая работает на ПК, смартфонах и планшетах. Есть много возможных улучшений этой игры. Например, в портретном режиме на смартфоне это будет выглядеть немного неловко, поэтому вам нужно убедиться, что вы держите телефон в альбомной ориентации, чтобы он работал правильно. Это всего лишь небольшая демонстрация возможностей разработки игр для Интернета и не только.

Майкл Онеппо * — творческий технолог и бывший руководитель программы Microsoft в команде Direct3D.Среди его недавних начинаний — работа техническим директором в технологической некоммерческой библиотеке для всех и получение степени магистра в программе интерактивных телекоммуникаций Нью-Йоркского университета*.

Благодарим за рецензирование этой статьи следующего технического эксперта: Мохамеда Амина Ибрагима

Вы играете в игры?…. Да! Вы когда-нибудь думали о том, чтобы построить его самостоятельно?… Хм…

Игры изначально кажутся сложными в разработке. С большим количеством движущихся частей (в буквальном смысле) разработка игр кажется ограниченной разработчиками, которые глубоко погрузились в священные воды сетей, математики, графики и тому подобного.

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


В этой статье мы рассмотрим пошаговую реализацию многопользовательской игры в реальном времени о космических захватчиках (ах, какая ностальгия!) с помощью Phaser3 и Ably Realtime.


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

Эта серия руководств состоит из четырех частей:

  • Часть 1. Введение в игровые концепции и библиотеку Phaser
  • Часть 2. Оценка сетевых протоколов для приложений реального времени
  • Часть 3. Реализация кода на стороне сервера для синхронизации всех игроков
  • Часть 4. Доработка клиентского кода для рендеринга игры

И последнее, прежде чем мы начнем. В этой статье предполагается базовое понимание JavaScript и Express/NodeJS. Я постараюсь максимально подробно объяснить все остальное 👩🏻‍🏫💡

Давайте играть!

Давайте начнем с правил игры, поскольку они не будут точно такими же, как в оригинальной ретро-классике.

Правила игры для многопользовательских космических захватчиков

  • Когда новый игрок присоединяется, ему случайным образом назначается аватар монстра из трех доступных вариантов.
  • Каждый игрок может перемещать свой аватар влево или вправо с помощью клавиш со стрелками на клавиатуре.
  • Каждый игрок увидит свой аватар в белом цвете, а все остальные — в случайном цвете, который им предварительно назначен.
  • Когда к игре присоединяется заданное количество игроков, запускается корабль. Этот корабль движется по горизонтальной оси в случайно выбранном направлении, которое меняется случайным образом каждые 5 секунд. Вместе с этим изменится и скорость корабля. Этот корабль также стреляет пулями через равные промежутки времени, которые мы также можем задать.
  • Все аватары автоматически перемещаются вниз с заданным шагом на протяжении всей игры.
  • Цель игры — добраться до нижней границы игрового экрана, не будучи убитым одной или несколькими пулями, выпущенными кораблем.

Компоненты многопользовательской игры в реальном времени

Хотя может показаться, что за сетевой игрой в реальном времени стоит множество вещей, на самом деле все сводится к трем основным компонентам:

Давайте рассмотрим каждый из них подробнее.

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


Если вы хотите сделать тему своей игры супераркадной, вы можете следовать этому руководству по пиксельной графике от Глаубера Котаки, чтобы узнать, как это сделать.

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

Все эти вещи в основном представляют собой математические расчеты в соответствии с понятиями физики под капотом. Но так много математики может быть ошеломляющим, чтобы писать с нуля даже для простой игры. Таким образом, вместо того, чтобы писать все с нуля, мы можем использовать физический движок, который сделает за нас большую часть математической магии.

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

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

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

Phaser — это холст с открытым исходным кодом и среда JavaScript для рендеринга WebGL для HTML5. Мы будем использовать Phaser 3 для создания игры. Причина, по которой я специально упомянул эту версию, заключается в том, что между Phaser 2 и 3 есть много критических изменений, включая синтаксис. Кроме того, если вы хотите в будущем самостоятельно добавить в игру новые интересные функции, вы должны знать, что и где искать.


Фазер не только позволяет нам отображать активы на холсте, воспроизводить анимацию, звуки и т. д. на веб-странице, но также имеет встроенный физический движок (на самом деле их несколько). Это означает, что мы можем просто сказать ему, например, что нужно делать при столкновении двух объектов, и он будет автоматически следить за столкновением и выполнять часть кода, если это произойдет.

Есть очень хорошая серия видеоуроков по Phaser, которые я бы порекомендовал, если вы впервые работаете с Phaser 3.

В версии TL;DR с Phaser3 мы можем указать объект конфигурации, который будет содержать информацию о холсте и самой игре, включая размер холста, атрибуты его стиля, различные включенные сцены. в нашем игровом процессе (которое вскоре обсуждается), типе физического движка (поскольку их много в Phaser) и т. д.

Затем мы передаем объект конфигурации, чтобы начать новую игру.

Это может показаться немного запутанным, поскольку вы еще не видели никакого кода. Давайте сделаем это дальше.

Перейдем прямо к игровому экрану. Мы побеспокоимся о страницах запуска и списка лидеров позже. Наша игра будет HTML-страницей с отрисованным на ней холстом. Этот холст будет содержать и запускать настоящую игру. Итак, давайте создадим файл, назовем его index.html. Чтобы все было организовано, мы будем хранить все наши файлы HTML в папке с именем views и все файлы JavaScript на стороне клиента в папке с именем public . Давайте начнем файл views/index.html с базовой структуры:

Как видите, все, что мы здесь делаем, — это ссылки на файлы CSS и JS, которые мы вскоре добавим, а также, что более важно, ссылка на CDN Phaser JS. Вы можете скопировать CSS прямо из проекта GitHub

Кроме этого, в теле HTML у нас есть div с идентификатором game-container . Здесь мы добавим наш игровой холст с помощью JavaScript.

Давайте создадим файл в общей папке, назовем его script.js и начнем с определения объекта конфигурации игры, о котором мы говорили ранее.

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

Phaser использует концепцию «сцен» для организации контента игры. Вы можете думать о сцене как о том, что вы визуально можете видеть в любой момент времени. Если во время игры игра переключается на другой фон с другим взаимодействием между игровыми объектами, то, вероятно, это отдельная сцена от того, что вы просматривали раньше.

Для нашей игры у нас будет одна сцена (обозначается GameScene ). Сцена в Phaser — это класс, расширяющий класс Phaser.Scene. Давайте определим это для нашей игры. Добавьте следующий код над объектом конфигурации, так как он ссылается на класс GameScene.

Как видите, у этого класса есть три пустых метода. Они поставляются с классом Phaser.Scene. Каждый из этих методов имеет разные функции, как описано ниже

  1. Метод preload() получает все ресурсы, которые могут нам понадобиться, откуда бы они ни находились, загружает их и поддерживает их готовность к тому моменту, когда мы захотим добавить их в нашу игру.
  2. Метод create() выполняется один раз при первом запуске игры. В этот метод мы можем добавить все инициализации переменных, определения анимации и т. д.
  3. Метод update() выполняется непрерывно в цикле, пока игра включена, и, следовательно, может постоянно обновлять игровые объекты в соответствии с логикой игры. Мы будем обновлять аватары, стрелять пулями, двигать корабль — все этим методом.

Давайте теперь загрузим некоторые ресурсы. Определите метод preload() следующим образом

Изначально я размещал эту игру на Glitch, где все активы хранятся в корзине, которую можно получить по ссылке CDN. Вы можете использовать то же самое, в противном случае Amazon S3 — еще один популярный вариант.

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

Как видите, мы загрузили актив листа спрайтов в Phaser с помощью this.load.spritesheet() и отправили ему три параметра:

  • идентификатор
  • путь к фактическому файлу
  • размеры файла (в пикселях).

Мы также можем назвать его просто изображением, но тогда мы не сможем делать с ним классную анимацию, как вы скоро увидите.

P.S. есть лучший способ реализовать цвета аватара. Мы могли бы просто добавить цветовой оттенок к существующему спрайту вместо того, чтобы загружать один и тот же объект в нескольких цветах как отдельные активы. Я пока не знаю как, но я обновлю это, когда разберусь :)

Если вы посмотрите на лист спрайтов «взрыв», вы увидите, что это набор разных изображений, расположенных рядом друг с другом. Мы вызываем «анимацию», просматривая эти разные изображения с определенной скоростью, что создает впечатление, что на самом деле это прозрачное видео взрыва.

В методе create() мы определим анимацию для этого взрыва:

Для создания анимации мы использовали метод this.anims.create() от Phaser. Этот метод принимает:

  • ключ, который мы будем использовать позже для воспроизведения этой анимации
  • frames, который генерирует кадры, используя идентификатор ресурса, к которому мы хотели бы применить эту анимацию
  • frameRate, указывающий скорость, с которой мы хотели бы воспроизводить эту анимацию
  • repeat указывает, сколько раз будет запускаться анимация
  • hideOnComplete указывает, должен ли анимируемый ресурс исчезнуть после завершения анимации.

Пока мы не будем ничего добавлять в метод update(). Если вы заметили, мы на самом деле не создавали экземпляр игры, мы сделаем это позже в этой серии статей.

Это пока. Мы узнаем о сети для приложений реального времени во второй части — Оценка сетевых протоколов для приложений реального времени

Отдельный выпуск, относящийся к этому руководству, доступен на GitHub, если вы хотите его проверить.

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

Если у вас есть вопросы, пишите мне в Твиттере @Srushtika. Мои личные сообщения открыты :)

Читайте также: