Итак, игра «Воин Света» — это двухмерный космосим с видом сверху. Blend4Web является трехмерным движком и в его API нет готовых методов для работы с 2D. Конечно имеется большое количество низкоуровневых функций. Поэтому приходиться работать с ними.
На данном этапе разработки игры я озадачился вопросами математических вычислений в двухмерном пространстве для создания логики функционирования кораблей противника. Первым в моем списке стоит «Дальний разведчик». По задумке, данный корабль представляет собой слабовооруженное судно, стремящееся покинуть поле битвы в случае обнаружения. Исходя из сказанного, логика поведения разведчика выглядит следующим образом:
Хаотичное движение по ключевым точкам.
В случае обнаружения корабля Игрока, прекратить предыдущее перемещение и удалиться из поля видимости с увеличением скорости. Отстреливаться по ходу движения.
Вернуться к патрулированию через некоторое время.
Есть два варианта создания игрового уровня: все действующие объекты сразу находятся на своих местах, либо генерируются в соответствии с заданным временем. Я выбрал второй вариант, что несколько усложняет программирование и балансировку, но с другой стороны имеет свои преимущества в виде экономии вычислительных ресурсов и некоторого случайного фактора.
В соответствии с этой концепцией, основная камера является неподвижной, все вспомогательные объекты также неподвижны, а иллюзия движения выполняется с помощью эффекта параллакса.
Всего в игре два глобальных места для генерации объектов. Верхние точки значительно удалены от экрана и предназначены для генерации метеоритов. Для последних случайным образом выбираются места создания, скорость перемещения и размер. Именно поэтому есть некоторое пространство между пунктами генерации метеоритов и самим экраном, чтобы несколько раскидать их стройные ряды. Другие точки вокруг экрана являются ключевыми местами для движения и генерации игровых объектов, например, кораблей противника.
Рассмотрим простое движение по координатным осям в двухмерном пространстве.
Код
var speed = 1.0; //скорость движения var elapsed = m_ctl.get_sensor_value(obj, id, 0); var coord = m_trans.get_translation(obj); // координаты объекта
coord [2] += speed*elapsed; //выбираем координату для движения m_trans.set_translation_v(obj.object, obj.coord);
Несколько сложнее выглядит перемещение по ключевым точкам.
Стандартные формулы расчета это:
velocity = normalize(target - position) * max_velocity position = position + velocity
В случае JavaScript и Blend4Web реализация их выглядит следующим образом:
Код
var velocity = new Float32Array(3); var maxVelocity = 0.7; //максимальная скорость перемещения
var obj = m_scene.get_object_by_name(“Object”); var objPos = m_trans.get_translation(obj); var destObj = m_scene.get_object_by_name(“TargetPoint”); var targetPos = m_trans.get_translation(destObj);
Этот код заставит двигаться объект Object в сторону точки TargetPoint с неизменной скоростью. Если нужно замедление и ускорение, то достаточно убрать нормализацию вектора (m_vec3.normalize()).
Когда объект достигает указанного места, то выполняется проверка на расстояние и вызывается функция выбора новой точки движения (из имеющихся в сцене).
Код
if (m_trans.distance(obj, destObj) < 0.5) GenerateWP (destObj.name);
// oldName - название старой точки движения function GenerateWP (oldName) { var min = 0; var max = 7; //максимальное количество пунктов -1 do { var number = Math.floor(Math.random() * (max - min + 1)) + min; var name = m_vars.WPS[number];//массив названий точек движения } while (oldName == name);
return name; }
Функция GenerateWP принимает на входе «отработавшую» точку движения и выдает имя нового пункта перемещения. Выбор выполняется случайным способом, но достаточно умно, с проверкой на дублирование.
В указанной схеме и алгоритме движения есть один недостаток: объект выполняет резкие переходы между точками. Наиболее простой способ устранить его — добавить плавный поворот объекта от предыдущего направления к новому.
Этой цели может служить следующая часть кода:
Код
var cur_dir = new Float32Array(3); var dir_to_dest =new Float32Array(3); var cur_rot_q = new Float32Array(4); var new_rot_q =new Float32Array(4);
var obj = m_scene.get_object_by_name("Player"); //объект А var objPos = m_trans.get_translation(obj); var destObj = m_scene.get_object_by_name("Target"); //объект Б var targetPos = m_trans.get_translation(destObj);
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:
Игровые объявления и предложения:
Если вас заинтересовал материал «Игра на Blend4Web. Логика движения в 2D (ч.1)», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела.
Предлагаются такие схожие материалы:
Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи. [ Регистрация | Вход ]