Урок 7 SFML принцип создания анимации

На прошлом уроке мы разбирались со “временем SFML “, значит теперь самое время разобраться с анимацией. Как я уже говорил – анимация это быстрое переключение прямоугольников с картинками. Для начала слегка почистим код с предыдущего урока, удалив 

ненужный нам таймер телепортации героя – удалите строки с этой переменной и все, что с ней связано.

Видеоверсия sfml урок 7

 

Если вы не особо поняли как работать с координатами в том же паинте – посмотрите предыдущие уроки ( 3,4 ). Здесь координат будет не мало, вам надо научиться их правильно извлекать.

Вернемся к созданию анимации. Нам нужна переменная, которая будет передвигать кадры нашей анимации благодаря времени, она будет хранить в себе текущий кадр. Объявим еще в ф-ции main:

float CurrentFrame=0;//хранит текущий кадр

Для начала я распишу на примере кнопки влево и разделив всё построчно с комментариями.

Напомню – у меня персонаж лев:

hero

И я хочу сделать анимацию “влево”, значит мне нужно пройтись по второму ряду льва и делать это “пока нажата клавиша влево”

В функции пока открыто окно, где у меня было управление персонажем, напишем вот такую строчку для клавиши “влево”, предварительно стерев предыдущую. Смотрим комментарии:

 

Аналогично поступаем для остальных клавиш:

 

 

Когда поймете что к чему – скомпонуйте для удобства и компактности код. Хочется отметить , что лучше использовать отдельный класс анимации и отделять ему отдельный заголовочный файл – это поможет увеличить читаемость кода и убрать лишнюю кашу, поскольку в реальных играх количество строк кода будет зашкаливать :) Ну об этом поговорим как-нибудь.

В моем случае на картинке есть движение льва и влево и вправо. Но что делать, если есть только влево ? Можно в редакторе (хоть в паинте) добавить вручную вправо (путем “отразить по горизонтали” и получится как у меня). Но это не лучший вариант. Лучше всего отразить с помощью кода. Есть несколько способов.

setScale(-1, 1);

этой функцией можно менять размер спрайта. Если напишите setScale(2, 2);  то увидите какой большой лвёнок получился. Если бы у нас марио съел гриб – можно было бы использовать :) Так вот этой функцией можно отразить спрайт, задав отрицательную координату. По х – отразите по горизонтали, по у – по вертикали.

Еще один способ отразить изображение:

Итак – текущий кадр у нас +96 то есть правый край и координата -96 означает, что мы идем наоборот справа налево, таким образом рисуя наоборот. Получается, что мы делаем инверсию и отражаем по горизонтали. Аналогичным способом можно начудить по Y.

Или вот например. Если у вас танк в виде квадрата с палкой (дуло), то вам достаточно будет одного его изображения в одном состоянии и можете использовать повороты:

 

То есть не обязательно рисовать несколько состояний персонажа в редакторе. Можно обойти всё кодом и изображение будет меньше “весить”.

 

В будущем создадим класс анимаций. Пока поживем так. Заметьте, что наш персонаж может двигаться по диагонали и к тому же делает он это быстрее, а всё потому, что выполняется сразу два условия и его скорости суммируются. Как это обойти? Сделать четыре направления для персонажа. Ну или исключить нажатие другой клавиши,. Первый вариант лучше. Рассмотрим эти вещи в следующем уроке. Счастливо :)

 

 

Листинг урока:

 

Буду благодарен, если поделитесь:
SFML вопросы, прошу, задавайте на форуме.
  1. спасибо за уроки.
    но не очень понял эту строку

    "
    первое 96 это на сколько передвигается прямоугольник. а остальные?

  2. Добрый день, Павел!

    Осваиваю SFML с помощью твоих уроков. Все просто, понятно и очень подробно описано. Большое спасибо за эти статьи!

    Однако есть некоторые проблемы с ротацией спрайтов. Был удивлен, что метод setRotation() поворачивает спрайт относительно верхнего левого угла, а не относительно центра изображения. Таким образом, картинка визуально при повороте вроде как “перепрыгивает” на новые координаты. Есть ли красивый способ решить эту проблему? Ниже приведен мой код.

    P.S. Еще раз хочу поблагодарить за великолепные уроки 😉

  3. Спасибо большое! Уроки просто восхитительны! Только вот возник такой вопрос. При нажатии кнопки “Вправо” мой персонаж, начинает двигаться вправо, при нажатии “Влево” соответственно влево. После того, как отпускаем клавишу, то персонаж остаётся в том спрайте, на каком он остановился. А как, например, сделать условие, “Если не нажато ничего, то вставляется определённый спрайт”?

Добавить комментарий