Читаем Графика DirectX в Delphi полностью

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

const

DelayMonsters = 1000;// Через сколько миллисекунд появится новый монстр

MaxSprites = 100; // Ограничение количества спрайтов

var

Monsters : Array [0..MaxSprites - 1] of TSprite; // Массив чудовищ

Bullets : Array [0..MaxSprites - 1] of TBullet; // Массив пуль

Warrior : TWarrior; // Объект бойца

GlobalThisTickCount : DWORD; // Глобальный таймер

GlobalLastTickCount : DWORD;

NumMonsters : Integer =0; // Текущее количество монстров

NumBullets : Integer =0; // Текущее количество пуль

Создание отдельного спрайта (имеющего собственную поверхность) происходит очень долго, поэтому массивы спрайтов заполняются в начале работы приложения. Если же поступать так, как подсказывает логика, и создавать объекты только непосредственно перед их появлением на экране, картинка в такие моменты будет замирать на долю секунды. Создание двух сотен объектов будет долгим. Чтобы скрасить время ожидания, перед началом этого процесса я вывожу на первичную поверхность картинку фона, но можно было бы использовать и специальную заставку:

FDDSBackGround := DDLoadBitmap(FDD, bkBitmap, 0, 0); // Загружаем фон

if FDDSBackGround = nil then ErrorOut(hRet, 'DDLoadBitmap');

// Палитра предварительно загружена,

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

hRet := FDDSBackGround.SetPalette(FDDPal);

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

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

SetRect(bkRect, 0, 0, ScreenWidth, ScreenHeight);

// Сразу же после загрузки на экран выводится фон

FDDSPrimary.BltFast(0, 0, FDDSBackGround, ObkRect, DDBLTFAST_WAIT;

Randomize;

// Создание объекта воина

Warrior := TWarrior.Create (ImgWarrior);

// Заполняем массив монстров

for wrkl := Low (Monsters) to High (Monsters) do

if random > 0.5

then Monsters [wrkl] := TSprite.Create (ImgMosterl,

40+ random (40), 4)

else Monsters [wrkl] := TSprite.Create (ImgMoster2, 40 + random (20), 6);

// Заполняем массив пуль

for wrkl := Low (Bullets) to High (Bullets) do

Bullets [wrkl] := TBullet.Create (ImgBullet);

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

Constructor TSprite.Create (const Image : TImage; const SprDelay : DWORD;

const FrmCount : Integer);

var

DC : HOC;

ddsd : TDDSurfaceDesc2;

hRet : HResult;

begin

ZeroMemory (@ddsd, SizeOf (ddsd) ) ;

with ddsd do begin

dwSize := SizeOf (ddsd) ;

dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH;

dwHeight := Image.Height;

dwWidth := Image.Width;

ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;

end;

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

if Failed (hRet) then frrr.DD. ErrorOut (hRet, ' CreateSpriteSurface ' ) ;

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;

Перейти на страницу:

Похожие книги

C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных
Adobe InDesign CS3
Adobe InDesign CS3

Книга посвящена верстке и макетированию в программе Adobe InDesign CS3. Помимо того что в ней описываются возможности программы, рассматриваются также принципы и традиции верстки, приводятся примеры решения типичных задач. Все это позволит читателю не только овладеть богатым инструментарием программы, но и грамотно применять его.Материал книги разделен на логические части: теоретические сведения, инструментарий программы, решение задач, – а также рассчитан на два уровня подготовки читателей – начинающих и опытных пользователей, что выгодно отличает книгу от других изданий. Это позволит применять ее как новичкам для знакомства с программой, так и пользователям со стажем для пополнения своих знаний.

Владимир Гавриилович Завгородний , Владимир Завгородний

Программирование, программы, базы данных / Программное обеспечение / Книги по IT
Разработка приложений в среде Linux. Второе издание
Разработка приложений в среде Linux. Второе издание

Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет СЃРѕР±РѕР№ отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из РґСЂСѓРіРёС… операционных систем. РџРѕРґСЂРѕР±но рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование СЃРІРѕР±одно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Р

Майкл К. Джонсон , Эрик В. Троан

Программирование, программы, базы данных