V předchozích lekcích jsme si již něco ukázali, i když toho máme ještě spoustu před sebou. Ukážeme si, co bychom již měli být schopni vytvořit. Vytvoříme spolu takovou jednoduchou hru, na které si zopakujeme naše znalosti a samozřejmě si je i rozšíříme.
Výsledek programu který spolu vytvoříme bude vypadat asi takto:
Půjde o to, že hráč bude pomocí kláves W, A, S, D ovládat tlačítko, na kterém je na obrázku <. Odteď tomuto tlačítku budu říkat žrout. Žroutem musíte vysbírat všechny bílé puntíky, ale aby to nebylo tak jednoduché, tak Vás honí tlačítko s nápisem ×. Nejlepší asi bude, když si to vyzkoušíte na vlastní "kůži": zracka.exe.
Formulář
Začneme tím, že umístíme všechny potřebné komponenty na formulář. Je úplně jedno, jak je umístíte. Použijte vlastní fantazii. Takže někam, nejlépe k sobě, dejte čtyři tlačítka pro pohyb (WASD). Poté další dvě, o kterých jsem už psal. Caption jim můžete nastavit tak, jak vidíte na obrázku. Ale o tom si ještě něco povíme. Ty bílé tečky nejsou nic jiného než RadioButtony = přepínací tlačítka. Najdete je pod záložkou Standart a takovouto ikonou:. Nasázejte jich tam kolik chcete ale zase to moc nepřežeňte. Teď to vypadá že je to všechno vše ale není tomu tak. Pak jsou na formuláři ještě dva Timery (časovače). To jsou komponenty, které nejsou vidět (jsou nevizuální). Povíme si o nich už za chvíli. Najdete je pod záložkou System a pod touto ikonkou: . To by už mělo být vše.
Pohyb
Snad to nejjednodušší na našem programu je pohyb žrouta. Bude ovládán, jak už jsem zmínil, pomocí tlačítek WASD. Kód tlačítka v události OnClick bude vypadat následovně:
procedure TForm1.horClick(Sender: TObject);
begin
zrout.Top := zrout.Top - 5;
end;
Jak vidíte, je to velmi jednoduché. Vlastnost žrouta Top se zmenší o 5. Top udává polohu komponenty od horního okraje formuláře v pixelech. To znamená, že po kliknutí na tlačítko W se žrout posune o pět pixelů nahoru. Nemusí to být zrovna pět. Nastavte
si to, jak Vám vyhovuje. Mě přišlo pět ideálních, protože pohyb poté není příliš
pomalý ani trhaný. Tady pro úplnost uvádím ještě kód ostatních
tlačítek, i když si myslím, že je to zbytečné:
procedure TForm1.dolClick(Sender: TObject); procedure TForm1.levClick(Sender: TObject);
begin procedure TForm1.pravClick(Sender: TObject);
begin
zrout.Top := zrout.Top + 5;
end;
zrout.Left := zrout.Left - 5;
end;
begin
zrout.Left := zrout.Left + 5;
end;
Asi jste si všimli, že popisek tlačítek na obrázku je podtržený. To je proto, aby se dala označit klávesami. Je to vcelku uspokojující způsob ovládání žrouta klávesnicí. Uděláte to jednoduše
tak, že ve vlastnosti Caption před písmenem které má být podtrženo
napíšete &.
.
Co jsouVlastnosti, to předpokládám, že každý chápe. Jsou to prostě vlastnosti komponenty např.: velikost, popisek, zda-li je vidět, poloha atd. Uvedu zde seznam takových nejzákladnějších vlastností u komponenty button:
Caption - Text na tlačítku (doporučuji tuhle vlastnost vyzkoušet i u jiných komponent jak se chovají).
Cursor - Jaký kurzor má myš po najetí na tlačítko.
Enabled - Pokud nastavíte na False, tak tlačítko zašedne a nejde s ním nic dělat (radši si to vyzkoušejte :).
Font - Úprava textu na tlačítku (Caption). Na normálním tlačítku nejde měnit barva to lze pouze u tlačítka s bitmapou.
Height - Výška komponenty v pixelech.
Hint - Popisek tlačítka, který se zobrazí pokud na něm déle necháte kurzor (funguje pouze pokud je vlastnost ShowHint nastavena na True).
Left - Vzdálenost v pixelech od levého okraje formuláře.
Name - Název komponenty.
Top - Vzdálenost v pixelech od horního okraje formuláře.
Visible - Pokud je tato vlastnost na False, komponenta zmizí.
Width - Šířka komponenty opět pixelech.
U Událostí to ale už může být o něco složitější. Události jsou různé podněty, které jsou posílány všelijakým komponentám a ty je potom zpracovávají. Např. kliknutí myší atp. Událostí může být i změna rozlišení. Váš počítač neustále zpracovává tisíce událostí. Proto využívá multitasking, jinak by každá událost zabrala v podstatě 100% využití procesoru. Zde jsou opět uvedeny takové základní události:
OnClick - Kliknutí myši.
OnMouseDown - Zmáčknutí tlačítka myši.
OnMouseUp - Uvolnění tlačítka myši.
OnMouseMove - Pokud kurzorem přejedete nad komponentou.
OnKeyDown - Zmáčknutí tlačítka. U tlačítka je to zmáčknutí mezerníku pokud je tlačítko označené.
OnKeyUp - Uvolnění tlačítka (mezerníku).
OnKeyPress - Potvrzení komponenty tlačítkem (mezera).
Timer
Na žroutovi jste si všimli (pokud máte stažený výše uvedený prográmek), že se text na něm mění. Mělo by to připomínat klapaní tlamou či tak něco. Doufám, že to alespoň z části splňuje účel. Toho jsem docílil pomocí komponenty Timer. Je to v celku jednoduchá komponenta a dosti užitečná. Má jen pár vlastností a jedinou událost:
Enable - Určuje jestli je Timer aktivní.
Interval - Interval v milisekundách, v kterém se má provádět událost OnTimer.
OnTimer - Událost, která se provede každých (Interval).
Pokud tedy chceme udělat jednoduché klapání, tak prvnímu časovači nastavíme interval přibližně na 100, Enabled necháme na True a do události OnTimer napíšeme nasledující kód:
if zrout.Caption = '-' then
zrout.Caption := '<'
else
zrout.Caption :='-';
Doufám, že je na tom vše jasné. Pokud je na žroutovi napsáno "-" tak se na něj vypíše "<" a pokud ne, tak se na něj vypíše "-".
Pojídání
Nyní si ukážeme, jak udělat, aby žrout pojídal bílé puntíky. Jde o to, že jakmile se zjistí kolize daného RadioButtonu se žroutem, tak se vlastnost Visible toho daného RadioButtonu nastaví na False. Ten nejtěžší problém bude asi, jak zjistit tu kolizi. Na to ale naštěstí Windows pamatují a znají několik užitečných funkcí. Pokusím se Vám to co nejlépe vysvětlit. Tlačítko, v našem případě žrout, má jednu takovou vlastnost, která se nám teď bude hodit. Je to vlastnost BoundsRect. Tu ovšem v inspektoru objektů nenajdete. Je typu TRect. To je typ, který udává nějaký čtverec. Obsahuje šest proměnných a to:
Left(Integer) - Vzdálenost v pixelech od levého okraje formuláře k levé straně čtverce.
Top(Integer) - Vzdálenost v pixelech od horního okraje formuláře k horní straně čtverce.
Bottom(Integer) - Vzdálenost v pixelech od horního okraje formuláře k dolní straně čtverce.
Right(Integer) - Vzdálenost v pixelech od levého okraje formuláře k pravé straně čtverce.
TopLeft(TPoint) - Označuje levý horní roh čtverce.
BottomRight(TPoint) - Pravý dolní roh.
TPoint, jak už z názvu vyplývá, se používá pro označení nějakého bodu. Obsahuje další dvě proměnné, a to X a Y. Ty udávají souřadnice bodu. X je vzdálenost v pixelech od levého okraje formuláře a Y od horního okraje. Z toho vyplývá že:
Button.BoundsRect.Right = Button.Left
+ Button.Width
Button.BoundsRect.Bottom = Button.Top
+ Button.Height
RadioButtony nejsou moc velké, takže si vystačíme s tím že známe jenom jejich prostřední bod. Na to už žádná funkce není ,ale to bez obtíží zvládneme sami. Naleznutí tohoto bodu může vypadat takto:
var Bod: TPoint;
begin
Bod.X := RadioButton.Left + (RadioButton.width div 2);
Bod.Y := RadioButton.Top + (RadioButton.Height div 2);
Nyní, když známe polohu všeho co potřebujeme, ukážeme si funkci, která vyhodnocuje kolizi. Je to funkce PtInRect. Zjišťuje, zda-li je bod ve čtverci. Má dva parametry. Prvním je čtverec a druhým bod. Pokud se tento bod nachází v daném čtverci, funkce vrací True, jinak False. Obecně to tedy vypadá takto:
PtInRect(TRect,TPoint).
V našem případě by tedy celé vyhodnocení mohlo vypadat následovně:
var Bod: TPoint;
begin
Bod.X := RadioButton1.Left + (RadioButton1.width div 2);
Bod.Y := RadioButton1.Top + (RadioButton1.Height div 2);
if PtInRect(zrout.BoundsRect,Bod) then
RadioButton1.Visible := false;
Ale tak jednoduché to nebude, protože RadioButtonů je tam několik. Aby se nám s nimi dobře manipulovalo, uložíme si je všechny do pole. To je datový typ, který zatím neznáte a budeme ho podrobně probírat později. Pravděpodobně v příští lekci. Pole se deklaruje za klíčovým slovem type:
type
pole = array[1..X] of TRadioButton;
Za X dosaďte takový počet RadioButtonů, jaký jste použili. Já tam mám číslo 13. Teď pod klíčovým slovem var nadeklarujeme proměnnou typu pole. Já jsem jí dal jméno jidlo:
var
jidlo: pole;
Do pole jidlo teď musíme přiřadit všechny RadioButtony. To uděláme v události formuláře OnCreate.:
procedure TForm1.FormCreate(Sender:
TObject);
begin
jidlo[1] := RadioButton1;
jidlo[2] := RadioButton2;
jidlo[3] := RadioButton3;
jidlo[4] := RadioButton4;
jidlo[5] := RadioButton5;
jidlo[6] := RadioButton6;
jidlo[7] := RadioButton7;
jidlo[8] := RadioButton8;
jidlo[9] := RadioButton9;
jidlo[10] := RadioButton10;
jidlo[11] := RadioButton11;
jidlo[12] := RadioButton12;
jidlo[13] := RadioButton13;
end;
To je mých třináct, ale pokud jich tam máte víc nebo míň, přiřaďte jen potřebný počet. Teď, když jsme vše přiřadili do pole, si můžeme ukázat, jak bude vypadat vyhodnocování kolize. Protože ještě nevíte, jak se manipuluje s polem, asi to budete muset opsat :( Následující kód napište do procedury, kterou si sami vytvoříte. Já jsem si ji pojmenoval žraní:
procedure TForm1.zrani;
var bod: Tpoint; i: integer; vysbiral:
boolean; //proměnná vysbiral ukazuje jestli zbívají ještě nějaké bílé puntíky
nebo už jsou všechny vyzbírané
begin
vysbiral := True; //zde je nutné nastavit na True aby vše správně fugovalo
for i := 1 to 13 do //cyklus s
pevným počtem opakování nastavený na 13.. zase si upravte podle toho kolik máte
puntíků;)
begin
Bod.X :=
jidlo[i].Left + (jidlo[i].width div 2);
//to Vám jistě něco připomíná:)
Bod.Y :=
jidlo[i].Top + (jidlo[i].Height div 2);
//to Vám jistě něco připomíná:)
if
PtInRect(zrout.BoundsRect,bod) then //tohle jsme taky už probrali
jidlo[i].Visible := false;
if
jidlo[i].Visible = True then //tady je vyhodnocení, jestli jsou
všechny RadioButtony vysbírané. Pokud je nějaký viditelný tak vysbiral := False
vysbiral := False;
end;
if vysbiral = True then
//Pokud tedy není ani jeden viditelný tak se program zavře
Close(); // funkce Close() ukončí
celou aplikaci...
end;
Teď už jenom stačí tuto proceduru vyvolat pokaždé, když se žrout pohne.
Úkol
Jistě jste si všimli, že v programu, který jste si stáhli, je toho mnohem víc než jsme teď probrali. To je proto, že zbytek je úkol. Takže si to shrneme:
×Přepsat to, co je v lekci.
×Dodělat co chybí - klapání ve všech směrech
- Tlačítko které Vás honí (Ano i tohle je už A.I., i když hodně primitivní).
*Teď si prosím přečtěte text dole u hvězdiček!!
- Doladit program. Můžete mu udělat menu. Přidat nějaké funkce. Když vysbíráte všechny puntíky, tak se program jenom suše vypne. Lepší by bylo kdyby nám třeba pogratuloval. Zkrátka zapojte fantazii ;)
****Vyhodnocení kam půjde tlačítko, které Vás honí napište do události OnTimer v druhém časovači. Interval bude určovat rychlost pohybu. Pro vyhodnocení kolize použijte funkci IntersectRect(). Má tři parametry, druhý a třetí jsou čtverce, ve kterých se má vyhodnotit kolize a první parametr udává čtverec, který vyjde z kolize.
Bude to vypadat asi takto:
IntersectRect(nic, zrout.BoundsRect, AI.BoundsRect)
Pokud nastala kolize, funkce vrací True jinak False.