Физика
В Blend4Web существует два варианта физического поведения объектов: cтатический и динамический. В первом случае предполагается, что с течением времени объект не будет изменять своё положение в пространстве. Во вторую же группу входят все объекты, которые могут быть перемещены под действием физики: все персонажи, различные подбираемые объекты, коробки, бочки и т.д.
Кроме того существует два возможных варианта построения физического объема объекта:
- по его реальной геометрии;
- с применением физических примитивов (сфера, куб, капсула и т.д.).
Статические объекты
Земля будет статическим объектом с генерацией физического объема по геометрии. Для этого в настройках физики объекта выбираем Physics Type: Static, а в настройках материала необходимо включить флаг Special: Collision. Теперь динамические объекты будут входить в соударение с землей, а персонаж, соответственно, сможет ходить по ней.
С домом можно было бы сделать всё то же самое, но в нашем случае мы прибегнем к небольшой оптимизации. С целью облегчения физической геометрии, мы создадим новый объект со значительно уменьшенным количеством вершин. На его материале включаем Special: Collision и так же запрещаем рендеринг для него c помощью флага Do not Render. На изображении ниже этот материал имеет зеленый цвет.
Последнее, на что стоит обратить внимание при настройке сцены - это тип поведения камеры. В нашем случае следует использовать STATIC, чтобы на камеру оказывали влияние только скрипты, которые буду написаны в приложении.
Управление
Пришло время оживить созданную сцену. Воспользуемся базовым каркасом для приложения из документации разработчика. В обработчике загрузки поместим следующий код:
function load_cb(data_id) {
var camobj = m_scs.get_active_camera();
var character = m_scs.get_first_character();
m_cons.append_stiff_trans(camobj, character, [0, 0.7, 0]);
var canvas_elem = m_main.get_canvas_elem();
canvas_elem.addEventListener("mouseup", function(e) {
m_mouse.request_pointerlock(canvas_elem);
}, false);
setup_movement()
}
Здесь, во-первых, происходит жёсткая привязка камеры к персонажу с отступом вверх на высоту 0.7. Во-вторых, происходит попытка захвата курсора при щелчке на элемент canvas. Аддон mouse.js автоматически позаботится о том, чтобы при перемещении мыши происходил поворот персонажа.
Теперь напишем логику управления в функции setup_movement. Для начала зададим все переменные, которые будем использовать.
var key_a = m_ctl.create_keyboard_sensor(m_ctl.KEY_A);
var key_s = m_ctl.create_keyboard_sensor(m_ctl.KEY_S);
var key_d = m_ctl.create_keyboard_sensor(m_ctl.KEY_D);
var key_w = m_ctl.create_keyboard_sensor(m_ctl.KEY_W);
var key_space = m_ctl.create_keyboard_sensor(m_ctl.KEY_SPACE);
var key_shift = m_ctl.create_keyboard_sensor(m_ctl.KEY_SHIFT);
var move_state = {
left_right: 0,
forw_back: 0
}
var move_array = [key_w, key_s, key_a, key_d, key_shift];
var character = m_scs.get_first_character();
Первые 6 строк создают сенсоры клавиш управления. Помимо типового WASD управления так же будет ускорение на SHIFT и прыжок на пробел. Объект move_state отвечает за наличие скорости в прямом и в боковом направлениях. move_array - массив управляющих сенсоров. В качестве объекта управления получаем первого найденного на сцене персонажа и сохраняем его в переменную character. Далее объявим основной обработчик управления move_cb.
var move_cb = function(obj, id, pulse) {
if (pulse == 1) {
switch (id) {
case "FORWARD":
move_state.forw_back = 1;
break;
case "BACKWARD":
move_state.forw_back = -1;
break;
case "LEFT":
move_state.left_right = 1;
break;
case "RIGHT":
move_state.left_right = -1;
break;
case "RUNNING":
m_phy.set_character_move_type(obj, m_phy.CM_RUN);
break;
}
} else {
switch (id) {
case "FORWARD":
case "BACKWARD":
move_state.forw_back = 0;
break;
case "LEFT":
case "RIGHT":
move_state.left_right = 0;
break;
case "RUNNING":
m_phy.set_character_move_type(obj, m_phy.CM_WALK);
break;
}
}
m_phy.set_character_move_dir(obj, move_state.forw_back,
move_state.left_right);
};
Этот обработчик будет срабатывать при нажатии или отпускании любой из клавиш: W, A, S, D, Shift. Первому случаю (нажатию) соответствует значение pulse равное 1, второму (отпусканию) - значение -1. move_state несёт в себе информацию о текущих нажатых клавишах, так, к примеру, его поле forw_back будет равно:
- 1, если нажата клавиша W,
- -1, если нажата S
- 0, если ни одна из этих клавиш не нажата
За логику вызовов функции move_cb будут отвечать следующие сенсорные множества:
m_ctl.create_sensor_manifold(character, "FORWARD", m_ctl.CT_TRIGGER,
move_array, function(s) {return s[0]}, move_cb);
m_ctl.create_sensor_manifold(character, "BACKWARD", m_ctl.CT_TRIGGER,
move_array, function(s) {return s[1]}, move_cb);
m_ctl.create_sensor_manifold(character, "LEFT", m_ctl.CT_TRIGGER,
move_array, function(s) {return s[2]}, move_cb);
m_ctl.create_sensor_manifold(character, "RIGHT", m_ctl.CT_TRIGGER,
move_array, function(s) {return s[3]}, move_cb);
var running_logic = function(s) {
return (s[0] || s[1] || s[2] || s[3]) && s[4];
}
m_ctl.create_sensor_manifold(character, "RUNNING", m_ctl.CT_TRIGGER,
move_array, running_logic, move_cb);
Все сенсорные множества имеют тип CT_TRIGGER, то есть срабатывают при любом изменении значения логической функции. Логика ускоренного движения персонажа включает в себя все 5 сенсоров. Таким образом увеличение и снижение скорости происходит, если изменяется значение одного из сенсоров движения и сенсора клавиши Shift.
Последнее действие - это прыжок персонажа:
var jump_cb = function(obj, id, pulse) {
m_phy.character_jump(obj);
}
m_ctl.create_sensor_manifold(character, "JUMP", m_ctl.CT_SHOT,
[key_space], null, jump_cb);
Здесь всё так же, как при перемещении персонажа, только сенсорное множество изменило свой тип на CT_SHOT. Таким образом, событие вызывается только при нажатии на клавишу пробел, но не при её отпускании.
В результате этих нехитрых операций мы получили отличную заготовку для полноценной игры с видом от первого лица. Можно пойти дальше и добавить возможность подбирать объекты, носить в руках какие-либо орудия, позволить персонажу взаимодействовать с окружающими объектами при нажатии на разные клавиши.
Ссылка на приложение в отдельном окне.
Исходные файлы моделей войдут в состав бесплатного дистрибутива Blend4Web SDK.
Вы можете обсудить эту статью и сделать предложения в соответствующей теме.
Оригинальная статься находится здесь.
#Blend4Web, #first person, #FPS, #game, #shooter, #WebGL
13 февраля 2015