Как сделать 3D шутер на JavaScript за пару дней

    imageВ субботу у меня ближе к полуночи появилось свободное время и жгучее желание сделать игрушку под браузер, забавы ради и увеличения опыта для. С жанром определился довольно быстро: т.к. на MMORPG в этот раз у меня точно не хватило бы времени, я решил делать просто мясорубку. Минут 20 ушло на написание базового кода для управления игроком и его противниками. И тут встал вопрос — 2D или 3D (вернее так: Canvas/SVG или все же полноценный WebGL)?

    Учитывая, что я сейчас участвую в разработке проекта, где WebGL является базовой технологией для 3D режима, выбор я сделал осознанно. Уже примерно полгода я работаю с замечательной библиотекой Three.js и в этот раз она снова стала моим лучшим помощником.

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

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

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

    Собственно, в качестве результата в ночь на воскресенье я имел следующую картинку:

    image

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

    Первым делом, после того как я вошел в офис, я попросил нашего моделлера сделать мне для антуража модель сухого дерева, а сам подобрал на просторах сети модельку пушки. Модель противника я взял из примеров к библиотеке Three.js.
    Народ в офисе периодически подходил посмотреть чем я занят. Все мило улыбались и ждали ссылку.

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

    image

    Потом я подумал, что на дворе зима и без снега будет неуютно. Сказано – сделано, за 10 минут был прикручен снег на основе системы частиц.

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

    Возвращаясь к описанию механики сцены я напомню, что нам всегда известны углы направления пушки и углы противников. Зная это, мы легко можем определить, попадает пуля в противника или нет, и в очередной раз замечу, что этот подход существенно упростил процесс расчета полета и попадания пули в противника. В итоге наша пушка научилась стрелять, а пуля – попадать в противника.
    Осталось научить наших противников быть похожими на что-то живое. Я использовал уже анимированные модели, что само по себе позволило очень быстро наладить простейший механизм смены анимации и состояния противника: он бежит, падает, встает и идет нахмурившись, а под конец и вовсе умирает.
    Кстати, достигнув определенного расстояния до игрока, противник переходит в режим атаки и, собственно, пытается забрать жизнь у игрока.

    image

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

    В конце концов все это дело перекочевало на сервер, и все, кто хотел – получили свою ссылку.

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

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

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

    PS И да, я не претендую на образцовое решение и идеальные варианты реализации, это just for fun который работает в Google Chrome, Safari и Mozilla Firefox.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 65

      +10
      Нано-шутер :)
        +2
        Что-то не понял, как там ходить?
        В FF/OSX не заработало управление совсем, в Chrome стреляю, но ходить не вышло ни стрелками, ни WASD.

        А за проделанную работу и открытый код — респект!
          0
          спасибо!
          по поводу «ходить» — я специально написал, что выбрал простой вариант — пушка закреплена в центре координат
            0
            Хм, я видимо этот фрагмент пропустил при чтении =)
            +8
            я так понял, что ходить там вообще нельзя. Мне, как лентяю, это нравится. Пожалуй, первый шутер, в котором не надо никуда идти…
              +7
              Тогда это не шутер, а тир…
                +2
                Tower defense от первого лица.
                  +1
                  Ждем косынку от первого лица в жанре «Симулятор».
                    0
                    Вообще-то survive,
                    TD подразумевает строительство башен, которые стреляют за тебя.
              +10
              НЛО прилетело и оставило эту надпись здесь.
                +4
                Епрст, друзья, я написал дублирующий комментарий и удалил его, какого черта это минусовать? Это не попытка пошутить не в тему, если что! НЛО не имеет отношения к данной игре!
                +5
                Все исходники проекта открыты для исследования. Я не добавлял комментарии, но старался писать код структурированным и понятным для изучения.

                Github?
                  –4
                  как-то не хочу захламлять своими поделками github
                    +8
                    Ничего себе «поделка»… зря вы так! Некоторые о таком даже и не мечтают… (не буду показывать пальцем). В общем интересная хорошая работа. Спасибо! А гитхаб и так захламлен всякими свисто-перделками на html. Терять вам нечего.
                      +1
                      Это нечто бОльшее, чем просто поделка. Выкладывайте, не стесняйтесь. Linux тоже начался как «небольшая ОС одного студента»… :)
                        +7
                        Гитхаб для того и нужен ;)
                          0
                          Выкладывайте, я уже готов отфоркать сию прелесть.
                            +2
                            положил на github
                          0
                          Смотрю на скриншоты и подпись «за пару дней», завидую.
                          Кстати, как ни печально, но под макосью 10.7.5, Safari 6.0.2 — бесконечный «loading...»
                            +2
                            в сафари надо включить webgl — discussions.apple.com/thread/3300585?start=0&tstart=0
                              0
                              Спасибо! Начал пользоваться сафари только с новой версии, до этого на хроме сидел.
                              0
                              У разработчика была маленькая форма — опыт работы c библиотекой :) Блин, надо юнити покопать наконец…
                              0
                              Не увидел списка поддерживаемыех браузеров :( Не запустилось ни в Опере, ни в Хроме, ни в FF. Надо вручную включать webgl?
                                +1
                                если он отключен, то лучше попробовать все-таки включить :)
                                  0
                                  В последней версии хрома 23.0.1271.97 m работает прекрасно.
                                    +2
                                    в хроме включено по умолчанию, в фф — тоже, но иногда не хочет, так что лучше хром, про оперу могу сказать только одно — не пробуйте
                                      0
                                      В Хроме не видно противников и вообще объектов (стрелаю в пустоту, по мне фигачит пустота), в FF бесконечная загрузка, в Опере аналогично.

                                      shot.qip.ru/00bl6T-2o8tiVHYk/

                                      Версия Версия 23.0.1271.97 m
                                        +1
                                        видимо стелс режим у противника, стреляйте на удачу!
                                        а по существу — не знаю чем вам помочь, посмотрите консоль javascript, может там ошибки какие есть
                                          0
                                          А ить и верно.

                                          THREE.WebGLRenderer 53 three.min.js:385
                                          THREE.WebGLRenderer: Float textures not supported.

                                          Это после загрузки, но до старта. После старта:

                                          WebGL: INVALID_OPERATION: getUniformLocation: program not linked planner5d.com:1
                                          WebGL: INVALID_OPERATION: getAttribLocation: program not linked planner5d.com:1
                                          WebGL: INVALID_OPERATION: useProgram: program not valid

                                          и т.п.

                                          слишком дохлая видеокарта?) (Intel встроенная, G33/G31 Express)
                                            0
                                            видимо да :) повод сделать себе подарок на НГ!
                                              +3
                                              Это рабочий компьютер) На домашнем ноутбуке точно запустится.

                                              P.S. Дожили...))
                                      +2
                                      самое то для ленивых праздничных поигрушек. у меня вот запланированы давно закупленные XCOM и Hotline Miami, а также диджей-контроллер Vestax VCI-380. вот между ними и буду стартублить!
                                        +1
                                        В 23-м Chrome под Ubuntu не грузится.
                                        В консоли:
                                        Error creating WebGL context.
                                        Uncaught TypeError: Cannot call method 'getExtension' of null.
                                          0
                                          к сожалению ваша система не поддерживает webgl, рекомендую под убунту nvidia карточку (у нас в офисе работает на ура)
                                            0
                                            Chromium под Linux'ом не умеет WebGL. Firefox — на ура.
                                            0
                                            Тоже самое, но 22 Хром под OpenSuse 12.1
                                              0
                                              Тоже самое в Chromium и FF под Gentoo.
                                                +1
                                                на встроенной карточке помог запуск со следующими параметрами:
                                                google-chrome --ignore-gpu-blacklist --enable-webgl
                                                0
                                                FF 17.0.1
                                                работает.
                                                замечания — босс, в отличие от других мобов умирает сразу, остальные пытаются встать.
                                                и пожелание — добавьте прицел =)
                                                  0
                                                  да, у босса иное поведение — он типа «танк» — у него с каждым разом все больше и больше хп и он не падает, а идет на пролом — это единственный способ убить умелого игрока
                                                    0
                                                    но всё равно как-то быстро «боссы» умирают =)
                                                    В общем очень даже круто для двух дней!
                                                  0
                                                  Реально круто для таких сроков. Только вот меня замочили два бота, которые стояли ко мне спиной за пределами радиуса поворота пушки :)
                                                  Но все равно круто, развивайте!
                                                    +2
                                                    ха, меня убили подлые мелкие чуваки, которые, как я думал, далеко находятся :) а они просто меньше ростом и стояли рядом!
                                                    +1
                                                    Мышка не захватывается?
                                                      +1
                                                      В Firefox запустилось, в Chromium 20 — “loading” и всё, WebGL включен.

                                                      Я так понимаю есть проблема с мышью, потому что курсор доходит до края и на этом всё? В браузерном EcmaScript предоставляется доступ к захвату курсора мыши?

                                                      Ещё есть вопрос с звуковым сопровождением, в частности я уже на хабре задавался вопросом, но ни к чему оптимальному не пришёл, — что если нужно расположить звук в пространстве? В HTML5 Audio есть даже реализация фильтров, где-то ссылочка была, например если отвернулся, — срезаем верха, отдалился — уменьшаем громкость. А вот как панорамировать звук — неизвестно.

                                                      Вот также интересная демонстрация WebGL в виде racing: triggerrally.com/x/Preview/Arbusu/drive
                                                        0
                                                        По поводу курсора — угол поворота камеры по горизонтали равен 180 градусам и они честно распределены по всей ширине области просмотра, по этому при выходе за края области — ничего не происходит. В браузере нельзя захватить курсор (я даже этому несколько рад).
                                                        По поводу звука — что нибудь придумаю, спасибо за ссылки, хотя эту демку я уже видел, но честно говоря не разглядывал ее детально.
                                                          0
                                                          Кстати насчёт захвата курсора я вспомнил что видео Quake 3, там просто отрисовывается карта и всё, можно побегать-посмотреть, но обзор мышью — полный, значит курсор можно захватить. А то, что нельзя — это бы не позволило сделать полноценный обзор кругом, это плохо, пусть и разрешения пользователя спрашивало, но возможность должна быть.
                                                            0
                                                            Нашёл: media.tojicode.com/q3bsp/ — при нажатии на Fullscreen — разворачивается на весь экран и захватывает мышь, полный обзор. Так что гипотетически все инструменты для шутера есть.
                                                              0
                                                              F11 и кнопка F == тот же эффект
                                                                0
                                                                Это вы к чему? F11 только убирает все панели, делает страницу на весь экран, «игра» по прежнему в небольшой области на странице. По нажатию F вообще ничего не происходит. А вот если там справа снизу нажать Fullscreen, — тогда сама область «игры» разворачивается на весь экран и захватывается мышь (фуррифокс спрашивает даже: «разрешить или запретить»). Так что != и тем более !==.
                                                            0
                                                            Вот ещё кое-какие интересные демо: www.chromeexperiments.com/webgl
                                                          0
                                                          Курсор мышки можно блокировать (см. также документацию в MDN).

                                                          Ну и, конечно, было бы круто добавить поддержку Fullscreen API — тем более, обычно это очень просто.

                                                          А вообще автор очень большой молодец. :)
                                                          0
                                                          Интересно же почитать, скиньте пож-та на github
                                                            +3
                                                            положил на github
                                                              0
                                                              отлично
                                                            0
                                                            Очень здорово! Заработало, правда, только в Хроме.
                                                            Опять зачесались руки попробовать это сделать на Canvas (пропали выходные, эх). Если это возможно, не могли бы Вы выложить модели? У меня с моделированием как-то не очень, увы.
                                                            0
                                                            Примитивненько, но для 2 дней очень круто. Я думаю, если нарядить немного монстров в новогодней тематике можно сделать крутую игру-открытку на новый год
                                                              0
                                                              Тема названия startublo не раскрыта)
                                                                0
                                                                Ха-ха, действительно, вы первый кто это заметил, но я правда пока и не собираюсь ее раскрывать, это будет в следующей версии, т.е. когда у меня появится побольше свободного времени.
                                                                0
                                                                В хроме 23.0.1271.97 m не заработало с index.html
                                                                Скопировал в хром ссылку из FF, после того как там поиграл, и загрузилась
                                                                  0
                                                                  Добавил управление с клавиатуры — стрелки для поворота пушки и пробел для стрельбы
                                                                    0
                                                                    Лучше бы PointerLock добавили для мышки, а то на 360 никак не повернуться (ну стрелки да, можно, но неудобно). Да и fullscreen через FullScreen API можно было бы сделать.
                                                                      0
                                                                      Как появится время — обязательно

                                                                  Only users with full accounts can post comments. Log in, please.