Михаил Краснов - Графика DirectX в Delphi

Тут можно читать онлайн Михаил Краснов - Графика DirectX в Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Графика DirectX в Delphi
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    3.56/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Михаил Краснов - Графика DirectX в Delphi краткое содержание

Графика DirectX в Delphi - описание и краткое содержание, автор Михаил Краснов, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Графика DirectX в Delphi - читать онлайн бесплатно ознакомительный отрывок

Графика DirectX в Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Михаил Краснов
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

if FSpriteSurface.GetDC(DC) = DD_OK then begin

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

0,0, SRCCOPY);

FSpriteSurface.ReleaseDC(DC) ;

end;

// Оба вида монстров нарисованы на зеленом фоне

DDSetColorKey (FSpriteSurface, RGB(0, 255, 0) ) ;

FSpriteSurface.SetPalette(frmDD.FDDPal);

SpriteHeight := Image.Height;

// Image содержит вcе кадры

SpriteWidth := Image.Width div FrmCount;

Collide := False;

PosX := random (640 - SpriteWidth);

PosY := random (426 - SpriteHeight);

CalcVector;

AnimFrame := random (FrmCount); // Текущий кадр - случайно

// Количество кадров для каждого вида монстров свое

FrameCount := FrmCount;

// Индивидуальная задержка смены кадров, передается случайное число

Delay := SprDelay;

// Прямоугольник кадра, фрагмент из ленты кадров

SetRect (rcRect, AnimFrame * SpriteWidth, 0,

AnimFrame * SpriteWidth + SpriteWidth, SpriteHeight);

Live := True;

LastTickCount := GetTickCount;

end;

Остальные методы классов спрайтов или схожи с предыдущими примерами, или тривиальны. Подробно разбирать их, думаю, не стоит, обращу внимание только на некоторые моменты.

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

В рассматриваемом примере блиттинг спрайтов на задний буфер осуществляется с флагом DDBLTFASTJDONOTWAIT, что редко для примеров этой книги.

Считаем, что задний буфер будет всегда доступным для вывода. При большом количестве отображаемых образов ожидание доступности устройства является слишком большой роскошью.

Каждый спрайт снабжен методом, связанным с восстановлением потерянной поверхности, в котором по высоте спрайта определяем, с какой картинкой ассоциирован конкретный объект:

function TSprite.Restore : HRESULT;

var

DC : HOC;

hRet : HRESULT;

Image : ТImage;

begin

hRet := FSpriteSurface .__Restore;

if Failed (hRet) then begin

Result := hRet;

Exit;

end;

// Пользуемся тем, что высота трех образов различна

if SpriteHeight = 15 then Image := frmDD.ImgMoster2 else

if SpriteHeight = 22 then Image := frmDD.ImgMosterl

else Image := frmDD.ImgDead;

// Копируем нужный образ на восстанавливаемую поверхность

if FSpriteSurface.GetDC(DC) = DD__OK then begin

BitBltfDC, 0, 0, Image.Width, Image.Height, Image.Canvas.Handle,

0, 0, SRCCOPY);

FSpriteSurface.ReleaseDC(DC);

end;

Result := FSpriteSurface.SetPalette(frmDD.FDDPal);

end;

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

procedure UpdateBul;

var

wrkl, wrkJ : Integer;

begin

for wrkl := 0 to NumBullets - 2 do

if (Bullets [wrkI].PosX >= 632) or (Bullets [wrkI].PosX <= 0) or

