Чтение онлайн

ЖАНРЫ

Графика DirectX в Delphi

Краснов Михаил

Шрифт:

type

TCollidelnfo = record

X, Y : Integer; // Вспомогательная запись, координаты столкновения

end;

TSprite = class // Класс спрайта

SpriteWidth : Integer; // Размеры

SpriteHeight : Integer;

FSpriteSurface : IDirectDrawSurfaceT; // Поверхность

PosX, PosY : Integer; // Позиция

Collide : BOOL; // Флаг, связанный со столкновением

function GetP.ect : TRect; // Прямоугольник, ограничивающий спрайт

function GetCenterX : Integer; //

Координаты центра

function GetCenterY : Integer;

// вывод спрайта на экран

function Show (const FDDSBack : IDirectDrawSurface7) : HRESULT;

procedure CalcVector; // Инициализация направления движения

procedure Update; // Вычислить новые координаты

procedure Init (const FDD : IDirectDraw7; const fileName : PChar);

procedure Hit (const S : TSprite); // Столкновение private

Xinc : Integer; // Приращения координат

Yinc : Integer;

Collidelnfo : TCollidelnfo; // Координаты столкновения

end;

В примере используется 8-битный режим, палитра одного из образов устанавливается для первичной поверхности и для всех спрайтов. Для разнообразия и закрепления пройденного не будем пользоваться готовой функцией загрузки образа на поверхность. Поверхность спрайтов создадим самостоятельно.

Обратите внимание, что в таком случае требуется формат пиксела "дочерней" поверхности задавать явно, и должен этот формат совпадать с форматом пиксела первичной поверхности. Иначе вполне может случиться так, что поверхности образов будут создаваться не 8-битными, и палитру на них установить не удастся:

const

ScreenWidth = 640;

ScreenHeight = 480;

ScreenBitDepth = 8;

NumSprites = 10; / Всего спрайтов, один из них - не круг, а фигура

var

frmDD : TfrmDD;

spr : Array [0..NumSprites - 1] of TSprite; // Массив спрайтов

PixelFormat : TDDPixelForraat; // Для согласования форматов пиксела

Значение переменной PixelFormat устанавливается после создания первичной поверхности, до инициализации системы образов:

procedure TfrmDD.FormCreate(Sender: TObject);

var

hRet : HRESULT;

ddsd : TDDSurfaceDesc2;

ddscaps : TDDSCaps2;

i : Integer;

begin

FDDPal := nil;

FDDSBack := nil;

FDDSPrimary := nil;

FDD := nil;

hRet := DirectDrawCreateEx (nil, FDD, IDirectDraw?, nil);

if Failed (hRet) then ErrorOut(hRet, 'DirectDrawCreateEx1);

hRet := FDD.SetCooperativeLevel(Handle, DDSCL_FULLSCREEN or

DDSCL_EXCLUSIVE);

if Failed (hRet) then ErrorOut(hRet, 'SetCooperativeLevel');

hRet := FDD.SetDisplayMode (ScreenWidth, ScreenHeight,

ScreenBitDepth, 0, 0);

if Failed (hRet) then ErrorOut(hRet, 'SetDisplayMode');

ZeroMemory(@ddsd, SizeOf(ddsd));

with ddsd do begin

dwSize := SizeOf(ddsd);

dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;

ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX;

dwBackBufferCount := 1;

end;

hRet := FDD.CreateSurface(ddsd, FDDSPrimary, nil);

if Failed (hRet) then ErrorOut(hRet, 'Create Primary Surface');

ZeroMemory(@ddscaps, SizeOf(ddscaps));

ddscaps.dwCaps := DDSCAPS_BACKBUFFER;

hRet := FDDSPrimary.GetAttachedSurface(ddscaps, FDDSBack);

if Failed (hRet) then ErrorOut(hRet, 'GetAttachedSurface');

FDDSBack._AddRef;

//

Палитра должна быть считана до инициализации спрайтов

FDDPal := DDLoadPalette(FDD, 'l.bmp');

if FDDPal = nil then ErrorOut(DD_FALSE, 'DDLoadPalette');

hRet := FDDSPrimary.SetPalette(FDDPal);

if Failed (hRet) then ErrorOut(hRet, 'SetPalette');

// Определяемся с форматом пиксела первичной поверхности

ZeroMemory(SPixelFormat, SizeOf(PixelFormat));

PixelFormat.dwSize := SizeOf(PixelFormat);

hRet := FDDSPrimary.GetPixelFormat(PixelFormat);

if Failed (hRet) then ErrorOut(hRet, 'GetPixelFormat');

Randomize;

// Первый спрайт - фигура

spr [0] := TSprite.Create; spr [0].Init (FDD, 'l.bmp');

// Остальные спрайты - сферы

for i := 1 to NumSprites --1 do begin

spr [i] := TSprite.Create;

spr (ij.Init (FDD, '2.bmp');

end;

end;

Инициализация спрайта реализована "длинным" кодом:

procedure TSprite.Init (const FDD : IDirectDraw7;

const fileName : PChar);

var

Bitmap : TBitmap;

hRet : HResult;

DC : HOC;

ddsd : TDDSurfaceDesc2;

begin

FSpriteSurface := nil;

Bitmap := TBitmap.Create;

Bitmap.LoadFromFile(fileName);

ZeroMemory(Sddsd, SizeOf(ddsd));

with ddsd do begin

dwSize := SizeOf(ddsd);

dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH or

DDSD_PIXELFORMAT;

ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;

dwHeight := bitmap.Height;

dwWidth := bitmap.width;

ddpfPixelFormat := PixelFormat; // Явно задаем 8-битный формат end;

hRet := FDD.CreateSurface(ddsd, FSpriteSurface, nil);

if Failed(hRet) then frmDD.ErrorOut(hRet, 'CreateSpriteSurface1);

// Воспроизведение картинки на поверхности спрайта

if FSpriteSurface.GetDC(DC) = DD__OK then begin

BitBlt(DC, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle,

0, 0, SRCCOPY);

FSpriteSurface.ReleaseDC(DC);

end;

// Цветовой ключ для всех спрайтов - белый

hRet := DDSetColorKey (FSpriteSurface, RGB(255, 255, 255));

if Failed (hRet) then frmDD.ErrorOut(hRet, 'DDSetColorKey1);

SpriteWidth := Bitmap.Width; // Задаем размеры спрайта

Поделиться с друзьями: