А нарушает ли портальная пушка законы физики?
Можно ли предположить физический закон, положенный в её основу?
Возможно ли теоретическое обоснование эффекта?
Если предположить, что мы имеем ящик (ок, пусть это будет куб) в комнате и рассматриваем комнату как замкнутую систему. Ящик Куб лежит у стены А. Мы щелкнули и создали портал у стены А. Затем у стены Б. Пхнули (легонько) Куб в портал. Куб у стены Б. Если из системы отнять энергию, которую мы передали кубу, то получается, что баланс не нарушен и куб переместился без затрат энергии. Problems, Newton?
Ага, ты сделал итальянское нейтрино.
Портал тоже будет потреблять какую-то энергию. Именно она и затратится на перемещение куба на большое расстояние.
А если второй портал сделать выше первого, то энергия должна появиться из ниоткуда, чтобы куб переместился на большую высоту, т.о. получаем невыполнение закона сохранения энергии. Да и вообще, пространство непрерывно, уже отсюда следует несостоятельность идеи.
«Нет, сын, это фантастика»
А как же принцип однородности пространства?
всё ок, просто пространство «сшивается» в указанных точках, тогда и энергии лишней не нужно; остаётся только постулировать, многомерность мира, чтобы гладкость пространства сохранилась.
Зато можно было бы вырабатывать энергию в неограниченных количествах.
А энергия-материя-информация через портал передаются со световой скоростью или мгновенно?
Кода практически не будет, поэтому, если вы не 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, класс и тип, способ отрисовки. Это так называемые, стандартные свойства и они есть абсолютно у всех объектов. Далее, в зависимости от класса и типа объекта на него навешиваются дополнительные свойства и методы.
Чтобы создавать огромное число объектов с одинаковыми свойствами и прототипами — внутри движка есть фабрика объектов. Каждый объект, в зависимости от типа и имеет набор конфигов. Далее есть два массива — массив свойств и массив прототипов (на самом деле это не массивы, а тоже объекты, но это уже по части ООП в 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 в полный экран с фиксированным соотношением сторон. Вовсе не обязательно использовать камеру по основному назначению, этот объект может помочь нам в восстановление старых игр (например, получать идеально квадратную доску для нард, при любом соотношение сторон экрана)
Как использовать движок
Т.к. все описанные выше компоненты мы получаем на так называемых «Фабриках», то мы можем создавать их в неограниченном количестве. Например, можно создать три мира, которые не будут никак пересекаться между собой. Или пять камер нацеленных на один мир, чтобы смотреть глазами разных персонажей.
Но есть и некоторые ограничения — например, объект может быть помещен только в один мир, иначе его поведение будет неадекватным (он будет реагировать на события в разных мирах).
Общая схема движка
Также есть модуль загрузки и сохранения. При сохранении он преобразует в JSON массив объектов в мире, а при загрузке — восстанавливает все объекты на фабрике и обновляет реестр.
Т.к. статью писал в течение нескольких дней — могут быть логические нестыковки, так что извините, если что не так. Чуть больше можно узнать тут. В следующей статье будет больше практики, разбор API, а также ресурсы, необходимые для разработки игр.
Также рекомендую ознакомиться с трудами этих товарищей:
БЭМ: «Организация файловой системы» и «История создания»
Выступление Вадима Макеева о CSS фреймворках
Канал Андрея Короткова о том, как нормальные мужики пилят архитектуру
Выступление Миши Давыдова в Челябинске о том как надо брать и масштабировать
Книгу Джоба Макара «Секреты разработки игр в macromedia Flash MX»
Серию статей Миши Кадикова «Дизайн уровней. Теория и практика»
UPD: Тут такое дело, что сайт с демками начал тупить из-за хабра эффекта и может не подгружаться анимация (превышен лимит по нагрузке). Так что это не баг, это фича 🙂 К следующей статье сменю тарифный план.
Давайте пофантазируем: Портальная пушка в реальной жизни
Вот давайте немного пофантазируем, представим, что вы счастливчик, которому прислали такой вот подарок. В этом подарке находится сапоги прыгуна и тортик. Cъели ли вы тортик дело ваше, но давайте перейдём уже к главному. Вы взяли портальную пушку, что будете делать?
Трюки конечно делать можно, но вот несмотря на то, что у вас есть сапоги прыгуна, для вас всё равно это может закончится летальным исходом. Так что, делать это придётся на свой страх и риск.
Так же не рекомендуется делать порталы наверху и внизу боюсь, остановится вы уже не сможете. (К тому же, вас легко вырвет)
Очень легко будет можно достать вещи, которые находятся очень далеко. Возможно ли спасать людей с помощью этой пушки? Очень сомневаюсь, поскольку человек, без сапог может либо сломать ноги, либо погибнуть.
Здесь моя фантазия заканчивается. Так давайте же пофантазируем вместе! Пишите, что бы вы сделали ещё?
Комментарий удален по просьбе пользователя
Я хотел об этом написать! Но не рискнул)))
Я даже видел ролик на эту тему..
Комментарий удален по просьбе пользователя
Да, это тоже тема для бесконечных дискуссий там %)
З.Ы. хотя кому какое дело ))
Ставишь телепорт дома на стене. Приехжаешь на рабочку. Когда надо валить домой, ставишь второй телепорт оказываешься дома, снимаешь первый телепорт.
На следующий день ставишь первый телепорт, оказываешься на рабочке, выключаешь второй телепорт.
нет не только. Лунный камень просто очень хороший проводник
Портальная пушка: состав, стоимость, рациональность
В очередной раз перечитав историю компании Aperture Science, меня уже не первый раз посетила мысль — а зачем военным портальная пушка? И если для чего-то нужна — насколько рационально её производство? Сколько она стоит? Каковы максимальные возможности? Для чего, чёрт возьми, создавалась Глэдос и все эти камеры?
Как ни странно, на некоторые вопросы ответы есть. А если таких нет — есть гипотезы. Итак, что мы имеем? Договор с американскими военными на разработку был заключён в 1981 году, когда Красная Угроза всё ещё существовала. Вместе с гонкой вооружений. Разумеется, нужно было что-то ядрёное, чтобы показать, что капитализм таки круче. Вопрос упирается лишь в цену.
Цена данного исследования точно неизвестна. Единственное, что сообщает GLaDOS — «Руководствуясь опциональным пунктом протокола тестирования, мы рады сообщить вам занимательный факт: теперь устройство стоит дороже, чем годовой доход и внутренние органы всех жителей в городе». Сложно сказать, что именно подразумевается — то ли стоимость самого устройства, то ли цена исследований, идущих перед этим. То ли она просто врёт — ибо за несколько камер до этой фразы она говорит «В соответствии с протоколом тестирования, с этого момента мы перестаём говорить правду. Три. Два. Один».
В одном из финансовых отчётов компании почти миллион долларов ушёл на некий INTUB-XLG
Но всё же предположим, что это правда. Стоимость всех человеческих органов вместе взятых составляет около 300 тысяч долларов. Думаю, при таких числах годовой доход я могу не учитывать. Исследовательский Центр расположен где-то в лесу, следовательно, ближайший город вероятно не очень велик размерами. От балды возьмём цифру «50 тысяч». Несложные расчёты на калькуляторе дают цифру в 150 миллиардов долларов. Многовато. Но если население города меньше 10 тысяч, цена уменьшается уже до 30 миллиардов, а это уже деловой разговор. Мораль? В случае необходимости, военные действительно могли выдать денег на разработку.
Но каков же функционал данной штуковины? В этом месте стоит обратить внимание на то, что порталы появляются не благодаря пушке. Тут можно приводить много теорий, укажу самую на мой взгляд вероятною.
Напрягите память и вспомните, что в самом начале игры у вас нет пушки. А порталы есть. И они «самостоятельно» сменяются. Я думаю, что каждый портал «фонит» определённым элементом, который объединяется с элементом противоположным и это даёт реакцию портала. Бред? В принципе, да. Но как ещё объяснить размеры пушки и тот факт, что порталы разного цвета (разные элементы) и существовать в пределах комнаты может лишь один? Есть альтернативный вариант. Порталы «привязаны» к некому генератору энергии. Вполне очевидно, что в этом случае он довольно малых размеров, если помещается в пушку. Соответственно, слегка изменив сам сигнал, а также его силу, в теории можно передавать объекты на приличные расстояния, если не будет помех. А они будут.
Портальная пушка, вид спереди. К рабочему концу устройства не прикасаться
В принципе, есть один полуфантастический вариант использования — создать портал на Земле, а позже построить шлюз, скажем, на Марсе. И сделать второй портал там. Возможные проблемы: дальность и поддержание связи.
Есть варианты. Берётся стандартный блок метр на метр, на нём создаётся портал. Вместе с этим портал создаётся в лаборатории X. При этом возникает замечательный парадокс — порталы намертво связываются. Т.е. пока не будет разрушен один из порталов (либо энергетический блок, если подразумевать существование оного) они не отсоединятся! Как это возможно? Очень просто — «источник» находится на Земле рядом с синим порталом. при этом, питая его. Однако сигнал проходит сквозь синий портал и оказывается в месте Y, где находится оранжевый портал.
Портальная пушка, вид сбоку. В теории, именно так она выглядит в выключенном состоянии
Но использование этой штуки в космосе хоть и весьма интересно, у него есть и более приземистый вариант действия. Это же мечта любого диверсанта! Опять же, создаётся некий «блок», достаточно лёгкий в транспортировке даже одним-двумя людьми. Опционально, прочный. И скидывается вместе с диверсантами в тыл врага. Как вам такое — армию в любую точку планеты — за секунды?! Да что там полёты в космос — Красную Угрозу можно будет покорить на месте, без особых усилий. Открыть портал на Красной Площади? Без проблем!
Помимо военного использования, при массовом производстве и условии, что порталы не «перекроют» друг друга, можно подумать и о бытовом устройстве. Лифт? Без проблем. Мост через реку? Да к чему такие сложности! Билетик до Токио? Возьмите, вам в портал номер три.
Для чего камеры испытаний? Для теста. Да, Челл никогда не написала бы баг-репорт — за неё это сделали бы другие. Надо предусмотреть все возможные проблемы использования порталов. Военные могут на это пойти ради важных целей.
Да, но для чего тогда портативное устройство? Это ещё большая загадка. Как вариант — инструмент для добычи пленных. А что? Создал портал на улице, вбежал в дом, кинул порталы всем под ноги и готово. Хотя как-то не верится. Может, у вас есть какие-нибудь варианты.
























