Движение по точкам (waypoints)

в 8:48, , рубрики: actionscript, game development, Gamedev, javascript, jquery, waypoints, Алгоритмы, метки: , , ,

Сегодня мы будем рассматривать реализацию движения игрока по точкам — так называемым вейпоинтам (waypoints) в режиме 2D — а именно вид сверху.

Движение по точкам (waypoints)

В алгоритме нет чего-то сверхъестественного, но одна вещь делает его пригодным к использованию для меня. По началу реализовав свой алгоритм я получил не совсем то что хотелось бы, не было реализма, или какой-то правильности, в общем что-то не хватало. Начались поиски… И было найдено решение. Момент этот связан в коде с переменной «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

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js