Сегодня мы будем рассматривать реализацию движения игрока по точкам — так называемым вейпоинтам (waypoints) в режиме 2D — а именно вид сверху.
В алгоритме нет чего-то сверхъестественного, но одна вещь делает его пригодным к использованию для меня. По началу реализовав свой алгоритм я получил не совсем то что хотелось бы, не было реализма, или какой-то правильности, в общем что-то не хватало. Начались поиски… И было найдено решение. Момент этот связан в коде с переменной «pathThreshold», как это перевести точно я не знаю, переводчик говорит что это «Порог пути», но для себя перевел как «Дистанция прибытия». Эта переменная указывает за какое расстояние до точки прибытия — переключаться на движение к следующей точке, что делает движение от точки к точке более правильным.
Думаю, хватить объяснять, а то запутаю, лучше посмотрим код.
Псевдокод на javascript (упрошен для понимания, строго не судить). Описывается 1 игровой цикл:
// Создается игрок
var e = [];
e['pathThreshold'] = 10;// Дистанция прибытия
e['waypoint'] = 0;// Точка к которой нужно двигаться
// Создается объект где будут храниться все точки пути
e['waypoints'] = [];
// При клике создается объект с координатами клика
var a = [mouseX, mouseY];
// И добавляется в объект с точками передвижения
e['waypoints'].push(a);
// Создается функция отвечающая за движение игрока
function FollowPath(e, loop)
{
// Текущая точка к которой нужно двигаться
var wayPoint = e['waypoints'][e['waypoint']];
// Если точка отсутствует - ничего не делаем
// Значит игрок стоит на месте
if(wayPoint == null) return false;
// Вычисляется расстояние от текущего
// положения игрока до точки к которой движемся
// И если оно меньше "Дистанции прибытия"
// определяем как именно поступить
if(dist(e, wayPoint) < e['pathThreshold'])
{
// Если вейпоинты кончились, т.е. это был последний
if(e['waypoint'] >= e['waypoints'].length)
{
// Если цикличность - true
if(loop)
{
// текущюю позицию сбрасываем в начало
// (движемся туда откуда начали)
e['waypoint'] = 0;
}
}
else
{
// Увеличиваем текущюю позицию на 1
// (переходим к движению к следующей точке)
e['waypoint']++;
}
}
// Если цикличность (loop) - false
// то игрока нужно остановить в последней точке
if(e['waypoint'] >= e['waypoints'].length && !loop)
{
// Срабатывает функция торможения (остановки) игрока
stop(e);
}
else
{
// Срабатывает функция передвижения игрока к точке
seek(e, wayPoint);
}
}
// Функция вычисляет расстояние от текущего
// положения игрока до точки к которой движемся
function dist(e, wayPoint)
{
// В каждой игре своя логика расчета
// Просто вернем, например, 7
return 7;
}
// Функция отвечает за торможение (остановку) игрока
function stop(e)
{
// В каждой игре своя логика
// Мы, например, затормозим так
e['speed']--;
}
// Функция отвечает за передвижение игрока к точке
function seek(e, wayPoint)
{
// В каждой игре своя логика
// Мы, например, переместим игрока так
e['x']++;
e['y']++;
}
FollowPath(e, true);
// Хотел коротко, все равно получалось много, извиняйте :)
Данный метод наверно знаком многим, и многие флешеры наверно даже что-то узнали. Код в этой статье — реализация actionscript кода из книги «AdvancED ActionScript 3.0 Animation», но на javascript. Собственно хорошая книга по разработке игр на flash (actionscript) — много алгоритмов и есть исходники.
Ссылка на книгу и исходники
AdvancED ActionScript 3.0 Animation, Keith Peters
Автор: cybernetic