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):
- Tvorba her v DirectX v Delphi - 1. díl
- Tvorba her v DelphiX - 2. díl
- Tvorba her v DelphiX - 3. díl
- Tvorba her v DelphiX - 4. díl
- Tvorba her v DelphiX - 5.díl
- Bludiště v DelphiX
- Kolize ve hrách v DelphiX
- Posuvný text v DelphiX bez komponenty
- Posuvný text v DelphiX podruhé
- Speciální grafické efekty v DelphiX
- TurboPixels aneb rychlé pixely v DelphiX
- Let s vrtulníkem v DelphiX
- Stíny a světla trochu jinak
Diskuse k článku
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007