15. Мульти анимация
read paper in english
В данном уроке мы проведем своего рода быстрый старт - это введение в создание игр в среде fle game engine.
Содержание
страница 1 - Спрайты
страница 2 - Объекты
страница 3 - Наложение объектов
страница 4 - Код - Настройка параметров Scene Editor fge и написание кода для вывода спрайта шарика в вашем первом игровом приложении
страница 5 - Отображаем прыгающий шарик
страница 6 - Загрузка игровой сцены
страница 7 - Перемещения игровой сцены
страница 8 - Закрываем часть сцены от пустот при помощи черной текстуры с прорезью, ограничиваем перемещение сцены
страница 9 - Реализуем корректное попадание в ямы и около ям - определяем границы спрайтов ям и спрайта прыгаюшего шарика
страница 10 - Проверка столкновений
страница 11 - Игровой счёт, звуки, музыка
урок #2 страница 1 - Создание новых сцен для игры simple game, расширенная версия simple game extended
13. Скроллинг больших локаций
14. использование переменных в игре на c++ directx 9c
15. Мульти анимация
Прошло совсем немного времени с момента написания урока про Спрайты.
Тема данного урока - изучить как можно использовать в игре не один, а несколько спрайтов. У одного персонажа анимаций может быть несколько: прыжки, хотьба, какие-то иные действия и т. п.
Это есть не что иное как МНОЖЕСТВЕННЫЕ АНИМАЦИИ, поэтому я и назвал урок Мульти анимация.
Мы будем рассматривать как использовать несколько анимаций относящихся к одному и тому же персонажу - в нашем случае - к Зеленому Шарику.
Вы можете заметить: что нового в мультианимации по сравнению с обычной ? Ведь что одна, что много - работа с ними ведется по-сути одинаково.
Да, вы это справедливо заметили, но не все так просто.
Хорошо, когда все анимации у вас циклические и неважно когда остановить анимацию. Например наш шарик - он прыгает постоянно и для нас совершенно неважно на каком текущем кадре он сейчас. Все эти кадры просто воспроизводятся циклически и бесконечно.
Но как быть когда анимацию нужно показать лишь однократно ? Причем важно чтобы она остановилась именно на нужном кадре, а не любом ?
Вот эти особенности я и хотел бы рассмотреть в статье, т. е. увязку множества анимаций как количественно, так и качественно в плане программной их части.
Помимо этого, можно коснуться немного реализации логики воспроизведения анимаций. Одни анимации нужно показывать при одних условиях, другие - при иных и все это реализуется функционалом программной части.
Художник может лишь показать на спрайте, что с ним происходит, а задача программиста не только показать созданный спрайт, но и реализовать условия по которым этот спрайт будет отображен в игре. Помимо этого нужно еще и запрограммировать особенности воспроизведения самой анимации: будет ли она (опять же) цикличной или однократной. Может быть она будет реверсивной - воспроизводимой в обратном порядке от конца к началу. И т. п.
Вот методы, которые нужно объявить в классе CGameSprite, для того, чтобы использовать однократно воспроизводимую анимацию Дразнящего Шарика.
//анимация Дразнящего Шарика (показывает язык)
void Draw_Showing_Tongue();
void Anim_Showing_Tongue();
float m_fShowing_Tongue_Sprite_Frame;
bool m_bAnim_Showing_Tongue_Stopped; //завершилась ли анимация Дразнящего Шарика
void Start_Showing_Tongue_Anim();
void Restart_Showing_Tongue_Anim();
Суть реализации заключается в следующем: при определенном условии - например если в течение 15 секунд подряд шарик ни разу не был пойман в ямку должна быть показана данная анимация - однократно - т. е. показана с начала и с остановкой на последнем кадре.
Метод
Draw_Showing_Tongue() отрисовывает текущий кадр анимации шарика.
Anim_Showing_Tongue() - выполняет анимирование, т. е. переключение кадров при изменении счетчика времени.
Поле -
m_fShowing_Tongue_Sprite_Frame запоминает текущий кадр анимации и нужно для того, чтобы один и тот же спрайт мог использоваться независимо разными игровыми объектами. Для этого просто каждый игровой объект должен иметь у себя такое поле.
Тогда, перед выполнением анимации игровой объект запоминает текущий кадр спрайта, передает ему свой текущий кадр, выполняет анимацию, затем
запоминает на каком кадре он остановился и возвращает спрайту его текущий кадр.
Поле -
m_bAnim_Showing_Tongue_Stopped служит для фиксации момента завершения анимационной цепочки. Если цепочка закончилась - то поле получит значение true. Таким образом приложение будет знать, что анимация спрайта закончилась и можно переходить к другим действиям. В моем примере - снова будет отображаться анимация обычного прыгающего шарика.
Ну и наконец метод
Start_Showing_Tongue_Anim() используется приложением для запуска анимации. В моем примере - если в течение 15 секунд шарик ни разу не был пойман в ямку, то будет вызван данный метод и запущен процесс показа этой анимации.
Когда анимация закончилась нужно, чтобы при следующем вызове
Start_Showing_Tongue_Anim() она снова началась с 0 кадра. Для этого и служит метод
Restart_Showing_Tongue_Anim().
Вот собственно и все.
Теперь вы наверное, хотели бы увидеть реализацию все описанных методов.
Пожалуйста, ознакомтесь.
//анимация Дразнящего Шарика (показывает язык)
void CGameSprite::Draw_Showing_Tongue()
{
LPD3D9SPRITE usedSprite = NULL;
int ball_sprite = ball_showing_tongue;
if ( m_iCurrentSprite == SpriteTexIndex )
ball_sprite = ball_showing_tongue;
if ( m_iCurrentSprite == ball_jump_red_SpriteTexIndex )
ball_sprite = ball_showing_tongue_red; //для красного шарика используется свой спрайт
usedSprite = GetGameSprite(ball_sprite, g_AI_Ball_Sprite.m_pTextures);
float OldFrame;
if ( usedSprite != NULL )
{
OldFrame = usedSprite->Frame;
usedSprite->Frame = m_fShowing_Tongue_Sprite_Frame;
Vector2Screen(&m_v2VectorPos, &m_v2Pos); //переводим векторные координаты
//в пиксельные
usedSprite->m_v2Vector2ScreenPos = m_v2Pos;
//выполняем отрисовку спрайта по указанным координатам и с указанным масштабом
usedSprite->Draw2(
m_v2Pos.x,
m_v2Pos.y,
m_vBallZ,
usedSprite->m_Scale.x,
usedSprite->m_Scale.y,
255);
usedSprite->Frame = OldFrame;
}
}
void CGameSprite::Anim_Showing_Tongue()
{
LPD3D9SPRITE usedSprite = NULL;
int ball_sprite = ball_showing_tongue;
if ( m_iCurrentSprite == SpriteTexIndex )
ball_sprite = ball_showing_tongue;
if ( m_iCurrentSprite == ball_jump_red_SpriteTexIndex )
ball_sprite = ball_showing_tongue_red; //здесь аналогично - для красного шарика свой спрайт
usedSprite = GetGameSprite(ball_sprite, g_AI_Ball_Sprite.m_pTextures);
float OldFrame;
if ( usedSprite != NULL )
{
OldFrame = usedSprite->Frame;
usedSprite->Frame = m_fShowing_Tongue_Sprite_Frame;
usedSprite->FrameMove_StopOnEndFrame(g_fElapsedTime, &m_bAnim_Showing_Tongue_Stopped);
m_fShowing_Tongue_Sprite_Frame = usedSprite->Frame;
usedSprite->Frame = OldFrame;
}
}
void CGameSprite::Start_Showing_Tongue_Anim()
{
m_bAnim_Showing_Tongue_Stopped = false;
m_dwAnimState = BAS_SHOWING_TONGUE; //когда была запущена данная анимация выставляем у объекта
//такое состояние
//чтобы знать какой метод использовать для его отрисовки и анимирования
}
void CGameSprite::Restart_Showing_Tongue_Anim()
{
m_fShowing_Tongue_Sprite_Frame = 0.0f;
}
На этом все.
[назад] [далее]