(Bullets [wrklJ.PosY <= 0) then begin

for wrkJ := wrkl to NumBullets - 1 do // Сдвигаем содержимое массива

with Bullets [wrkJ] do begin

PosX := Bullets [wrkJ + I].PosX;

PosY := Bullets [wrkJ + l].PosY;

Xinc := Bullets [wrkJ + 1].Xinc;

Yinc := Bullets [wrkJ + l].Yinc;

end;

NumBullets := NumBullets - 1;

end;

end;

Положение пули, попавшей в монстра, устанавливается за пределами экрана, чтобы она не летела дальше, поражая других чудовиш.

Для погибшего монстра необходимо заменить размеры спрайта и ленту кадров. Все эти действия следует производить максимально быстро. По возможности будем опираться на конкретные числа; проверки успешности, равно как и академическое пересоздание поверхности, опускаем:

procedure TfrmDD.DeadMonster (const Number : Integer);

var

DC : HDC;

ddsd : TDDSurfaceDesc2;

begin

ZeroMemory (@ddsd, SizeOf(ddsd));

with ddsd do begin

dwSize := SizeOf(ddsd);

dwFlags := DDSD__CAPS or DDSD_HEIGHT or DDSD_WIDTH;

dwHeight := ImgDead.Height;

dwWidth := ImgDead.Width;

ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;

end;

with Monsters[Number] do begin

// Пересоздаем поверхность (без := nil)

FDD.CreateSurface(ddsd, FSpriteSurface, nil);

// Считаем, что ошибок не будет

FSpriteSurface.GetDC(DC);

// Конкретные числа размеров копируемого образа

BitBlt(DC, 0, 0, 100, 25, ImgDead.Canvas.Handle, О, О, SRCCOPY);

FSpriteSurface.ReleaseDC(DC);

// Ключ необходимо переустановить

DDSetColorKey (FSpriteSurface, RGB(0, 255, 0));

// Опять опираемся на конкретные числа

SpriteHeight := 25;

SpriteWidth := 25;

AnimFrame := 0;

FrameCount := 4;

Xinc := 0; // Погибший спрайт остается неподвижный

Yinc := 0;

Live := False;

end;

end;

Кадр перерисовывается непрерывно, но изменения в нем вносятся в соответствии с принятыми задержками:

function TfrmDD.UpdateFrame : HRESULT;

var

wrkl, si, s2 : Integer;

begin

GlobalThisTickCount := GetTickCount;

// Подошло время выпустить нового монстра

FDDSBack.BltFastfO, 0, FDDSBackGround, @bkRect, DDBLTFAST_WAIT);

if (GlobalThisTickCount - GlobalLastTickCount > DelayMonsters)

and (NumMonsters < High (Monsters) - 1) then begin Inc (NumMonsters);

GlobalLastTickCount := GlobalThisTickCount;

end;

// Обновить положения и воспроизвести монстров

for wrkl := 0 to NumMonsters - 1 do Monsters [wrkl].Show;

Warrior.Show; // Вывод воина поверх пролетающих, монстров

UpdateBul; // Удалить пули, вылетевшие за пределы экрана

// Обновить положения и отобразить пули

for wrkl := 0 to NumBullets - I do Bullets [wrkl].Show;

// Определить столкновение монстров и пуль

for s1 := 0 to NumMonsters - 1 do

for s2 := 0 to NumBullets - 1 do

if Monsters [s1].Live and SpritesCollidePixel (Monsters [s1],

Bullets [s2]) then begin

// Попавшая пуля перемещается за границы экрана

Bullets [s2].PosY := -10;

DeadMonster (s1); // Заменить образ монстра

end;

// Столкновения монстров, берутся в расчет только живые чудовища

for s1 := 0 to NumMonsters - 2 do

for s2 := si + 1 to NumMonsters - 1 do

if Monsters [s1].Live and Monsters [s2].Live and

SpritesCollidePixel (Monsters [si], Monsters[s2]) then begin

Monsters [si].Hit(Monsters [s2]);

Monsters [s2].Hit(Monsters [si]);

end;

Result := DDJDK;

end;

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

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

Очередной пример является развитием предыдущего - это игра аналогичного жанра, поменялись только фон и вид нашего бойца (рис. 5.4).

Скорость работы игры повысилась существенно, инициализация и восстановление происходят мгновенно, и нет ощутимой паузы в моментах замены картинки спрайтов.

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

Образы спрайтов хранятся в единственном компоненте класса Timage (рис. 5.5).

В принципе это и не обязательно Главное повторюсь то что используется одна - фото 31

В принципе, это и не обязательно. Главное, повторюсь, то, что используется одна поверхность. Она может заполняться отдельными образами или единым, как в нашем примере, но при выводе спрайтов применяется не индивидуальная поверхность спрайта, а поверхность Foosimages, обслуживающая все спрайты. Вот как выглядит теперь код воспроизведения воина:

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Михаил Краснов читать все книги автора по порядку

Михаил Краснов - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Графика DirectX в Delphi отзывы


Отзывы читателей о книге Графика DirectX в Delphi, автор: Михаил Краснов. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x