Hidden structure #2

Немного о технической стороне и используемой логике.

Это продолжение, начало можно почитать вот здесь:

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

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

Дальше стал выбор: а собственно как строить уровни, делать их монолитом или использовать тайловый подход? Выбрал тайлы, потому что это удобно. Сделал небольшой тайловый набор с текстурами и каждому из них присвоил класс в js. Сами карты уровней решил хранить в виде массива каждый в отдельном js-файле. Написал функцию, которая при загрузке документа выводит весь массив в окно браузера и каждому элементу массива - соответствует свой тайл с текстурой в виде квадратного div.

Каждому классу тайлов в CSS соответственно указал какая текстура должна быть привязана, и z-index - какой тайл может отображаться поверх другого.

Дальше пришлось поморочиться, нужна функция определяющая можно ли игроку перемещаться вперёд/назад/влево/вправо или перед ним находится дверь/стена/монстр и т.д. Одним словом нужен "движок" эмулирующий физику столкновений. А так как никаких фреймворков я не использовал - то сделал следующее:

Написал функцию определяющую класс тайла, находящегося перед игроком на расстоянии в один тайл в том направлении куда он должен двигаться после нажатия кнопки/свайпа по тачскрину. Если класс тайла "wall" или "person", то игрок "упрется" в стену или персонажа и не пройдет сквозь него, функция установит значение флага разрешающего движение в "0". И наоборот, если класс близлежащего тайла "empty", то функция установит флаг разрешающий движение персонажа в значение "1" и дальше передаст его в функцию, которая передвинет персонажа в нужном направлении и добавит анимацию ходьбы.

Шаг сетки для ходьбы персонажа при этом 10px а размеры тайлов стен и обьектов 50px на 50px - такое соотношение позволяет создать иллюзию плавного перемещения персонажа по уровню.

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

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

1.Определяем есть ли столкновение с игроком, если да, то атакуем и наносим ему урон. (если в этот момент игрок стреляет, отнимаем жизни у бота соответственно)

2.Если столкновения нет, но игрок находится на минимально допустимом расстоянии(этот параметр можно настраивать - на сколько далеко бот может увидеть игрока) - двигаемся в сторону игрока для атаки.

3.Если столкновения нет, игрока в поле зрения тоже нет - совершаем рандомное передвижение по уровню.

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

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

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

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

Сейчас игра доступна на двух ресурсах:

Версия, которая постоянно обновляется:

и более стабильная старая версия:

77
4 комментария

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

Чем canvas не угодил? 

Возможно я ошибаюсь, но что бы элементы canvas расположенные один над другим или по соседству реагировали на клик/тач или свайп, придется писать кучу кода на js, или использовать библиотеку - что не входило в поставленные мной условия: разработать игру с ноля, без использования фреймворков и библиотек,  только html, js и css. (про это писал в первой статье)