Delphi World - Видео формат для использования в играх. Со звуком формата WAV (скоро будет MP3)
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Видео формат для использования в играх. Со звуком формата WAV (скоро будет MP3)

Оформил: XVeL
Автор: Spose
WEB-сайт: http://daddy.mirgames.ru

Данный видео формат использует компоненты DelphiX, и Jpeg для отрисовки изображения, поэтому процесс отрисовки изображений не очень прогрессивен, и в ближайшее время появится статья, где все это выполняется через WinAPI, более быстрый способ.
Вот типы процедур, которые будут использоваться в статье:
1.StartScene - эта процедура будет выполнятся один раз, и только перед началом Scene, обычно, создает Объекты для Scene и ставит нужные параметры для отрисовки.
2.Scene - эта процедура, выполняемая каждую секунду столько раз сколько у Вас кадров всекунду (FPS) у DxTimer'а, обычно отрисовывает те объекты, которые создавались в StartScene.
3.EndScene - в этой процедуре, обычно, очищают память от тех объектов, которые не будут использованы в других сценах, а использовались только в этой.
Сначала укажем в USES что будем использовать Jpeg, потом после слова TYPE пишем:

TIMHeader = record
   Face:array[1..5] of char; //Это типа мой идентификатор
   fps:byte; //Количество кадров в секунду
   Pictures:integer; //Количество картинок в файле
   width,height:integer; //Ширина и высота картинок
   sound:byte; //Если 1 то звук есть, если 0 то звука нет
   soundsize:int64; //Размер звукового файла
end;
//А в поле VAR пишем:
var
   schet:integer=1; //Количество картинок-schet=кадров осталось до конца
   fs:tfilestream; //Компонент необходимый для чтения файлов
   f:TImHeader; //Собственно заголовок Видео Файла
   center,str:boolean; //1е - елси нужно ровнять по центру, 2е-растянуть
   jpg:TjpegImage;//Картинка Jpeg

Теперь идет процедура типа StartScene:

fs:=tfilestream.Create('Имя файла',fmOpenRead); //Открываем видео файл
fs.Read(f,sizeof(f)); //Читаем заголовок
if f.sound=1 then
begin
   m:=tmemorystream.Create;
   m.CopyFrom(fs,f.soundsize);
   m.Position:=0;
   wl.Items.Find('sound').Wave.LoadFromStream(m);
   wl.Items.Find('sound').Restore;
end;
timer.Interval:=1000 div f.fps; //Устанавливаем скорость отрисовки картинок(кадры в секунду)
dximagelist.items.clear; //Отчищаем Имэйдж Лист от картинок, для освобождения памяти
dximagelist.Items.Add; //Добавляем один Итэм в Имэйдж Лист (в нем будет лежать каждый кадр видеоролика)
if (f.width=640) or (f.height=480) then //Если картинка например 640х240 то рисуем по центру
   center:=true
else
begin
   if (f.width=320) and (f.height=240) then //Если картинка пропорциональна 640х480 то растягиваем
   str:=true;
end;
jpg:=tjpegimage.create;
dxtimer.Enabled:=true; //Начинаем отрисовку
end;
Ну и наконец сама процедура отрисовки, она ставится на dxdtimer.ontimer или попросту к процедурам типа Scene:
var //Объявляем переменные
   size:int64; //Размер изображения в Видео Файле
   memo:tmemorystream; //Временый участок памяти под картинку
begin
   if not ddraw.CanDraw then exit;
   if (schet=1) and (f.sound=1) then //Начинаем с первого кадра играть звук
      if dxsound.Initialized then wl.Items.Find('sound').Play(false);
   if schet<f.Pictures then //Если картинки в Видео Файле закончились
   begin //ТО:
      fs.Free; //Закрываем видео файл
      endscene; //Конец сцены (процедура типа EndScene)
      jpg.free; //Картинку тоже отчищаем
      exit; // Далее не продолжаем
   end else //А если картинки не закончились то:
   inc(schet); //Schet увеличиваем на единицу
   memo:=tmemorystream.Create; //Выделяем участок в памяти
   fs.Read(size,sizeof(size)); //Читаем из Видео Файла размер изображения
   memo.CopyFrom(fs,size); //Загружаем это изображение в память
   memo.Position:=0;
   jpg.LoadFromStream(memo); //Загружаем в нее изображение
   dximagelist.items.Items[0].Picture.Assign(jpg); //Засовываем картинку в Имэйдж Лист
   dximagelist.Items.Items[0].Restore; //принимаем изменения
   ddraw.Surface.Fill(0); //Заливаем фон черным(в случае если видео непрозрачное или на весь экран, можно не писать)
   {Далее 8 строк, проверяем на центрированость и на растяг, потом орисовываем картинку}
   if center then
   begin
      x:=(640-f.width)div 2;
      y:=(480-f.height)div 2;
      il.Items.Items[0].draw(ddraw.Surface,x,y,0);
   end;
   if str then il.Items.Items[0].stretchdraw(ddraw.Surface,bounds(0,0,640,480),0);
   memo.Free; //Отчищаем память от нарисованой картинки
   ddraw.flip; //Переключаем страницу видеопамяти (если эта процедура типа Scene, то можно не писать)



Пример. Перетащите файл file.imp на файл video.exe(Сначала откомпилируйте проект).
Программа создающая видео файлы теперь на русском языке. Описание:
Hеобходимо, чтобы в папке с программой находились картинки (из которых состоит видео фрагмент) в формате BMP. При этом их названия должны быть, не такие:
1
10
11
12
2
3
4
5
6
7
8
9
А такие:
01
02
03
04
05
06
07
08
09
10
11
12
Чтобы сохранить их порядок!

Вот в принципе и всё.
Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования