@gosha_tst

Принцип работы анимации?

Никак не могу понять, как работает анимация. Есть такой алгоритм (2D платформер на SFML): есть тайлсет, содержащий в себе текстуры персонажа. В одном из полей класса персонажа создается currentFrame и FloatRect rect, а в главном цикле переменная time, которая делится на какое-то число. Код функции, в котором используются эти переменные:
void update(float time) {
	sprite.setTextureRect(IntRect(0, 190, 40, 50)); // Устанавливает спокойный спрайт игрока

	rect.left += dx * time; // rect.left - координата x
	if (!onGround) {
		dy += 0.005*time; // 0.005 - ускорение, 
	}
	rect.top += dy*time; // rect.top - координата y
	onGround = false;
	if (rect.top > ground) {
		rect.top = ground;
		dy = 0;
		onGround = true;
		// Если координата по y больше координаты земли по y, то скорость по y = 0, а игрок становится на земле
	}

	currentFrame += 0.005; // 0.005 - скорость анимации 
	if (currentFrame > 6) currentFrame -= 6;
		
	if (dx>0) sprite.setTextureRect(IntRect(40 * int(currentFrame), 244, 40, 50));
	if (dx<0) sprite.setTextureRect(IntRect(40 * int(currentFrame) + 40, 244, -40, 50));

	sprite.setPosition(rect.left, rect.top);

	dx = 0;
}


Сами вопросы: 1) почему currentFrame обнуляется именно после достижения 6? 2) зачем в последних двух условиях координата x умножается на округленное currentFrame? 3) зачем rect.top и rect.left складываются с dx(y)*time?
Заранее благодарю.
  • Вопрос задан
  • 537 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
time — это длительность такта (в игре, очевидно, не просто переменный FPS, но и переменная тактовая частота). Писал такое, правда, не в платформере, а в гоночке.

rect.left — это точное решение дифура left′ = dx (движение с постоянной скоростью). Очевидно, dx где-то устанавливается по управлению.

rect.top и dy — это приближённое решение дифура top′′ = 0,005, если снят флаг onGround (полёт под действием силы тяжести). Здесь 0,005 — это ускорение силы тяжести, ось Y направлена вниз. Дифур второго порядка, преобразуется в систему top' = dy, dy′ = 0,005, и то, что в первом случае было точным, здесь приближённое, но приемлемое для игр.

currentFrame просто прокручивается, чтобы 6-кадровая анимация прошла за 1200 тактов, независимо от частоты. Здесь 1200 = 6 / 0,005.

Заметьте, dx и dy проходят по разным трактам данных: один — состояние управления, второй — состояние физики персонажа. К тому же что делает dx = 0 и где он ставится не в 0, чтобы не зависеть от частоты автоповтора клавы — непонятно. И много магических констант. Говнокод.

UPD. Прямые ответы на ваши вопросы.
1) 6-кадровая анимация, но тут одно из двух. Либо из-за огромного цикла (1200 тактов) явно анимируются не ноги. А может, афтар гонит такты с предельной частотой и потому 1200 тактов действительно пройдут за секунду-две, но тогда это слишком уж явная привязка к скорости компьютера;
2) в зависимости от номера кадра выбираем тот или иной спрайт на атласе;
3) dy — скорость, и чтобы откорректировать положение (rect.y), надо прибавить к нему скорость·время.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы