Tvorba her v DirectX v Delphi - 1. díl - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Tvorba her v DirectX v Delphi - 1. díl

25. září 2000, 00.00 | Chcete tvořit hry a nevíte jak na to? Že neovládáte ten správný jazyk? My vám ukážeme že pěknou hru lze vytvořit i v Delphi. Čtěte první díl našeho seriálu.

Ano. I když se to někomu může zdát hodně divné, právě čtete článek o tvorbě her v DELPHI. Ano, i v Delphi jdou programovat hry. Jestli lepší, či horší než v ostatních jazycích nevim, ale rozhodně to není zas až tak složité.
Co k tomu tedy potřebujete ? Jak jistě každý asi uhodne, tak Delphi a ještě navíc komponenty DelphiX, pomocí kterých můžete programovat v DirectX (a samozřejmě musíte mít nainstalované DirectX). Kromě toho ještě kupu fantazie, trochu grafiky a hlavně hodně trpělivosti. Připraveni ? Tak začneme:

Ti, kteří si mysleli, že naprogramují Quake 5 nebo něco podobného musím hned na začátku zklamat. Pokud si ale přečtete a pochopíte všechny články o tvorbě her, měli byste být schopni sami naprogramovat hru podobnou hře ufo ( ufo.zip 0.5 Mb).
Na začátek bych napsal jednu radu, která se právě při tvorbě her hodí nejvíc - pokud děláte hru, a uděláte v ní výraznou změnu, hned ji uložte do nového adresáře ( např. hra v. 1.5 ). V případě, že ve hře poté uděláte chybu, na kterou nebudete moci příjít, máte možnost se vrátit k verzi předchozí.

První program v DelphiX...

Nechme už ale povídání, a pusťme se do tvorby. Náš první projekt nebude umět nic jiného, než zobrazit na pozici obrázek. To ještě samozřejmě není hra, ale musíme začít něčím jednoduchým. 

Nejprve tedy spusťte Delphi a  vytvořte nový projekt. Z palety komponent DelphiX vložte na formulář komponenty DXDraw (), DXTimer () a DXImageList (). Princip programu bude jednoduchý - DXTimer se bude starat o to, aby se na DXDraw vykresloval obrázek z DXImageList. U komponenty DXImageList nastavíme vlastnost DXDraw na DXDraw1 a klinutím na Items vlastnost se nám otevře seznam nahraných obrázků. Zatím je prázdný, a proto tlačítkem Add New přidáme novou položku. Klineme na ni a vlastnost Name nastavime např. na obrazek. Nyní klikneme na vlastnost Picture a nahrajeme již samotný obrázek (tlačítkem Load), např. obrázek ufa.
Pokud chceme, aby byl obrázek průhledný, nastavíme vlastnost Transparent na true, vlastnost TransparentColor pak určuje průhlednou barvu. Položky DXimageListu nyní zavřeme, jelikož vše potřebné již máme hotové, a přesuneme se ke komponentě DXTimer. Ta, obdobně jako standartní komponenta Timer provádí proceduru OnTimer každých x milisekund, které určuje vlastnost Interval. Pokud v komponentě DXTimer nastavíme Interval na 0, bude se komponenta snažit provádět proceduru OnTimer co nejvíckrát to půjde. Počet snímků za sekundu, nebo-li FPS (frames per second) je ve vlastnosti DXTimer.FrameRate. Komponenta DXTimer má navíc ještě vlastnost ActiveOnly typu boolean, která určuje, má-li být timer neaktivní, i když je okno neaktivní. K tomu náleží i dvě procedury OnActive a OnDeactive. Těmi se ale teď nebudeme zabývat, a přistoupíme k proceduře třetí, a to OnTimer. Poklepáme myší na prázdné políčko a můžeme již psát kód. Zde je na čase popsat proceduru, pomocí které budeme vykreslovat obrázek na povrch DXDraw:

procedura DXImageList1.Items[x].Draw(Dest, x, y, patternIndex)

Tato procedura prostě nakreslí obrázek x komponenty DXImageList1 na povrch Dest (v našem případě DXDraw1.surface) na pozici x, a y. PatternIndex určuje vzorek, ten zatím necháme na nule. A to je vše. Jak prosté. Zde je výpis celé procedury:

procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
// pokud z jakéhokoliv důvodu nemůžeme na
// povrch DXDraw kreslit, rovnou z procedury vyskočíme

if not DXDraw1.CanDraw then exit;

// povrch DXDraw1 vyplníme černou barvou
// == vymažeme předchozí kresby

DXDraw1.Surface.Fill(0);

// na pozici 0,0 nakreslíme obrázek
// 0 z DXImageListu

DXImageList1.items[0].Draw(DXDraw1.surface,0,0,0);

// nakonec procedura flip,
// abychom to také viděli

DXDraw1.Flip;
end;

Jak vidíte, v proceduře se nám vyskytly ještě další procedury, které jsou popsány dále. Začněme tedy prvním řádkem. Vlastnost DXDraw1.CanDraw určuje, zda můžeme na povrch kreslit. Pokud tomu tak není, první řádek se postará o to, aby nedošlo k chybě a rovnou z procedury vyskočí. Procedurou Fill vyplníme povrch DXDraw danou barvou (0 = černá), čímž všechny předchozí kresby z obrázku vymažeme. Pomocí proc. Draw nakreslíme obrázek na pozici 0,0 a nakonec skrytý povrch zobrazíme proc. Flip. Nyní můžeme projekt přeložit a spustit klávesou F9, a pokud se Vám opravdu zobrazuje obrázek v levém horním rohu, udělali jste program správně a můžete všem říkat, že jste udělali program v DirectX :) Tím to ale samozřejmě nekončí, to je teprve začátek...

Program druhý - trocha pohybu neuškodí...

 Tedy myslím pohybu obrázku, jelikož dívat se, jak se obrázek zobrazuje pořád na stejné pozici je po chvíli...nudné. Jako základ nám může posloužit program předchozí, do kterého pouze doplníme trochu kódu. Ten se postará o to, aby se obrázek při každém volání proc. OnTimer zobrazil na jiném místě (pozn. - pokud jste měli vlastnost DXTimer.Interval nastavenou na 0, nebo jiné malé číslo, je dobré jej trochu zvětšit, aby se Vám potom nedělali mžitky před očima). pro tvorbu náhodného čísla použijeme procedury Random(x), která vytvoří náhodné celé číslo od 0 do X. V sekci public tedy definujeme dvě proměnné x a y typu integer a mezi procedury Fill a Draw tedy vložíme následující kód:

// nastavení náhodné pozice obrázku
x:=Random(DXDraw1.SurfaceWidth-DXImageList1.Items[0].Width);
y:=Random(DXDraw1.SurfaceHeight-DXImageList1.Items[0].Height);

a proceduru Draw změníme na: 

// na pozici x a y nakreslíme obrázek
// 0 z DXImageListu

DXImageList1.items[0].Draw(DXDraw1.surface,x,y,0);

Jak sami vidíte, x a y obrázku bude nanejvýš takové, aby se zobrazil těsně u kraje okna a tedy abychom ho vždy viděli. Program můžeme zase přeložit a spustit klávesou F9 a pokud je vše v pořádku, bude se objevovat obrázek na náhodných místech. Obrázek se již hýbe, ale jak udělat, aby létal po obrazovce a odrážel se od stěn ?

Program třetí - létání a odrážení od stěn...

A konečně program třetí, a pro dnešek již poslední. V tomto programu si ukážeme, jak naprogramovat, aby sprite létal sem a tam a odrážel se od krajů okna. Pro pohyb budeme používat trochu jiné techniky, než ve článku o animaci spritu v Delphi a která nám dovolí, aby sprite nelétal pouze pod úhly 45°. Princip je ale stejně jednoduchý - kromě prom. x a y si defunujeme ještě IncX a IncY a při každém volání proc. OnTimer k x přičteme IncX a k Y přičteme IncY. Teď si ale řeknete - to je sice hezké, ale v tom případě poletí sprite pouze dolů a doprava. Tak to ale není. Pokud se sprite dostane ke kraji okna, změní se IncX nebo IncY (podle toho, ke kterému kraji okna) na záporné číslo. A jelikož + a - je mínus, bude se sprite pohybovat na druhou stranu ! A pokud se dostane ke kraji doleva nebo nahoru, je to přesně naopak. Navíc k IncX a IncY přiřazujeme náhodně číslo (samozřejmě kladné, nebo záporné) o kolik se má sprite pohnout, a proto letí pod různými úhly. Vyzkoušet si to můžete ostatně sami.Do sekce public přidejte proměnné IncX a IncY typu integer. Zde je kód procedury OnTimer:

procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
// pokud z jakéhokoliv důvodu nemůžeme na
// povrch DXDraw kreslit, rovnou z procedury vyskočíme
if not DXDraw1.CanDraw then exit;

// povrch DXDraw1 vyplníme černou barvou
// == vymažeme předchozí kresby
DXDraw1.Surface.Fill(0);

// vypočítáme novou pozici obrázku
x:=x+IncX;
y:=y+IncY;
if x >= DXDraw1.Surfacewidth-DXimageList1.Items[0].Width
then IncX:=-(Random(5)+1);
if x <= 0 then IncX:=Random(5)+1;
if y >= DXDraw1.Surfaceheight-DXImageList1.Items[0].height
then IncY:=-(Random(5)+1);
if y <= 0 then Incy:=(Random(5)+1);

// na pozici x,y nakreslíme obrázek
// 0 z DXImageListu
DXImageList1.items[0].Draw(DXDraw1.surface,x,y,0);

// nakonec procedura flip,
// abychom to také viděli
DXDraw1.Flip;
end;

Nakonec ještě přidejte proceduru Form1.OnCreate do které přidejte následující:

x:=Random(DXDraw1.SurfaceWidth-DXImageList1.Items[0].Width);
y:=Random(DXDraw1.SurfaceHeight-DXImageList1.Items[0].Height);
IncX:=Random(5)+1;
IncY:=Random(5)+1;

To zajistí, aby se při startu programu sprite objevil na náhodném místě a pohybovat se náhodou rychlostí náhodným směrem.

Download:
Hra UFO (0.5 Mb)

Screenshot:


Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: