Вход/Регистрация
Графика DirectX в Delphi
вернуться

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

Шрифт:

if FDDPal <> nil then begin

if Failed (FDDSPrimary.SetPalette(FDDPal))

then ErrorOut(DDERR_PALETTEBUSY, 'SetPalette1);

end

else ErrorOut(DDERR_PALETTEBUSY, 'DDLoadPalette') ;

for i := 0 to NumSprites - 1 do begin

// Восстанавливаем поверхность спрайтов

hRet := spr [i].FSpriteSurface._Restore;

if Failed(hRet) then begin Result := hRet;

Exit;

end;

// Переустанавливаем поверхность спрайта

if Failed (spr [i].FSpriteSurface.SetPalette(FDDPal))

then ErrorOut(DDERR_PALETTEBUSY, 'SetPalette');

// Восстанавливаем изображение

if i = 0 then spr [ij.lnit (FDD, 'l.bmp')

else spr [i].Init (FDD, '2.bmp');

end;

Result := DD_OK end else

Result := hRet;

end;

По завершении работы также нельзя забывать о поверхностях спрайтов:

procedure TfrmDD.FormDestroy(Sender: TObject);

var

i : Integer;

begin

if Assigned(FDD) then begin

if Assigned(FDDPal) then FDDPal := nil;

for i := 0 to NumSprites - 1 do begin

if Assignedfspr [i].FSpriteSurface) then begin spr [i].FSpriteSurface._Release;

spr [i].FSpriteSurface := nil;

end;

spr [i].Free;

end;

if Assigned(FDDSPrimary) then begin FDDSPrimary. Release;

FDDSPrimary := nil;

end;

FDD._Release; FDD := nil;

end;

end;

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

Опытным путем я определил, что пикселы фона для установленной палитры имеют значение 191, поэтому такие пикселы пропускаем. Как только встречается пиксел, по адресу которого в обеих поверхностях записывается значение, отличное от 191, перебор прекращается:

function TfrmDD.SpritesCollidePixel(Spritel, Sprite2 : TSprite) : BOOL;

var

Rectl : TRect;

Rect2 : TRect;

IRect : TRect;

rltarget : TRect;

r2target : TRect;

locWidth : Integer;

locHeight : Integer;

Descl, Desc2 : TDDSURFACEDESC2;

Ret : BOOL;

Surfptrl : POINTER; // Указатели на начало области памяти поверхности

Surfptr2 : POINTER;

Pixel1 : PBYTE; // Пикселы поверхностей

Pixel2 : PBYTE;

XX, YY : Integer;

label

Done ;

begin

// Прямоугольники, ограничивающие спрайты

Rectl := Spritel.GetRect;

Rect2 := Sprite2.GetRect;

// Вычисляем точку пересечения прямоугольников

IntersectRect (IRect, Rectl, Rect2);

// Если нет пересечения прямоугольников, спрайты сталкиваться не могут

if (IRect.Left = 0) and (IRect.Top = 0) and

(IRect.Right = 0) and (IRect.Bottom = 0) then begin

Result := FALSE;

Exit;

end;

// Находим положение области пересечения для каждого спрайта

IntersectRect (rltarget, Rectl, IRect);

OffsetRect(rltarget, -Rectl.Left, -Rectl.Top);

IntersectRect (r2target, Rect2, IRect);

OffsetRect(r2target, -Rect2.Left, -Rect2.Top);

r2target.Right := r2target.Right - 1;

r2target.Bottom := r2target.Bottom - 1;

// Предыдущие две строки обеспечивают корректное нахождение

// размеров области пересечения

locWidth := IRect.Right - IRect.Left;

locHeight := IRect.Bottom - IRect.Top;

// Подготавливаем структуры для работы с памятью поверхностей

ZeroMemory (gdescl, SizeOf(descl));

descl.dwSize := SizeOf(descl);

ZeroMemory (@desc2, SizeOf(desc2));

desc2.dwSize := SizeOf(desc2);

Ret := False;

// Запираем поверхности спрайтов

Spritel.FSpriteSurface.Lock(nil, descl, DDLOCK_WAIT, 0) ;

Surfptrl := descl.IpSurface;

Sprite2.FSpriteSurface.Lock(nil, desc2, DDLOCK_WAIT, 0) ;

Surfptr2 := desc2.IpSurface;

// Просмотр содержимого пикселов для каждого спрайта

//в пределах области пересечения

for YY := 0 to locHeight - 1 do

for XX := 0 to locWidth - 1 do begin

// Для оптимизации эти действия можно свернуть в одну строку

  • Читать дальше
  • 1
  • ...
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: