скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Видео формат для использования в играх. Со звуком формата WAV (скоро будет MP3)



Оформил: XVeL
Автор: Spose

Данный видео формат использует компоненты 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
Чтобы сохранить их порядок!

Вот в принципе и всё.





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook