Информатика и образование
  Мобильная версия сайта            
               
[Главная] [Новости]
[Статьи]
[Проекты]
[Ссылки]
[Автор]
               
    [Архив новостей]        
               
  [Форум] на форуме можно задать вопрос, посмотреть ответы на часто задаваемые вопросы  
       
  Здравствуйте! Вы попали на информационно-образовательный сайт посвященный информатике, информационным технологиям и компьютерным играм. Подробнее о целях и задачах сайта в разделе Главная. [English version of this page here...]    
       
  [Базовые уроки по DirectX] [Основы DirectMusic на Delphi] [Основы DirectInput8 на Delphi] [Основы DirectSound8 на Delphi]    
  [Разработка компьютерной игры] [Пример игры Donuts3D] [Delphi DirectX]    
       
  Эмулятор электронной игры Электроника ИМ-02 "Ну, Погоди!"    
       
  триал-версия, 1,34 Mb   скачайте полную версию игры, зарегистрируйтесь и получите бесплатно полный исходный код игры для компиляции в delphi 7 или 2006 и уроки delphi directx 8.1 содержащие статьи по созданию собственной 2D/3D игры в среде delphi directx    
       
  Урок 7 2D-анимация    
       
  О том, что потребуется для данного урока читайте в основном разделе - уроки delphi directx 8.1    
       
  Далее у читателя подразумевается наличие базовых знаний языка Delphi.    
       
  [назад] [страница 1] [далее] [к содержанию]    
       
 

При создании 2D-анимации нужно учитывать следующие моменты:

- покадровое размещение анимированного изображения нужно производить в файле формата bmp, tga или dds. jpg для этих целей не подойдет, т.к. из-за сжатия возможно появление посторонних пикселей в тех местах изображения, где должен быть прозрачный фон;

- текстура обязательно должна быть квадратной и лучше одного из типовых размеров - 32х32, 64х64, 128х128, 256х256, 512х512, 768х768, 1024х1024 пикселя, если не учесть этот момент, то будут наблюдаться сдвиги картинки в кадре;

- если анимируется не один игровой объект, а несколько, то в класс TD3DImage2D или в производный от него класс нужно внести код, рассчитанный на запоминание текущего кадра и индивидуальной скорости анимации для каждого из игровых объектов, иначе все объекты будут выдавать синхронную и очень ускоренную анимацию из-за одновременных обращений к данным одного и того же разделяемого экземпляра класса TD3DImage2D. Далее будет показано как это сделать.

   
       
  Если Вы не совсем понимаете в чём состоит суть создания анимации, то советую сначала прочесть статью Создаем анимацию хотьбы волка в Photoshop и ImageReady    
       
  Для того, чтобы использовать такие анимированные изображения в игре можно воспользоваться классом TD3DImage2D, в который были добавлены возможности для анимирования.    
       
 

Для использования класса TD3DImage2D нужно выполнить следующие шаги

в секцию uses кода модуля, в котором Вы будете использовать данный класс добавить ссылку на модуль D3DGUI.pas (если Вы её еще не добавили, если же Вы уже используете в коде данный класс, пусть даже не для анимированных изображений, то естественно вторично добавлять ссылку в uses не нужно)

 

   
       
 

В папку ресурсов проекта добавляем нужное изображение, например, я это буду делать на примере добавления индикатора в игре "в плену желаний"

в папку Media\Textures\scene1 копирую нужный мне файл adgezio_indicator.tga

описываем имя файла текстуры в виде константы, это можно сделать в любом месте секции интерфейса нужного модуля вашего проекта

const

{...}

DesiresIndicatorTexture = 'Media\Textures\scene1\adgezio_indicator.tga';

В класс D3D-приложения, например TD3DGameApp добавляю новое поле -

DesiresIndicatorImage: TD3DImage2D;

это может происходить не только в классе приложения, но и например, в моём случае я добавляю поле в класс не приложения, а игровой сцены - TGameScene7Title, но суть от этого не меняется.

Далее с этим объектом (для корректного его использования) нужно проделать стандартные шаги, как и аналогичных объектов применяющих данный класс.

В методе конструктора класса (в моем проекте это TGameScene7Title.Create)

DesiresIndicatorImage := nil; //данный шаг необязателен, т.к. в экземпляре класса все указатели первоначально //инициализируются в nil, но данная строка кода явно демонстрирует этот шаг в коде

в методе загрузки объектов игровой сцены (или инициализации класса) выполняем загрузку текстуры из файла -

TGameScene7Title.LoadMiniGame2

{...}

DesiresIndicatorImage := TD3DImage2D.Create(g_d3dApp.m_d3dfmtTexture);
if DesiresIndicatorImage = nil then Exit;
hr := DesiresIndicatorImage.InitDeviceObjects(m_pd3dDevice, DesiresIndicatorTexture);
if Failed(hr) then Exit;

в методах реставрации (Restore), инвалидации (Invalidate) и освобождения (Free) нужно добавить соответствующий код -

TGameScene7Title.RestoreMiniGame2

{...}

if DesiresIndicatorImage <> nil then
DesiresIndicatorImage.RestoreDeviceObjects;

TGameScene7Title.InvalidateMiniGame2

{...}

if DesiresIndicatorImage <> nil then
DesiresIndicatorImage.InvalidateDeviceObjects;

TGameScene7Title.FreeMiniGame2

{...}

SAFE_DELETE(DesiresIndicatorImage);

   
       
 

Эти операции относятся к любому объекту класса TD3DImage2D не зависимо от того, будет ли он анимированным или статичным.

Теперь перечислим действия обязательные для того, чтобы анимация заработала, т.е. начали в определенной последовательности и с определенной скоростью меняться кадры анимированного изображения.

в методе загрузки объектов игровой сцены после кода загрузки текстуры нужно добавить ряд параметров, касающихся анимации -

TGameScene7Title.LoadMiniGame2

{...}

DesiresIndicatorImage.Width := 70;
DesiresIndicatorImage.Height := 16;
DesiresIndicatorImage.TextureOffsetX := 0;
DesiresIndicatorImage.TextureOffsetY := 128;
DesiresIndicatorImage.Frame := 0;
DesiresIndicatorImage.FramesPerLine := 3;
DesiresIndicatorImage.Delay := 10;
DesiresIndicatorImage.fMaxFrame := 5;

Эти строки задают размер кадра анимации, смещение до начала анимационной последовательности на текстуре (если таковых несколько), начальный кадр анимации, количество кадров на строку анимационной последовательности, скорость анимации, определяемая временной задержкой в миллисекундах, номер последнего кадра анимационной последовательности.

   
       
 

в методе рисования сцены нужно добавить рисование анимированного или статичного изображения -

TGameScene7Title.DrawMiniGame2

{...}

DesiresIndicatorImage.DrawScaled(-1.0, 1.0, 0.9, 0.35, 0.35,
DrawD3DImage2D_Filtered, 255, True);

Обратите внимание, что для анимированных изображений вызывается функция рисования DrawScaled с новым параметром True, который необходим для анимированных изображений и определяет корректную выборку кадров

   
       
 

в методе анимирования сцены нужно добавить 2 строки кода -

TGameScene7Title.AnimMiniGame2

{...}

FTimeLapsed := DXUtil_Timer(TIMER_GETELAPSEDTIME);

DesiresIndicatorImage.FrameMove(FTimeLapsed);

первая строка потребует, чтобы Вы объявили FTimeLapsed: Single; внутри класса игровой сцены и производит запрос интервала времени прошедшего с последнего вызова от системного таймера

вторая строка кода передает полученный интервал в метод анимирования изображения. если Вы используете подвижный спрайт, то Вам лучше описать его в виде отдельного класса, а его перемещение по экрану реализовать внутри его метода анимации или так как это выполнено в игре "Ну, Погоди!". В её коде для анимационного ролика создан отдельный модуль GameCartoonScript.pas и отдельный класс TGameCartoon. Внутри него и происходит всё самое интересное касающееся реализации анимации 2D-спрайтов.

   
       
 

Теперь приведем пример кода, который можно использовать для одновременной анимации множества подобных объектов.

В методе анимации TGameScene7Title.AnimPauseScreen

{...}

for i := 0 to StarsNum-1 do begin
StarsImage.Delay := Stars[i].Delay;
//заносим текущую скорость в экземпляр TD3DImage2D
StarsImage.Frame := Stars[i].Frame;
//а также номер текущего кадра
StarsImage.FrameMove(FTimeLapsed);
//выполняем анимацию
Stars[i].Frame := StarsImage.Frame;
//запоминаем новый текущий кадр в данных игрового объекта
end;

В методе рисования TGameScene7Title.DrawStars;

for i:= 0 to StarsNum-1 do begin
StarsImage.Frame := Stars[i].Frame;
//заносим текущий кадр в экземпляр TD3DImage2D
StarsImage.DrawScaled(Stars[i].vPos.x,
//выполянем рисование данного текущего кадра
Stars[i].vPos.y, 0.9,
Stars[i].Size, Stars[i].Size, DrawD3DImage2D_Filtered,
Stars[i].Alpha, True);
end;

   
       
  Как видите всё достаточно просто, нужно лишь запоминать данные об текущем кадре и скорости анимации в каждом игровом объекте. Для сильно различающихся по свойствам игровых объектов (в частности использующих разные экземпляры TD3DImage2D) конечно же лучше использовать производные классы.    
       
  В следующем уроке Вы узнаете как реализовать многие из особенностей игрового проекта, которые не имеют прямого отношения к самому игровому процессу, но являются важной частью любого игрового приложения - режимы сохранения/загрузки текущей игры, специфичные режимы игры "Ну, Погоди!", запуск браузера для отображения сайта разработчика или другого интернет-ресурса.    
       
       
       
  [назад] [страница 1] [далее] [к содержанию]    
       
       
       
       
       
  по всем вопросам пишите на megainformatic@mail.ru или оставьте сообщение на форуме    
       
 

 

Обновления и новости о развитии Delphi DirectX проекта
смотри на сайтах:

http://www.megainformaticsite.pochta.ru

http://www.megainformatic.boom.ru

http://www.megainformatic.narod.ru

 

   
       
     
 

Cвои пожелания, вопросы или заметки отправляйте на:

megainformatic@mail.ru или пишите на форуме

 
     
   Обмен ссылками  
     
     
             
 
 
         
(с) МЕГА ИНФОРМАТИК 2006-2009
Hosted by uCoz