DirectX Графика в проектах Delphi


Хранитель экрана - часть 3


Класс TFish инкапсулирует свойства и методы наших рыбок:

TFish = class
XFish, YFish :Integer; // Позиция на экране
Direction :0..1; // Направление движения
WidthFish :Integer; // Ширина
HeightFish :Integer; // Высота
FDDSFish :IDirectDrawSurface7; // Поверхность с образом
SpeedFish :Integer; // Скорость движения
procedure Init; // Инициализация
procedure Render; // Воспроизведение
end;

При инициализации очередной рыбки ее размеры задаются случайно, чтобы создать иллюзию пространства, как будто некоторые рыбки удалены дальше от глаза наблюдателя. Но при указании размеров я соблюдаю пропорции первоначальной картинки. Чтобы рыбка могла плавать и слева направо, и справа налево, можно заготовить два образа на каждую рыбку. Но в этом случае размер файла хранителя экрана резко увеличится. Я выбрал другой путь: имеется одна картинка каждого вида рыбок, плывущих слева направо, а при необходимости содержимое поверхности зеркально переворачивается.
Размер исполнимого файла при таком подходе не увеличивается, но мы, конечно, при каждой инициализации рыбки теряем немного во времени:

procedure TFish.Init;
procedure Rotate; // Зеркальный поворот поверхности рыбки
var
desc : TDDSURFACEDESC2; i, j : Integer; wrkW : Word;
begin
ZeroMemory (@desc, SizeOf(desc));
desc.dwSize := SizeOf(desc);
if Failed (FDDSFish.Lock (nil, desc, DDLOCK_WAIT, 0)) then Exit;
for i := 0 to (WidthFish - 1) div 2 do // Цикл по столбцам растра
for j := 0 to HeightFish - 1 do begin // Цикл по строкам растра
wrkW := PWord (Integer (desc.IpSurface) + j * desc.lPitch +
i * 2)^; // Переставляем пикселы растра
PWord (Integer (desc.IpSurface) + j * desc.lPitch + i * 2) ^ :=
PWord (Integer (desc.IpSurface) + j * desc.lPitch +
(WidthFish - I - i) * 2)л; PWord (Integer (desc.IpSurface) + j * desc.lPitch +
(WidthFish - I - i) * 2)л := wrkW;
end;
FDDSFish.Unlock (nil);
end;
begin
case random (4) of // Случайный выбор одного из четырех видов рыбок
0 : begin
WidthFish := random (141) + 24;
HeightFish := WidthFish * 129 div 164; // Сохранение пропорций
if Failed (frmDD.CreateFromlmage (FDDSFish, frmDD.imgFishl,
WidthFish, HeightFish))
then frmDD.ErrorOut(DDJTALSE, 'CreateFish');
end;
1 : begin
WidthFish := random (161) + 22; HeightFish := WidthFish * 115 div 182;
if Failed (frmDD.CreateFromlmage (FDDSFish, frmDD.imgFish2,
WidthFish, HeightFish))
then frmDD.ErrorOut(DD_FALSE, 'CreateFish');
end;
2 : begin
WidthFish := random (161) +22;
HeightFish := WidthFish * 122 div 182;
if Failed (frmDD.CreateFromlmage (FDDSFish, frmDD.imgFish3,
WidthFish, HeightFish))
then f rmDD. ErrorOut (DD__FALSE, 'CreateFish');
end;
3 : begin
WidthFish := random (175) +22; HeightFish := WidthFish * 142 div 182;
if Failed (frmDD.CreateFromlmage (FDDSFish, frmDD.imgFish4,
WidthFish, HeightFish))
then frmDD.ErrorOut(DD_FALSE, 'CreateFish');
end;
end;
Direction := random (2); // Направление движения случайно
SpeedFish := random (6) +1; // Следим, чтобы скорость была ненулевой
if Direction =0 // Плывет слева направо, значит,
// должна появиться слева экрана
then XFish := -WidthFish
else begin
XFish := ScreenWidth; // Должна появиться справа экрана
Rotate;
// Требуется зеркальный поворот картинки
end;
YFish := random (360) +5; // Глубина, на которой поплывет рыбка
end;




- Начало -  - Назад -  - Вперед -



Книжный магазин