Создание гравитационной и портальной пушки. Как правильно убить персонажа в машине и создать теплый вязаный интерфейс

  • Tutorial
Привет Хабра!

Эта статья продолжает цикл статей об игровом движке StalinGrad. В прошлой статье мы насиловали DHTML, а в этой — будем насиловать архитектуру и прототипы.

Кода практически не будет, поэтому, если вы не web разработчик, можете просто почитать про архитектуру и ООП. И таки да — про HTML5 тут снова ничего не будет, только DHTML-хардкор :)



Сразу короткое демо:
Пример 1 — паралельные миры
Пример 2 — один мир с разных камер
Пример 3 — боты
Пример 4 — нянкэт, облака и портальная пушка

Логика работы


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

Как сделать это хождение на JavaScript? В большинстве случаев это выглядит так: есть экран и персонаж, который ходит от одного конца экрана в другой.



Реализовать довольно просто. Но что если бар будет больше чем экран? Тогда можно придумать такую схему: есть экран — это DIV1 c позиционированием. Внутри этого лежит другой DIV2, который больше чем DIV1 и позиционируется относительного родителя. DIV2 — это и есть наш уровень. Все люди и объекты в баре лежат внутри DIV2 и позиционируются от его левого края.

Реализовать схему в принципе просто, но не нужно. Это абсолютно неправильный подход. Что если у нас в баре будет тысяча объектов? Мы получаем не масштабируемую основу, которая со временем может заставить нас страдать.

Я начал искать информацию о том, как делают 2D игры и перебрал кучу статей на Хабре про игры на HTML5. К сожалению, во всех найденных статьях, которые прочитал, не нашлось ни одного алгоритма или отсылки к архитектуре — только скрипты одноразовых игр. Этот факт меня опечалил, и я спросил парней на работе о том, что они думают. Мой коллега, Виталий Никитин, посоветовал прочитать книжку «Секреты разработки игр в macromedia Flash MX» (автор Jobe Makar). С этого все и началось.



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

С полученными знаниями, представление об играх расширилось и возникло острое желание написать игру с проработанным миром. Сначала я посмотрел на игровые движки на JavaScript, которые уже были на рынке. Обратил внимание на то, что у многих отсутствовала нормальная документация. Хардкорные варианты — тоже не нашлись. А ведь следуя логике Джоба Макара и опыту игростроя, уровень хардкора можно сделать запредельным.

Что я хотел? Марио, в котором можно будет убивать/насиловать/грабить караваны. Что нужно было сделать:

  • Добавить погоду
  • Возможность телепортироваться
  • Портальную пушку
  • Гравитационную пушку
  • Вообще много разных пушек и холодного оружия
  • Возможность ездить на транспорте
  • Чтобы у транспорта было ограничено топливо и его можно было заправлять
  • Погоду
  • Смену дня и ночи
  • Нарко и алко трипы
  • Чтобы можно было строить как в Майнкрафт
  • Карму каждому игроку
  • и много других веселых и забавных вещей.


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

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

Любая игра состоит из трех объектов.

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

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

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



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



Какие проблемы решает создание разных миров? Мы можем вынести код на сервер и доделать режим игры по сети. По сути, мир — это массив и парочка методов, которые его обслуживают. Он не работает с DOM, а значит, ему безразлично, где существовать. Кроме того, генерируя миры, мы можем создавать игры с параллельными мирами, которые существуют одновременно.

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

Архитектура, описанная выше — это ООП в чистом виде. Поэтому ядро движка это прототип на прототипе, повсеместная инкапсуляция и модульность. Если начать думать в таком формате, архитектура игр представляется совсем с другой стороны и возникает куча дополнительных вопросов.

Расширяемость

Идет парень, подбирает автомат и садится в машину. Другой парень стреляет в него из базуки. Кто от чего умрет? Как вообще они будут умирать?
  • Ракета подлетает к машине, происходит столкновение. Рекурсией идет перебор вложенных объектов (перебор пассажиров и вещей у этих пассажиров) и все объекты внутри машины уничтожаются. Потом уничтожается сама машина. Эта схема первой приходит в голову.
  • Ракета подлетает к машине, происходит столкновение. Создается зона повышенной температуры/ущерба. Всем объектам наносится ущерб. Если объект сильнее нанесенного ему ущерба — он остается в мире. Эта схема кажется более логичной, да и возможностей к масштабированию больше (например, можно расширить зону ущерба и получим взрывную волну).
  • Схема два, только для вложенных объектов учитывается степень вложенности. Получается, чем более вложен объект, тем он больше защищен.
  • Схема два, только учитывается дополнительный урон от топлива в машине. Получается ущерб от ракеты + ущерб от взрыва топлива в машине. Такая схема более реалистична.


Что такое погода?

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

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

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



На основе того, что мы можем задать размер камеры (не размер экрана, на который выводится изображение, а именно области отображения мира) очень легко была реализована функция масштабирования. А ссылка для таймера на отдельную переменную mdash; дала возможность добавить камере кнопку стоп/запустить для остановки отрисовки мира.



Проектируем объекты мира


Любой объект, который добавляется в мир, должен иметь обязательные стандартные свойства. Например: координаты, размер, ID, класс и тип, способ отрисовки. Это так называемые, стандартные свойства и они есть абсолютно у всех объектов. Далее, в зависимости от класса и типа объекта на него навешиваются дополнительные свойства и методы.

Например:
  • Фон ничего не получает, т.к. ему больше ничего и не надо. С фоном никто не взаимодействует.
  • Персонаж получает физические параметры (массу, ускорение, силы и т.д.), рюкзак (пустой массив, куда в последствии возможно добавлять ID вещей), характеристики живого объекта (тип мозгов, жизни, рейтинг, карму и т.д.) и т.п.
  • Машина получает почти тот же комплект свойств и методов, что и персонаж, но есть и особые характеристики транспорта (запас топлива, расход, пассажировместимость и т.д.)


Чтобы создавать огромное число объектов с одинаковыми свойствами и прототипами — внутри движка есть фабрика объектов. Каждый объект, в зависимости от типа и имеет набор конфигов. Далее есть два массива — массив свойств и массив прототипов (на самом деле это не массивы, а тоже объекты, но это уже по части ООП в JavaScript).



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

Проектируем оружие


Так получилось, что оружие разделилось на три вида по типу стрельбы:

С зоной поражения.



В зависимости от дальности стрельбы, перед персонажем создается зона поражения. Далее находятся все объекты, которые попали в зону поражения. Из них выбирается объект, который ближе всего находится к персонажу. Когда жертва найдена — ей наносится ущерб, в зависимости от типа оружия.

Подобный алгоритм использует кирка. Пример можно посмотреть тут

С созданием объекта снаряда.



Перед персонажем создается объект снаряда, у которого отключено воздействие гравитации. Снаряд летит и проверяет наличие столкновений с объектами. Если он столкнулся с персонажем — снаряд исчезает, а персонажу наносится урон.

Подобный алгоритм использует пушка. Пример можно посмотреть тут

С проверкой свободного места.



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

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

Как сделать оружие ближнего боя

Тут все просто — любые мечи, ножи, кирки работают по первому принципу (с зоной поражения)

Как сделать скорострельное и медленное оружие

Скорострельное оружие работает по первому принципу и наносит урон сразу. Медленное оружие (ракеты и т.п.) — по второму, и ждет столкновение снаряда.

Как сделать гравитационную пушку

Стрельба делается по первому типу, только вместо урона на все объекты накладывается дополнительное ускорение. Его направление зависит от режима стрельбы (либо к себе, либо от себя).

Пример гравитационной пушки можно посмотреть тут



Как сделать портальную пушку

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

Пример портальной пушки можно посмотреть тут

Как прокачать портальную пушку

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

Как реализована камера


Какие проблемы решает объект камеры? Т.к. Canvas работает не везде (перспектива прокачать играми электронные книги меня все ещё манит), я решил делать камеру, которая сможет отрисовать мир с помощью верстки. Наркомания скажете вы? Возможно, зато работает везде. В данный момент камера может рисовать картинками и div`ами с background`ом. Перевести все на canvas если заставит нужна — не проблема, т.к. для этого нужно всего лишь переписать несколько функций рендеринга (на самом деле тут, шутки ради, можно вообще сделать отрисовку текстом). Мой друг постоянно говорил мне о том, что без canvas все будет виснуть, т.к. шейдеры… бла… бла… бла… HTML5… и т.д. — но оказалось, что нет. В начале камера конечно висла, но проблема каждый раз была не в ней, а в алгоритмах обсчета мира.



Когда я показал схему работы одному коллеге на работе — он сказал, что камера должна сразу отрисовать весь мир, а не создавать и удалять постоянно DOM элементы. Это абсолютно неправильное понимание. Предположим, что в мире 40 объектов, а значит, у нас есть 40 DOM элементов для работы. Ну и ладно, это не много и браузер сможет их вывести без тормозов. А если у нас в мире тысяча объектов? Следуя такой логике, мы должны создать тысячу DOM элементов и страдать от тормозов (хотя на экране, в данный момент, все равно будет лишь штук 30, т.к. больше не влезет).

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

Рендеринг мира осуществляется в данный момент двумя способами — картинками и div`ами. Для обоих методов подойдет один дисплей в виде родительского div`а, относительно которого позиционируется вся верстка. В будущем можно добавить ещё рендеринг через canvas, но в данный момент особой необходимости в этом не вижу, т.к. есть более интересные задачи.

Ещё один интересный момент. Поскольку вся отрисовка игры mdash; это верстка, то любой верстальщик (даже с малым опытом работы) сможет легко исправить CSS файл и заменить картинки, тем самым придать объектам совершенно иной внешний вид. Например можно создать вязанный мир (для сравнения обычный).

Как выбрать между картинкой и div`ом?

Ну тут зависит от ситуации.

Если у вас большой экран и какой-нибудь очень длинный объект — то следует отрисовать его div`ом с background`ом (например кирпичную стенку). Она будет хорошо выглядеть и это будет всего лишь один DOM элемент (чем меньше DOM элементов на дисплее, тем меньше тормозит отрисовка).

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

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

Надо также понять, что камера это отдельный объект сам по себе, и он никак не связан ни с одним персонажем в мире. Но у каждой камеры, есть метод bind, который привязывает её к другому объекту в мире (не обязательно к персонажу, можно и к кирпичу её привязать). Такой интерфейс объекта позволяет легко реализовать переключение камеры между разными игроками (аналог вы уже видели в Counter-Strike, когда после смерти можно посмотреть бой от лица ещё живых игроков).

Какие выгоды нам дает объект камеры сам по себе?



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

Как использовать движок


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


Для создания новой игры вам понадобятся четыре основных компонента:
  • Мир. В мире находятся все объекты, и развивается сюжет. Мир следит за столкновениями и действиями объектов. Мир управляет все физикой.
  • Камера. Камера показывает вам мир или следит за персонажем. Именно благодаря камере, мы можем знать, что происходит в мире.
  • Персонаж. Персонаж, это один из объектов, который мы поместим в мир. Так же мы добавим в мир его окружение, врагов, оружие и т.п.
  • Джойстик. Чтобы управлять персонажем, мы должны привязать к нему джойстик. Если отдать джойстик компьютеру, то он сможет управлять персонажем.




Т.к. все описанные выше компоненты мы получаем на так называемых «Фабриках», то мы можем создавать их в неограниченном количестве. Например, можно создать три мира, которые не будут никак пересекаться между собой. Или пять камер нацеленных на один мир, чтобы смотреть глазами разных персонажей.

Но есть и некоторые ограничения — например, объект может быть помещен только в один мир, иначе его поведение будет неадекватным (он будет реагировать на события в разных мирах).

Общая схема движка




Пояснение к схеме

  • Ядро — файл, который содержит типовые функции (создать/удалить/заменить класс у DOM элемента, сгенерировать ID, назначить событие и т.д.)
  • Фабрика миров — создает миры, где все происходит
  • Фабрика камер — создает камеры, которые показывают нам, что происходит в мирах
  • Фабрика объектов — создает персонажей/вещи/оружие/окружение, которое добавляется в миры. Также фабрика может восстанавливать объекты, но об этом ниже.
  • Конфигурации объектов — у фабрики объектов так много настроек, что часть из них вынесена в отдельный файл. Почему вынесены не все настройки? Потому что если поломать/изменить базовые настройки для всех объектов, объекты могут стать не валидными и миры не будут их добавлять в себя.
  • Далее все что создается на фабриках — попадает в единый реестр. Он нужен для того, чтобы убрать ссылки между объектами. Если кто-то кому-то нужен — он запрашивает жертву у реестра, указывая его ID. Так, например, персонажи хранят в сумках только ID вещей, а сами вещи приезжают из реестра по мере необходимости.
  • Далее идет группа модулей, которые работают с конкретными объектами фабрик. Так например для миров:
  • Погода — обрабатывает настройки погоды
  • Обработка карт — строит карту по заданным параметрам. Получить строку таких параметров вы можете в редакторе карт.
  • Для объектов в мирах (вещи/персонажи/препятствия):
  • Менеджер миссий — следит за персонажем и его миссиями. При успешном завершении миссии может делать какие-либо действия.
  • Рейтинг — составляет рейтинг игроков в мире.
  • Кланы — отвечает за все, что связанно с кланами. Может добалять игроку клан, выдавать список кланов и т.д.
  • Фабрика сумок — создает объект, способный работать с вещами персонажа.
  • Фабрика джойстиков — создает контроллеры для персонажей.
  • Мозг — управляет персонажами. Если вбросить туда персонажа — ему будет создан джойстик, и в зависимости от его типа мозгов компьютер будет управлять им.


Также есть модуль загрузки и сохранения. При сохранении он преобразует в JSON массив объектов в мире, а при загрузке — восстанавливает все объекты на фабрике и обновляет реестр.

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

Также рекомендую ознакомиться с трудами этих товарищей:
БЭМ: «Организация файловой системы» и «История создания»
Выступление Вадима Макеева о CSS фреймворках
Канал Андрея Короткова о том, как нормальные мужики пилят архитектуру
Выступление Миши Давыдова в Челябинске о том как надо брать и масштабировать
Книгу Джоба Макара «Секреты разработки игр в  macromedia Flash MX»
Серию статей Миши Кадикова «Дизайн уровней. Теория и практика»

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

Подробнее
Реклама
Комментарии 34
  • +6
    Наркомания скажете вы? Возможно, зато работает везде.
    Нет, не наркомания. Так раньше и писали игры на HTML.
    • 0
      Более того, только таким образом можно писать игры на HTML5 для текущего поколения Smart TV (потому что, все что может мой LG Smart TV 2012 года — это три раза в секунду очистить canvas 1280x720px).
      • 0
        Для сравнения канвас в разрешении 800х600 (width=«800» height=«600»), растянутый на весь экран (style=«width\height») около 50 элементов — квадратов\линий\кружочков и проч. с анимацией каждого элемента — каждый раз перерисовывается (в интервале).

        PC (коллеги, linux chrome) — 220 fps
        Android browser Htc One S — 60-110 fps
        Ipad Mini — 60-70 fps
        Iphone 4 — 45 fps
        Android browser Xperia Neo — 28-30 fps
        Phonegap Xperia Neo — 32-34 fps

        Мой рабочий комп Windows:
        Chrome 29 — 200 fps
        Opera 12 — 248 fps
        Opera Next 17 — 200 fps
        FireFox 24 — 116 fps
        Maxthon 4 — 60 fps
        Safari 5.1 — 248 fps
        IE 11 — не работает

        Из чего можно сделать вывод, что канвасы надо немного оптимизировать Вам, ибо хоть разрешение и поболе 800х600, но не думаю, что мой телефон (xperia) 2011 года выпуска — круче в N раз, чем телевизор с интернетом =)
        • 0
          Если у вас есть демо, то с радостью запущу его на телевизоре (пусть даже канва в 800x600, ничего не меняйте), запишу видео и выложу сюда в комментарии.
          • +1
            Увы, это самое самопальное демо было погребено под порывом безудержного рефакторинга =)

            Вот набросал быстренько другое: jsbin.com/ItIpOpUv/1
            Разрешение: 800х600
            Рисуется: 800 \ 2 + 600 \ 2 линий, т.е. 550 штук раз в два пикселя
            Канвас растягивается на полный экран. Выдаёт на моём рабочем компе в хроме от 180 до 197 кадров, на Xperia Neo (в браузере) — около 8-10 кадров в секунду. Может немного перестарался с количеством линий, Вы уж извините =)
            • +1
              Результаты:
              LG Smart TV 2012 (Netcast 3.0, модель LM640T): 0-1 FPS. Запущено как приложение, не из браузера. Фото: раз, два и три. Видео не выкладываю — совсем ничего не видно, нужно полосы толще и FPS крупнее раза в три-четыре. Вместо этого записал видео BunnyMark Pixi.JS: 3-5 FPS — ссылка.

              Такие дела.
              • 0
                Теперь можно смело говорить, что не телевизорах не будет Watch Dogs! А вообще, если честно, имхо, какой-то бред играть в игры на телевизоре…
                • 0
                  Ну, телевизоры поддерживают подключение геймпада, а в LG есть еще Magic Remote (наподобие Wiimote). Поэтому играть можно :)
            • 0
              Матерь Василиса! Сегодня получил телевизор LG 2013 года LA660 и в нем обнаружилась поддержка WebGL(!!!). BunnyMark Pixi.JS летает, 400 зайцев с 30-35 FPS.
              В документации LG ни слова о WebGL, видимо он есть лишь благодаря обновленному движку WebKit, который на html5test.com идентифицируется как Chrome 22.
    • +8
      Если у вас маленький экран или объект с анимацией — то следует отрисовать его через img, т.к. через смену адреса картинки можно воссоздать анимацию

      Мне кажется, намного быстрее будет работать если не менять src у картинки, а показывать один длинный спрайт с чередой кадров, отрисовывая его в background какого-нибудь div-а и меняя background-position на длину или высоту кадра.
      • –1
        Долго думал над вашим вопросом. Использование позиционирования:
        1. Поломает маштабируемость логики
        2. Не будет работать в старых IE
        3. Заставит разработчиков джуниоров страдать при копании в чужом коде

        Два года назад я исправлял и переделывал две игры со спрайтами персонажей. Это было ужасно!
        В следующей статье я напишу про конфиги, раскрою суть сборки объектов мира, и более подробно отвечу на ваш вопрос (вместе с демо примерами).
        • 0
          1. По первому пункту мне сложно дискутировать, так как не совсем понимаю, что вы имеете в виду.
          2. Свойство background-position присутствует в css с версии CSS1 и поддерживается браузерами IE с шестой версии.
          3. Код сменяющий значение background-position на ширину (высоту) кадра вряд ли будет запутаннее, чем при использовании одного спрайта. Зная расположение кадров в спрайте (горизонтальное или вертикальное), он может делать их смену автоматически (т.е. менять x или y координату свойства background-position на ширину или высоту контейнера).

          То что это будет быстрее — тоже весьма очевидно. Представьте, что у вашего объекта зацикленная анимация на 100 кадров. Пролистывая их все, нам придется делать 100 запросов к веб-серверу. А перед этим еще забивать в конфиги массивы этих самых кадров. В случае с CSS-спрайтами мы грузим всего одну картинку.
          • 0
            А еще я сделал небольшое демо. По коду выглядит так, что для одного спрайта его требуется больше, но если вынести его отдельно, то в результате многое упростит. Например, нам не придется хранить где-то в конфигах массив кадров всей анимации, достаточно ссылки на один файл. Во втором примере я этот момент упростил, но в живом проекте скорее всего будут огромные конфиги с массивами вида ['object_1_frame_1.png','object_1_frame_2.png','object_1_frame_3.png' ...].
        • +9
          Извиняюсь за такой странный вопрос: а у вас котик радугой какает?
          Если да, — то как это реализованно и как влияет на производительность?
          • +1
            Присоединяюсь к вопросу. Как лучше в таком контексте реализовывать шлейфы? особенно постепенно гаснущие/уходящие в прозрачность. Все реализации, что я могу придумать, сводятся к большому количеству элементов.

            Кстати. Порекомендовал бы взглянуть на структуру three.js, пока читал — была стойкая ассоциация с ним, уж очень много тех же терминов. Может быть, найдете пару идей, которые пригодятся.
            • 0
              Над этим вопросом, честно говоря не думал. Сейчас думаю как правильно сделать объект зон — он сможет сразу добавить: ветер, радиацию, взрывную волну (а значит ещё два вида оружия — мины и шахидские пояса) и объект лестниц.
              Three.js и прочие штуки можно будет начать крутить, когда все будет работать на ура и возникнет необходимость третий координаты. А пока и в 2D баг на баге

              *а ещё с зоной можно будет запилить гравитационную мину, которая будет всех раскидывать*
              • +1
                Теоретически взрывная волна может быть абстрагирована как временная область аномальной гравитации тогда уж сама по себе — и вакуумные бомбы тогда делать можно те самые, и обычные взрывы будут наносить зональный урон + придавать импульс телу.
                А по-хорошему тогда уж надо сводить все не к гравитации, а к передаче импульса за промежуток времени, правда, когда я пытался что-то подобное реализовать — запутался в абстракциях, так что меня не факт что стоит слушать :)

                Относительно three.js — я больше имел ввиду взглянуть на структуру, а не на сам движок, так как там структура работы с данными очень похожа — объекты, камера, сцена… Возможно, что-то пересмотрите у себя, если наткнетесь на интересные решения в аналогичном по структуре проекте.
                • +1
                  Спасибо за совет! three.js — посмотрю

                  Кстати такой момент всплыл: те кто пишут на C++ видимо познают дзен чаще других.
                  Когда искал информацию на форумах, адекватные люди попадались только на форумах C++`ников. Там ребята по таким темам загоняются, что и на других форумах подобного и близко не найти. Очень запомнилось обсуждение того, как они леску от удочки топили (представили её в виде множества мелких подшипников из железа, т.к. по другому она у них всплывала). Очень интересно читать, как они физику пишут и как представляют мир вокруг.
          • 0
            Но есть и некоторые ограничения — например, объект может быть помещен только в один мир, иначе его поведение будет неадекватным (он будет реагировать на события в разных мирах).

            по-моему отличное и вполне адекватное поведение. даже очень интересное в некоторых играх
            • +1
              Прикольно, только над багами еще поработать надо, а то в примере 1 в 4 мире удалось добиться чтобы ня-котэ вышел за пределы комнаты сквозь кирпичную стену О_О
              • 0
                это да, вообще ещё очень много оптимизировать нужно. Например фабрика миров все в свойства пихает, а не в прототипы (это очень большой косяк). Ещё в этой сборке трипы отвалились (к следующей статье постараюсь починить, тогда будет демо наркотрипов). Потихоньку исправляю, не на все времени хватает.
              • +1
                «Психанул».jpeg

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

                Так что удачи и пишите еще.

                Нужна рельса из квейка, рейдбоссы, дроп вещей и инвентарь :D
                И можно запускать самую безумную мморпг всех времен и народов.
                • 0
                  Одна из лучших статей, которые я здесь читал.
                  Респект за креатив, упертость и творческое безумие!
                  • +1
                    Как-то мне захотелось написать квест, где мужик ходил бы по бару и мог разговаривать с разными людьми. А события и люди в этом баре — генерировались случайно, и каждый раз перед игроком появлялась новая цель.

                    Была такая игрушка у Lucas Arts много-много лет назад.

                    image

                    UPD: Оказалось, что была ещё одна похожая игра, тоже у LucasArts.
                  • 0
                    Нашел баг :)
                    image

                    А первая демка работает? Ни в хроме, ни в сафари клавиши не работают.
                    • 0
                      А неминифицированную версию вашего движка где можно увидеть?
                      • 0
                        Любопытно, сколько времени ушло на разработку?
                        • 0
                          В примере с киркой, после разрушения блоков и падения на землю: Земля копается не блоками, а слоями. Прямо-таки тетрис какой.
                          Это связано с тем, что каждый слой земли это один объединенный объект или баги в логике?
                          • 0
                            скорее всего один объект, об этом в статье упоминалось.
                            • 0
                              Да упоминалось, но там речь шла об одном DOM объекте при «рендеринге»(!).
                              И тогда получается, что либо автор «схалтурил» при создании карты — это все нормально и понятно — просто пример.
                              Либо же, это баг из-за нарушения принципов ООП. Получается так: Воздействие -> DOM объекты -> экзепляры -> Отрисовка через DOM, хотя по хорошему игрок должен взаимодействовать с экземплярами объектов напрямую, а через что там происходит рендеринг — уже не важно.
                              Я с трудом представляю, что там творится внутри браузера(только общие представления о web-разработке), возможно я не прав. Но с точки зрения программирования должно быть именно так.
                              • 0
                                > «схалтурил» при создании карты
                                Первые два слоя земли — это просто два больших пласта. Рисовать эти слои мелкими кубами было лень. На самом деле у объектов есть ещё свойство неразрушаемости. По нормальному надо было задать это свойство для нижних пластов, чтобы останавливать бесконечное копание вниз. Рассказ о картах и их создании будет в следующих статьях.

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

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.