80
ZÆklady programovÆn Ingrid NagyovÆ

Proè se budeme uèit programovat právì v Delphihome.tiscali.cz/masinka_mala/do_prohlizece.pdf · 2015. 5. 23. · Œ V menu zvolíme File → New → Application. Tím se vytvoří

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

  • Základy programováníIngrid Nagyová

  • Obsah

    1 ÚVOD DO PROSTŘEDÍ 31.1 Proč se budeme učit programovat právě v Delphi? .............................................. 31.2 Programátorské prostředí Delphi........................................................................... 31.3 Tlačítka, přiřazení akcí tlačítkům .......................................................................... 51.4 Grafická plocha Image, grafické příkazy .............................................................. 61.5 Nastavení prostředí Delphi, soubory a přípony..................................................... 92 PROMĚNNÉ A JEDNODUCHÉ CYKLY 112.1 Celočíselné proměnné, deklarace proměnných ................................................... 112.2 FOR-cyklus ............................................................................................................. 122.3 Barvy, míchání barev............................................................................................. 142.4 Vnořené cykly ......................................................................................................... 163 OBJEKT ELVA 193.1 Kreslení kruhových objektů .................................................................................. 193.2 Objekt elva ........................................................................................................... 203.3 Kreslení geometrických útvarů n-úhelník, krunice, spirála.......................... 233.4 Víc elv v jednom programu ................................................................................. 254 PODMÍNKY PODMÍNĚNÝ CYKLUS A PODMÍNĚNÝ PŘÍKAZ 284.1 Podmíněný cyklus................................................................................................... 284.2 Podmíněný příkaz .................................................................................................. 304.3 Výběr z více moností............................................................................................. 325 PODPROGRAMY - PROCEDURY A FUNKCE 375.1 Deklarace procedur................................................................................................ 375.2 Formální parametry............................................................................................... 395.3 Funkce ..................................................................................................................... 436 ZNAKOVÉ PROMĚNNÉ, TEXTOVÉ SOUBORY 466.1 Typy proměnných, znakové proměnné ................................................................ 466.2 Textové soubory...................................................................................................... 486.3 Textové soubory a objekt elva ............................................................................ 547 TYP POLE 587.1 Typ interval............................................................................................................. 587.2 Strukturovaný typ pole.......................................................................................... 597.3 Pole elv animace pomocí elv, honičky elv .................................................... 618 ZNAKOVÉ ŘETĚZCE, DVOUROZMĚRNÁ POLE 668.1 Znakové řetězce ...................................................................................................... 668.2 Dvourozměrné pole, matice ................................................................................... 698.3 Bitmapové obrázky, práce s myí, editovací řádek ............................................. 728.4 Objekt Bitmapa ...................................................................................................... 75

  • 1 Úvod do prostředí

    1.1 Proč se budeme učit programovat právě v Delphi?Delphi je pojmenování prostředí, které umoňuje navrhovat a vytvářet programy

    v jazyce Objektový Pascal. Objektový Pascal se v průběhu času (v polovině osmdesátýchlet) vyvinul z jazyka Pascal.

    Jazyk Pascal, podobně jako jazyk C, vznikl počátkem 70-tých let. Oba tytoprogramovací jazyky (Pascal i jazyk C) vzely ze struktury jazyka Algol a oba seinspirovali tehdy pouívanými jazyky Fortran a PL/1. Oba jazyky jsou tedy postaveny naspolečných základech a jsou si tedy podobné. Pokud ale jazyk Pascal vznikl naakademické půdě jako nástroj pro výuku principů tvorby algoritmů, programování,algoritmického mylení apod., jazyk C byl od počátku určen pro zkuené systémovéprogramátory.

    Jazyk Pascal je navíc natolik jednoduchý a jednoznačný, e pozdějí přechod nalibovolný jiný programovací jazyk Vám jistě nebude činit velké potíe. Mnoho novýchprogramovacích jazyků se jazykem Pascal inspirovalo, proto při jejich zvládání jistěvyuijete metody a programátorský styl, které jste se naučili při práci s jazykem Pascal.

    Programové prostředí Delphi vyuijete k výuce jazyka Pascal. Bude sice nutnéseznámit se s tímto prostředím a jeho nástroji. Získáme tím vak jednak monost vytvářetprogramy pro operační systém MS Windows (na rozdíl od Turbo Pascalu) a toto prostředínás povede při definicích a pouívání jednotlivých prvků jazyka Pascal (členění programudo podprogramů, strukturovaný zápis programu, nastavování parametrů procedur apod.).

    1.2 Programátorské prostředí DelphiProgramátorské prostředí Delphi je IDE (Integrated Development Environment). To ji

    podle názvu znamená, e toto prostředí v sobě integruje vechny prvky, které programátorpotřebuje pro návrh a vývoj programů, pro jejich kompilaci (překlad), testování a ladění.Prostředí je zaloeno na vizuálním principu: vechno, co bude v běícím programuvizuálně zobrazeno, programátor ji během návrhu programu vizuálně skládáz předpřipravených částí (komponent).

    Programátorské prostředí Delphi sestává z následujících částí: panel ovládacích tlačítek, například Otevři, Nová poloka, Načti, Zapi, Spusť

    apod. editovací okno pro zápis kódu programu (popis činnosti programu v jednotlivých

    situacích), formulář pro vizuální návrh prostředí budoucího programu, paleta komponent obsahuje předpřipravené části (komponenty) programu, které

    můeme přímo vkládat na plochu navrhovaného formuláře, například tlačítka,editovací pole, různé grafické komponenty, komponenty pro načtení souboru,kalendář apod.

    objektový inspektor pro nastavení vlastností a parametrů jednotlivých komponentumístěných na formuláři,

    prostředí obsahuje i dalí části, se kterými se seznámíme později.

  • Poznámka 1.2.1:Editovací okno programu a formulář spolu navzájem souvisí. Pokud se vzájemně

    překryjí, přepínáme se mezi nimi pomocí klávesy F12.

    První program spoutění a zastavování aplikacíNe se pustíme do návrhu a psaní sloitějích programů (aplikací, projektů) v Delphi,

    uvedeme obecný postup, kterým při vytváření nových aplikací, jejich spoutění a zastavenípostupovat:

    Spustíme Delphi. V menu zvolíme File → New → Application. Tím se vytvoří základ nové aplikace

    (programu). Editovací okno obsahuje pouze několik základních konstrukcí, formulářaplikace je prázdný.

    I kdy máme zatím pouze prázdnou aplikaci, je dobré jí v tomto okamiku uloit nadisk počítače, abychom předeli pozdějí ztrátě částí programu, které jsme jivytvořili. Aplikaci uloíme výběrem volby File → Save Project As z menu. Jsmevyváni k vloení názvu dvou souborů Unit1.pas, který obsahuje vlastní program anavrený formulář a Project1.dpr obsahující projektový soubor. Projektový soubor se

    Objektový inspektor Editovací okno

    Paleta komponentPanelovládacíchtlačítek

    Formulář

    Programové prostředí Delphi

  • vytváří automaticky a obsahuje dalí informace o struktuře projektu. Pro začátečníkydoporučujeme názvy těchto souborů neměnit, pro kadý projekt (program) vytvořitnovou sloku, do které projektový soubor, vlastní program a formulář uloíme.

    Uloenou aplikaci můeme spustit, i kdy jsme jetě nic nenaprogramovali.Programové prostředí Delphi za nás připravilo a definovalo konstrukce, potřebné proběh programu. Aplikaci spustíme stiskem klávesy F9 nebo výběrem volby Run →Run z menu. Na obrazovce se zobrazí prázdné edé okno (námi navrený formulář)nahoře s modrým pásem s nápisem Form1 a tlačítky pro minimalizaci amaximalizaci okna a pro ukončení aplikace.

    Aplikaci ukončíme tlačítkem pro uzavření okna nebo kombinací kláves Alt-F4. Tímse vrátíme zpět do programového prostředí Delphi a můeme pokračovat v návrhuprogramu.

    Úkol k textu 1.2.1:Vytvořte svoji první prázdnou aplikaci podle uvedeného návodu. Aplikaci ulote doadresáře PrvniPokus na disk svého počítače. Aplikaci přelote a spusťte. Zkontrolujteobsah adresáře PrvniPokus. Který ze souborů obsahuje projektový soubor, ve kterém jeuloen zdrojový kód programu, ve kterém formulář?

    1.3 Tlačítka, přiřazení akcí tlačítkůmJak ji bylo uvedeno, jsou tlačítka (podobně jako mnoho dalích prvků) komponenty,

    nalezneme je proto v paletě komponent. Paleta komponent má více záloek, napříkladStandard, Additional, System apod. Pokud chceme vybrat nějakou komponentu, musímenejprve zvolit odpovídající záloku, čím určíme skupinu komponent, ke které potřebnákomponenta náleí.

    Pro umístění tlačítka na plochu formuláře vybereme v paletěkomponent záloku Standard a v ní vyhledáme komponentus názvem Button (tlačítko) malé tlačítko s nápisem OK.Klikneme na tuto komponentu a následně na plochu formuláře.Tam se objeví tlačítko s nápisem Button1 ohraničené černýmičtverečky, které označují vybrané objekty. Myí můemezměnit velikost tlačítka (pomocí černých čtverečků) a jehoumístění (taháním myi) na ploe formuláře.

    Současně se změní údaje v objektovém inspektoru (ObjectInspector). Ty vdy aktuálně popisují vybrané objekty,označené černými čtverečky. Pokud máme vybrané tlačítko (vizprvní řádek v objektovém inspektoru Button1: TButton),objektový inspektor obsahuje informace o tomto objektu.Můeme pozorovat, e při posouvání tlačítka po ploeformuláře se automaticky mění jeho vlastnosti Top (nahoře) aLeft (vlevo), udávající souřadnice levého horního rohu tlačítka.Při změně velikosti tlačítka se mění vlastnosti Heght (výka) aWidth (ířka). Vlastnost Caption (nápis, popis) umoňujezměnit nápis na tlačítku. Naproti tomu, vlastnost Name (jméno)

  • nese název objektu, kterým se na objekt odkazujeme v programu a doporučujeme jí protoneměnit!

    Úkol k textu 1.3.1:Změňte nápis na tlačítku Button1 na Tlačítko (můete pouít i české znaky s diakritikou).Umístěte na plochu formuláře dalí tlačítka, seřaďte je pod sebe a vhodně změňte nápisyna tlačítkách. Spusťte takto vytvořený program klávesou F9 a ověřte jeho funkci.

    Tak, jak jsme se prozatím naučili tlačítka pouívat, tyto sice udělají výsledný programzajímavějím, avak po jejich stlačení nenásleduje ádná akce program nic nedělá.Tlačítku můeme přiřadit akci, která se vykoná při kadém stisku tlačítka během běhuprogramu, a to následovně:

    při návrhu programu dvakrát klikneme na dané tlačítko (nechť je to tlačítko s názvemButton1).

    zobrazí se editovací okno, ve kterém se automaticky vypíou následující řádkyprocedure TForm1.Button1Click(Sender: TObject);begin

    end;

    název Button1Click označuje, e následující akce se provede po stisku tlačítka sejménem (Name) Button1, popis akce provedeme mezi příkazy begin a end.

    Příklad 1.3.1:Změnu popisu tlačítka provedeme úpravou kódu, zapsaného v editovacím okně:

    procedure TForm1.Button1Click(Sender: TObject);begin Button1.Caption:=’Nový popis’;end;

    Umístíme-li na plochu formuláře dalí tlačítko Button2 s popisem Konec, můeme mupřiřadit akci ukončení programu následovně:

    procedure TForm1.Button2Click(Sender: TObject);begin Close;end;

    Upozornění 1.3.1:Platí pravidlo, e vekeré zápisy, které provede programové prostředí v editovacím okněautomaticky nikdy nemaeme! Pokud chceme odstranit naprogramovanou akci, smaemepouze námi připsané příkazy mezi begin a end. Vlastní odstranění přebytečných konstrukcíse provede při nejbliím uloení projektu (například Ctrl-S).

    1.4 Grafická plocha Image, grafické příkazyPro kreslení na formulář pouíváme grafickou plochu Image, která umoňuje vykreslit

    jednoduchý obrázek, načíst a zobrazit obrázek ze souboru, vytvářet animace, vizualizovatrůzné algoritmy apod. Vyhýbáme se kreslení přímo na plochu formuláře, které je velicepodobné práci s grafickou plochou, nemá vak vechny její vlastnosti.

  • Začneme poloením grafické plochy Image na plochu formuláře. Najdeme jí v paletěkomponent na záloce Additional. Po umístění na plochu formuláře má Image velikostpřiblině 100x100 bodů. Pokud jí chceme zvětit, můeme to udělat buď roztaenímpomocí myi, nebo nastavením vlastnosti Align v objektovém inspektoru na alClient.Velikost grafické plochy se tak přizpůsobí velikosti formuláře (a to i při změně velikostiformuláře), tlačítka zůstávají nad grafickou plochou.

    Grafická plocha nese název (Name) Image1, Image2 ... Má svoje plátno Canvas, nakterém kadý bod má svoje souřadnice. Bod nejvíce vlevo nahoře má souřadnice [0,0].Přesunem bodu doprava roste jeho první (x-ová) souřadnice, přesunem bodu směrem dolůroste jeho druhá (y-ová) souřadnice v kladné části osy (záporné souřadnice popisují bodymimo grafickou plochu). Na plátno kreslíme pomocí pera Pen a plochy vybarvujemepomocí tětce Brush. Pero i tětec mají svoji barvu Color, pero má svoji tlouťku Width atětec styl výplně Style (průhledný, neprůhledný, horizontální, vertikální čáry apod.).

    Na grafickou plochu budeme větinou kreslit pomocí akcí, přiřazených tlačítkům(například Button1Click) a grafické příkazy budeme zapisovat mezi begin a end.Nejjednoduím příkazem je příkaz pro vykreslení obdélníku:

    Image1.Canvas.Rectangle(100, 150, 200, 300);

    který se skládá s názvu grafické plochy Image1, názvu plátna Canvas, na které budemekreslit a příkazu pro vykreslení obdélníku Rectangle. Příkaz má čtyři celočíselnéparametry první dva jsou x-ová a y-ová souřadnice levého horního rohu obdélníku, dalídva souřadnice pravého dolního rohu tohoto obdélníku.

    Úkol k textu 1.4.1:Definujte akci na smáčknutí tlačítka, která vykreslí tři obdélníky první dva přes sebe dokříe a třetí mimo ně. Program vylaďte a otestujte. Jakou barvou se vykreslují hraniceobdélníků a jakou jejich vnitro?

    Při sputění programu má pero černou barvu a tlouťku 1, tětec má bílou barvu aneprůhledný styl výplně. Chceme-li je změnit, pouijeme přiřazovací příkazy:

    Image1.Canvas.Pen.Color:=clRed; // červená barva peraImage1.Canvas.Pen.Color:=clGreen; // zelená barva peraImage1.Canvas.Pen.Width:=5; // tlouťka pera 5Image1.Canvas.Brush.Color:=clBlue; // modrá barva tětceImage1.Canvas.Brush.Style:=bsClear; // průhledný styl výplně tětce

    Princip těchto přiřazovacích příkazů spočívá v tom, e objektům pero a tětec (Pen,Brush) na plátně Canvas změníme (přiřadíme přiřazovacím příkazem := dvojtečka, rovnáse) barvu, tlouťku nebo styl výplně. Moné hodnoty barvy a stylu výplně můeme zjistitz nápovědy po stisku klávesy F1.

    Úkol k textu 1.4.2:K tlačítku, umístěnému na ploe formuláře definujte akci,jen vykreslí tři čtverce do řady vedle sebe perem modrébarvy a tlouťky 5 s různobarevnou výplní.

    Úkol k textu 1.4.3:Grafickou plochu Canvas maeme tím způsobem, e přes ní vykreslíme bílou barvouneprůhledný obdélník. Vytvořte akci na tlačítko formuláře pro vymazání grafické plochy.

  • Přehled grafických příkazůUváděné grafické příkazy jsou odvozeny od plátna Canvas grafické plochy Image. Protopři jejich pouití musíme uvádět název grafické plochy, na kterou budeme kreslit a takénázev plátna (například Image1.Canvas pokud se jedná o plátno grafické plochy Image1).Nastavení pera a tětce

    Pen.Color:=clRed; // barva pera, další barvy clBlue, clYellow, clGreen, clWhite, clBlack atd.

    Pen.Width:=5; // tlouťka pera od 1 výePen.Style:=psSolid; // styl čáry tečkovaná, čárkovaná: psDash,

    PsDotBrush.Color:=clOlive; // barva tětceBrush.Style:=bsSolid; // styl výplně, bsSolid neprůhledné,

    bsClear bez výplně, bsVertical,bsHorizontal atd.

    KresleníRectangle(x1,y1,x2,y2); // obdélníkEllipse(x1,y1,x2,y2); // elipsa (i krunice) vepsaná do obdélníku,

    x1,y1,x2,y2 stejné souřadnice jako u obdélníku

    MoveTo(x,y); // přesun kreslícího pera do bodu [x,y]LineTo(x,y); // úsečka (čára) z aktuální pozice

    kreslícího pera do bodu [x,y]

    Práce s textemTextOut(x,y,’text’); // vypíše text v apostrofech od bodu [x,y]TextOut(x,y,IntToStr(25)); // vypíe číslo 25 od bodu [x,y]Font.Name:=’Ariel’; // typ písmaFont.Height:=16; // velikost písmaFont.Style:=[fsBold]; // řez písma tučné, ikmé, podtrené:

    fsBold, fsItalic, fsUnderLineFont.Color:=clYellow; // barva písma

    Kreslení nepravidelných tvarůPolyLine(Body: array of TPoint); // postupně spojí čárami jednotlivé

    body uvedené v závorkáchPolygon(Body: array of TPoint); // postupně spojí čárami jednotlivé

    body uvedené v závorkách a nakonecspojí poslední bod s prvním

    Příkaz PolyLine kreslí pouze křivou čáru (křivku) barvou pera. Příkaz Polygon slouík vykreslení nepravidelních n-úhelníků, uzavřených tvarů, kterých vnitro je vybarvenobarvou tětce.

    Příklad 1.4.1:Vyzkouejte následující grafické příkazy:

    PolyLine([Point(10,10),Point(100,20),Point(100,100), Point(190,100)]);Polygon([Point(10,10), Point(100,20), Point(100,100)]);

    Jaký je v těchto příkazech rozdíl? Nastavte rozdílné barvy pera a tětce asledujte účinky těchto změn. Která nastavení mají vliv na který z příkazů?

    Úkol k textu 1.4.4:Vyzkouejte vechny uvedené příkazy při vytváření programu, který postisku tlačítka vykreslí jednoduchého panáčka. Panáčka pojmenujte a jehojméno vypite také na grafickou plochu. Nezapomeňte panáčka vybarvit,můete mu namalovat vlasy, oči a nos (viz obrázek).

  • 1.5 Nastavení prostředí Delphi, soubory a příponyI kdy lze v programovém prostředí Delphi pracovat s jeho nastavením inicializovaným

    instalací programu, zkuenosti Vám jistě ukáou, e některé věci je lépe změnit. Uvedemedvě nastavení, které budou důleité i při hodnocení Vámi odevzdávaných programů.

    Prvním důleitýmnastavením je Rangechecking, které naleznetev menu Project →Optionsna záloceCompiler. Jedná se okontrolu přetečení indexůpolí a alespoň v začátcíchVám toto nastavenípomůe i při tvorběprogramů. Na stejnézáloce doporučujemenastavit také přepínačeI/O checking (kontrola

    vstupně-výstupnýchoperací) a Owerflowchecking (kontrolapřetečení při různýchvýpočtech, aritmetickýchoperacích apod.).

    Dalí nastavení jedůleité při laděníprogramu. Jedná se onastaveníautomatickéhoukládání souborů přispoutění programu.Toto nastaveníoceníte, pokud seVám při běhuprogramu zaseknepočítač, poslednízměny máte aktuálněuloeny a můete sek nim kdykoliv vrátit.Nastavení naleznetepo výběru volbyTools →EnvironmentalOptions na zálocePreferences, kdezakrtnete políčkoEditor Files.

  • Jak ji bylo uvedeno, je dobré kadý projekt (program) ukládat do jiného adresáře. Připřenosu projektu na jiný počítač není nutné přenáet vechny zde ukládané soubory (mnohéz nich pouze průběně zálohují Vai práci). Důleité jsou soubory s následujícími příponami: *.dpr projektový soubor, *.pas soubory se zdrojovým kódem programu, *.dfm formuláře programu, *.exe spustitelný soubor, který lze pomocí programového prostředí Delphi kdykoliv

    z předchozích souborů vytvořit.

    Poznámka 1.5.1:Při odesílání vypracovaných úkolů ke kontrole je nutné odeslat vechny soubory s příponami*.dpr, *.pas a *.dfm.

    Cvičení:1. Pomocí grafických příkazů vykreslete na grafickou plochu barevnou květinu.2. Pomocí příkazu Polygon vykreslete na grafickou plochu vybarvený rovnostranný

    trojúhelník viz obrázek A.3. Pomocí grafických příkazů MoveTo

    a LineTo vykreslete pyramidu vizobrázek B.

    4. Pomocí příkazu Polygon vykresletevybarvenou pyramidu sestávajícíz rovnostranných trojúhelníků vizobrázek C.

    5. Vykreslete na grafickou plochu deset různobarevných soustředních krunic (vechnykrunice mají stejný střed).

    Řeení úkolu k textu 1.4.3:Smazání grafické plochy můeme provést následovně:

    procedure TForm1.Button2Click(Sender: TObject);begin Image1.Canvas.Brush.Color:=clWhite; // bílá barva tětce Image1.Canvas.Brysh.Style:=bsSolid; Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height);end;

    nebo můeme vyuít příkaz FillRect pro vymazání grafické plochy barvou tětce (v naempřípadě bílou barvou):

    procedure TForm1.Button2Click(Sender: TObject);begin Image1.Canvas.Brush.Color:=clWhite; // bílá barva tětce Image1.Canvas.FillRect(Image1.ClientRect);end;

    Parametrem Image1.ClientRect je dána velikost grafické plochy Image1.

  • 2 Proměnné a jednoduché cykly

    Pokud jste řádně plnili úkoly, uvedené ve cvičeních předchozí lekce, jistě jste si povimli,e by bylo uitečné mít nástroj, kterým by se zadávání souřadnic zjednoduilo. Jistě jste častodanou souřadnici měnili pouze o jistý počet bodů, přitom celý zbytek příkazu zůstával bezezměny.

    V této kapitole si ukáeme, jak takovéto problémy řeit. Zavedeme pojem proměnné,hodnoty které budeme moci jednodue měnit. Změna hodnoty proměnné v cyklu(několikanásobní změna hodnoty proměnné) nám umoní kreslit dalí zajímavé obrázky.

    2.1 Celočíselné proměnné, deklarace proměnnýchVyuití proměnných ukáeme nejprve na konkrétním příkladu.

    Příklad 2.1.1:Vykreslíme čtverec o velikosti strany 100 bodů. Souřadnice levého horního rohu čtvercebudou [50,70]. Vykreslení provedeme po stisku tlačítka Button1.

    procedure Button1Click(Sender: Tobject); var a, x, y: Integer; begin a := 100;

    x := 50; y := 70; Image1.Canvas.Pen.Width := 5; Image1.Canvas.Rectangle(x, y, x+a, y+a);

    end;

    Vytvořte aplikaci s grafickou plochou Image1 a jedním tlačítkem Button1. Ověřte funkciuvedené procedury. Změňte uvedenou proceduru tak, aby souřadnice levého horního rohučtverce byly [120,120]. Pomocí stejné procedury vykreslete větí čtverec nebo krunici.

    V uvedeném příkladu jsou a, x a y proměnné. Pokud je chceme v programu pouít,musíme je nejprve zadeklarovat: za slovo var zapíeme seznam proměnných a protoe sejedná o celočíselné proměnné, zapíeme za dvojtečku Integer (var a, x, y: Integer;).

    Tím, e jsme proměnné zadeklarovali, vyhradí se pro ně při sputění procedury (při slověbegin) místo v paměti počítače. Pokud se jedná o celočíselné proměnné, je kadé proměnnépřiřazeno místo 4B (32 bitů), a tedy deklarovaná celá čísla mohou nabývat hodnot z intervalu, co je přiblině + nebo - 231 (4Byte = 32 bit = 31 bitů pročíslo + bit pro znaménko).

    Tím, e se proměnné vyhradí potřebné místo v paměti počítače, tato proměnná jetě nemápřiřazenou hodnotu. Říkáme, e její hodnota je nedefinovaná. Předtím, ne tuto proměnnoupouijeme, musíme jí nějakou hodnotu přiřadit pomocí přiřazovacího příkazu (:=) vizpříklad. Hodnota proměnné je pak uchována na vyhrazeném místě během celé procedury.Můeme s ní pracovat, můeme jí i několikrát měnit. Při skončení procedury (slovo end) sevak vechny deklarované proměnné zruí a jejich hodnoty se nenávratně ztratí.

    Kadá proměnná má své jméno (název, identifikátor). V příkladu jsem pouili pouzejednopísmenová jména proměnných (a, x, y). Obecně můe být jméno proměnné jakékolivslovo, které můe obsahovat i číslice (ne na začátku jména) a podtrhovátko (znak _). Jménaproměnných nesmí obsahovat písmena s diakritikou. V jednoduchých programech vystačíme

  • obvykle s krátkými jmény (jedno-, dvoj- písmenová pojmenování), ve sloitějích a delíchprogramech pouijeme pro lehčí orientaci spíe delí pojmenování (i více ne 10 znaků).

    Vraťme se zpátky k naemu programu. Očekávali jsme, e zavedení proměnných přispějek variabilitě programu. Skutečnost je ale taková, e proměnné a, x a y (viz příklad) majíhodnoty pevně přiřazené na začátku procedury (hodnoty 100, 50 a 70). Tyto hodnoty jsou přikadém volání procedury stejné, nemění se ani při běhu procedury. Proto se při kliknutí natlačítko Button1 vykreslí pokadé stejný čtverec na stejném místě grafické plochy. Pokudbychom chtěli při kadém stisku tlačítka vykreslovat čtverec na jiném místě grafické plochy,museli bychom měnit souřadnice x a y levého horního rohu čtverce. Provedeme to pomocínáhodného generátoru funkce Random a program upravíme následovně.

    procedure Button1Click(Sender: Tobject); var a, x, y: Integer; begin a := 100; x := Random(350); y := Random(300); Image1.Canvas.Pen.Width := 5; Image1.Canvas.Rectangle(x, y, x+a, y+a); end;

    Funkce Random(n) vybere (vygeneruje) náhodně celéčíslo z intervalu . Příkazem x := Random(350)přiřadíme proměnné x náhodné celé číslo v rozmezí 0 a349. Podobně přiřadíme proměnné y náhodné číslov rozmezí 0 a 299. Uvedená procedura tedy při kadémstisku tlačítka Button1 vykreslí čtverec o straně délky 100bodů na jiném místě grafické plochy (viz obrázek).

    Generátor náhodných čísel generuje při opětovném sputění programu pokadé stejnáčísla (ověřte). Proto je dobré generátor inicializovat příkazem Randomize. Při dvojnásobnémpoklepání na formulář (na místo mimo záhlaví a umístěných komponent) můeme zapsat kódprogramu, jen se provede při vytváření formuláře (při spoutění programu). Inicializujemezde náhodný generátor:

    procedure TForm1.FormCreate(Sender: TObject);begin Randomize;end;

    2.2 FOR-cyklusZačneme opět příkladem.

    Příklad 2.2.1:Vykreslíme 8 svislých čar vedle sebe.

    procedure Button1Click(Sender: Tobject); begin Image1.Canvas.Pen.Width := 5;

    Image1.Canvas.MoveTo(10, 10); Image1.Canvas.LineTo(10, 110); Image1.Canvas.MoveTo(20, 10); Image1.Canvas.LineTo(20, 110); Image1.Canvas.MoveTo(30, 10); Image1.Canvas.LineTo(30, 110); Image1.Canvas.MoveTo(40, 10); Image1.Canvas.LineTo(40, 110); Image1.Canvas.MoveTo(50, 10); Image1.Canvas.LineTo(50, 110); Image1.Canvas.MoveTo(60, 10); Image1.Canvas.LineTo(60, 110);

  • Image1.Canvas.MoveTo(70, 10); Image1.Canvas.LineTo(70, 110); Image1.Canvas.MoveTo(80, 10); Image1.Canvas.LineTo(80, 110);end;

    Pokud jste uvedené řeení opravdu přepisovali do počítače, určitě Vás napadlo, zdaneexistuje konstrukce, která by automaticky zvyovala x-ovou souřadnici příkazů MoveTo aLineTo a y-ovou souřadnici by neměnila. Uvedený příklad lze přepsat pomocí FOR-cyklunásledovně:

    procedure Button1Click(Sender: Tobject);var i: Integer;

    begin Image1.Canvas.Pen.Width := 5; for i:=1 to 8 do begin Image1.Canvas.MoveTo(i*10, 10); Image1.Canvas.LineTo(i*10, 110); end;end;

    Z konstrukce uvedeného příkladu je zřejmé, e FOR-cyklus slouí k opakování částíprogramu jednoho nebo několika příkazů uzavřených mezi begin a end. Konstrukce tohototypu cyklu začíná slovem for, za kterým následuje přiřazení počáteční hodnoty (v naempřípadě 1) pomocné proměnné i, tzv. proměnné cyklu. Za slovem to následuje koncováhodnota, kterou nanejvý můe proměnná cyklu nabývat. Slovo do končí úvodní deklaraciFOR-cyklu a uvádí seznam příkazů pro opakování, tzv. tělo cyklu příkazy uzavřené mezibegin a end.

    Proměnná FOR-cyklu musí být deklarována před cyklem v části var. S její hodnotoumůeme v příkazech těla cyklu počítat a pouívat jí (viz příkazy MoveTo a LineTo). Hodnotuproměnné cyklu vak nesmíme v těle cyklu měnit! Po skončení cyklu ztrácí proměnná cyklusvoji hodnotu, její hodnota je nedefinovaní a pro dalí pouití musíme této proměnné nějakouhodnotu přiřadit.

    Tělo cyklu se opakuje pro proměnnou cyklu od její počátečné po koncovou hodnotu.Pokud označíme počátečnou hodnotu proměnné cyklu A a koncovou hodnotu B, platí:

    pro A ≤ B se tělo cyklu opakuje pro hodnoty A, A+1, A+2, , B, tj. B-A+1 krát, pro A = B se tělo cyklu zopakuje právě jednou pro hodnotu A proměnné cyklu, pro A > B se tělo cyklu vůbec nevykoná.Počátečná a koncová hodnota proměnné cyklu nemusí být zadána pouze konstantou, jak

    tomu bylo v naem případě. Můe být zadána i sloitým aritmetickým výrazem. V takovémpřípadě se tyto výrazy před prvním vykonáním těla cyklu vyhodnotí a tělo cyklu se opakujepodle vypočtené počáteční a koncové hodnoty.

    Příklad 2.2.2:Vykreslíme 15 čtverců se společným středem v bodě [250,200]. Budeme vycházet z programu z příkladu 2.1.1.procedure TForm1.Button1Click(Sender:TObject);

    var a, x, y, i: Integer; begin Image1.Canvas.Pen.Width := 5; x := 250; // souřadnice středu y := 200; for i := 1 to 15 do begin

  • a := 158-8*i; // polovina délky strany čtverce Image1.Canvas.Rectangle(x-a,y-a,x+a,y+a); end; end;

    Podívejme se podrobněji na uvedené řeení:• Bod [x, y] v tomto případě není (na rozdíl od příkladu 2.1.1) levým horním rohem čtverce,

    ale jeho středem. Proměnným x a y jsme přiřadili hodnoty před cyklem, dále se hodnotytěchto proměnných nemění.

    • V proměnné a není uloena délka strany čtverce (viz příklad 2.1.1), ale pouze jejípolovina. Pro její výpočet jsme pouili výraz a := 158-8*i, a tedy z ohledem napočátečnou a koncovou hodnotu proměnné cyklu i (i nabývá hodnoty od 1 do 15) jehodnota proměnná a postupně 150, 142, 134, 126, ..., 38.

    • Uvedené řeení vykreslí čtverce od největího po nejmení. Pokud bychom chtěli postupobrátit a vykreslit čtverce od nejmeního po největí, museli bychom upravit vzorec provýpočet hodnoty proměnné a následovně a := 30+8*i. Víme, e předdefinované hodnotastylu tětce je neprůhledné kreslení, a tedy větí čtverec by v tomto případě překreslilmení (ji vykreslený). Pokud bychom chtěli vykreslovat čtverce od nejmeního ponejvětí, museli bychom nastavit styl tětce na bsClear (průhledný). Pokuste se tutomylenku prakticky realizovat.

    Vidíme, e v programech můeme pouívat nejrůznějí, často i značně komplikované,výrazy. Při zapisování těchto výrazů je nutné mít na paměti prioritu operací (násobení a dělenímá větí prioritu neli sčítání a odečítání), která je při jejich vyhodnocování dodrována.Kromě základních operací pro celá čísla +, -, * (výsledek dělení není celočíselný) můemepouít celočíselné dělení div a zbytek po dělení mod.

    2.3 Barvy, míchání barevProzatím jsme se naučili pouívat předdefinované barvy, jako například clWhite,

    clYellow, clRed, clBlue, clGreen, clOlive, clBlack a podobně. Samozřejmě, e ve svýchprogramech můeme pro vykreslení pouít i řadu jiných barev. Ty si namícháme ze třízákladních sloek červené, zelené a modré přes tzv. RGB paletu (RGB = red, green, blue= červená, zelená, modrá).

    Hodnoty RGB nejpouívanějích barevRGB Název barvy Barva

    RGB(255, 0, 0) clRed červenáRGB(128, 0, 0) clMaroon tmavě červenáRGB(0, 255, 0) clLime zelenáRGB(0, 128, 0) clGreen tmavě zelenáRGB(0, 0, 255) clBlue modráRGB(0, 0, 128) clNavy tmavě modráRGB(0, 0, 0) clBlack černáRGB(255, 255, 255) clWhite bíláRGB(128, 128, 128) clGray edá

  • RGB(255, 255, 0) clYellow lutáRGB(0, 255, 255) clAqua tyrkysováRGB(255, 0, 255) clFuchsia cyklámenováRGB(153, 51, 0) hnědá

    Příklad 2.3.1:Vykreslete čáru, která bude plynule měnit barvu od bílé, přes červenou, do černé.Čáru vykreslíme ve dvou fázích: přechod od bílé RGB(255, 255, 255) do červené RGB(255, 0, 0) červená sloka

    zůstane konstantní (rovna 255), zelená a modrá sloka se budou současně měnit odmaximální hodnoty 255 do 0,

    přechod od červené RGB(255, 0, 0) do černé RGB(0, 0, 0) zelená a modrá slokazůstanou konstantní (nulové), červená sloka bude klesat k 0 (k černé barvě).

    procedure TForm1.Button1Click(Sender: TObject);var i: Integer;begin Image1.Canvas.Pen.Width := 5; Image1.Canvas.MoveTo(0, 100); for i := 0 to 255 do // změna od bílé do červené begin Image1.Canvas.Pen.Color := RGB(255,255-i,255-i); Image1.Canvas.LineTo(0+i, 100); end; for i := 0 to 255 do // změna od červené do černé begin Image1.Canvas.Pen.Color := RGB(255-i,0,0); Image1.Canvas.LineTo(255+i, 100); end;

    end;

    Úkol k textu 2.3.1:Řete problém z příkladu 2.3.1 pro čáru měnící se od bílé, přes zelenou, do černé a pro čáru,která se bude měnit od bílé, přes modrou a do černé.

    Náhodnou barvu můeme namíchat například takto:Image1.Canvas.Pen.Color := RGB(random(256),random(256),random(256));

    Image1.Canvas.Pen.Color := RGB(random(256),0,random(256)); Image1.Canvas.Pen.Color := RGB(150+random(106),0,200);

    Příklad 2.3.2:Vykreslete soustředné barevné krunice měnící postupněsměrem do středu barvu.Krunice budeme vykreslovat bez hraniční čáry pera (stylpera nastavíme na psClear). Barvu výplně budeme měnitod modré RGB(0, 0, 255) do bílé.

  • procedure TForm1.Button1Click(Sender: TObject);var a, x, y, i: Integer;begin Image1.Canvas.Pen.Style := psClear; x := 260; y := 260; for i := 0 to 255 do begin a := 255-i; // poloměr krunice Image1.Canvas.Brush.Color:=RGB(i,i,255); Image1.Canvas.Ellipse(x-a, y-a, x+a, y+a); end;end;

    2.4 Vnořené cyklyTam, kde při kreslení a výpisech potřebujeme měnit obě souřadnice (x-ovou i y-ovou), se

    uplatní vnořené cykly. Jejich vyuití si předvedeme na příkladech.

    Příklad 2.4.1:Vykreslíme hvězdičky do čtverce 10 x 10 hvězdiček.Pouijeme vnořené cykly, přičem proměnná i vnějího cyklu bude procházet řádky (odvinese od ní y-ová souřadnice) a proměnná j vnitřního cyklu bude procházet sloupce (a také x-ovou souřadnici).

    procedure TForm1.Button1Click(Sender: TObject);var i, j: Integer;begin Image1.Canvas.Font.Color := clGreen; Image1.Canvas.Font.Size := 10; for i := 1 to 10 do for j := 1 to 10 do Image1.Canvas.TextOut(j*10, i*10, '*');end;

    Úkol k textu 2.4.1:U vnořených cyklů se vnitřní cyklus (v naem případě cyklus s proměnnou j) vykoná prokadou hodnotu proměnné vnějího cyklu (proměnné i).Vytvořte si jednoduchou tabulku, do které budete zapisovat aktuální hodnoty proměnnýchi a j. Procházejte postupně krok za krokem programem z příkladu 2.4.1. Při kadé změněhodnoty jedné z proměnných evidujte tuto změnu v tabulce. Jak se postupně mění hodnotyproměnných i a j? Kolikrát v průběhu výpočtu dosáhne maximální hodnoty (hodnoty 10)proměnná i a kolikrát proměnná j?

    Příklad 2.4.2:Vykreslete hvězdičky do trojúhelníku v prvním řádku bude pouze jedna hvězdička, vedruhém dvě, ve třetím tři, atd. Vyjdeme-li z řeení příkladu 2.4.1, bude počet opakovánívnitřního cyklu záviset na aktuálním řádku počet opakování vnitřníhocyklu bude přesně odpovídat hodnotě proměnné i vnějího cyklu.

    procedure TForm1.Button1Click(Sender: TObject);var i, j: Integer;begin Image1.Canvas.Font.Color := clGreen;

  • Image1.Canvas.Font.Size := 10; for i := 1 to 10 do for j := 1 to i do Image1.Canvas.TextOut(j*10, i*10, '*');end;

    Pokud bychom chtěli vypsat trojúhelník hvězdiček symetricky podle svislé osy, muselibychom změnit souřadnice pro výpis hvězdiček:

    procedure TForm1.Button1Click(Sender: TObject);var i, j: Integer;begin Image1.Canvas.Font.Color := clGreen; Image1.Canvas.Font.Size := 10; for i := 1 to 10 do for j := 1 to i do Image1.Canvas.TextOut(110-j*10, i*10, '*');end;

    Úkol k textu 2.4.2:Upravte předchozí programy tak, aby se trojúhelníky hvězdiček vypisovaly jedním svýmcípem směrem dolů (oproti příkladu 2.4.2 překlopené podle vodorovné osy). Jak je potřebaupravit počátečnou a koncovou hodnotu proměnné vnitřního cyklu?

    Cvičení:1. Vraťte se k programu, který jste vytvořili

    v minulé lekci pro vykreslení jednoho panáčka.Program upravte tak, aby vykreslil několikpanáčků vedle sebe drících se za ruku.K vykreslování pouijte FOR-cyklus.

    2. Napite program, který po stisku tlačítka vypíe tabulku malénásobilky.

    3. Napite program, který po stisku tlačítka vypíe text s dlouhým barevným stínem.Stín půjde zprava doleva a bude plynule měnitbarvu. Na obrázku jsme vyli z modré barvy(clBlue) a měnili její prostřední sloku RGBpalety. Pro vykreslení stínu je potřeba nastavitprůhledný styl tětce (bsClear).Nezapomeňte pro zvýení efektu vypsat nakonecstejný text původní barvou.

  • 4. Upravte příklad 2.3.2 tak, e nebudete vykreslovat krunice, ale čtverce. Vyzkouejte ijiné plynulé barevné změny.

    5. Vykreslete malé čtverečky (3x3 bodů) do sítě256 x 256 čtverečků. Kadý čtvereček budevykreslen jinou barvou jednu sloku v RGBpaletě zafixujte, druhou budete měnits proměnnou vnějího cyklu a třetí se změnouproměnné vnitřního cyklu (viz obrázek).

    6. Vykreslete achovnici 8x8 čtverců. Pozor na pravidelné střídáníbílých a černých políček.

  • 3 Objekt elva

    Předtím, ne se seznámíme s objektem elva, který nám umoní kreslit jednoduchýmzpůsobem sloité geometrické tvary, si ukáeme, jak vyuít ke kreslení kruhových objektů aobrázků uspořádaných do kruhu goniometrické funkce sinus a cosinus.

    3.1 Kreslení kruhových objektůZ matematiky je obecně známo, e v pravoúhlém trojúhelníku (viz obrázek) platí pro

    sinus a cosinus úhlu α následující vztahy:

    Převedeme-li tyto vztahy na body, leící na krunici, zjiťujeme, e kadý bod leící nakrunici se středem v bodě [x, y] a poloměrem r má souřadnice ( ) ( )[ ]αα sin*,cos* ryrx ++ ,kde α je úhel, který svírá polopřímka začínající ve středu krunice a procházející danýmbodem krunice s kladnou částí x-ové osy.

    Příklad 3.1.1:Vytvoříme program, který po stisku tlačítka vykreslí 24 paprsků rovnoměrně rozdělených pokrunici. Paprsky budeme kreslit jako čáry, které budou vycházet ze středu krunice a budoukončit na jejím obvodu.

    procedure TForm1.Button1Click(Sender: TObject);var i, x, y, r: Integer; a: Real;begin Image1.Canvas.Pen.Width := 2; Image1.Canvas.Pen.Color := clNavy; x := 100; // souřadnice středu paprsků y := 100; r := 70; // délka paprsků for i:=1 to 24 do begin a := 360/24*i*pi/180; // úhel přepočtený na radiány Image1.Canvas.MoveTo(x, y); Image1.Canvas.LineTo(x+Round(r*cos(a)), y+Round(r*sin(a))); endend;

    ( )ca

    přeponastranaprotilehlá == _sin α

    ( )cb

    přeponastranapřílehlá == _cos α

  • Při řeení příkladu 3.1.1 jsme poznali, e pokud pouijeme goniometrické funkce sinus acosinus, nevystačíme pouze s celočíselnými proměnnými. I v případě, e sami budeme počítatúhly ve stupních (celočíselných), musíme tyto hodnoty převádět pro jejich pouitív goniometrických funkcích na radiány podle vztahu:

    Proměnné, jejich hodnoty jsou reálná čísla, deklarujeme jako proměnné typu Real(var a: Real;). Při deklaraci proměnné typu Real se jí v paměti vyhradí místo 6B, a tedyreálná čísla mohou nabývat hodnot z intervalu .

    Reálná čísla nejsou v počítači obvykle reprezentována úplně přesně (nenabývají přesněsvých hodnot). Při počítání a operacích s reálnými čísly se tyto chyby a nepřesnosti jetězvyují, proto se snaíme jejich pouití v programech minimalizovat a výpočty převádětv oboru celých čísel. Pro převod reálných čísel na celá čísla můeme vyuít následujícífunkce:

    Trunc z reálného čísla vybere pouze jeho celou část (desetinnou část odstraní), Round zaokrouhlí reálné číslo na celá čísla (viz příklad 3.1.1).

    Upozornění 3.1.1:Reálná čísla píeme v programech s desetinnou tečkou!!! (Viz zápis intervalu přípustnýchreálných čísel.) Desetinnou čárku můeme pouít pouze ve výstupech (ve výpisech naobrazovku, při tisku apod.).

    Úkol k textu 3.1.1:Upravte program z příkladu 3.1.1 tak, aby se při stisku tlačítka vymazala grafická plocha avykreslilo se nové sluníčko. Počet paprsků sluníčka náhodně generujte v rozmezí 20-50paprsků.

    3.2 Objekt elvaKreslení sloitějích grafických struktur nám usnadní speciálně cvičené elvy, které se po

    grafické ploe budou různým způsobem pohybovat a zanechávat za sebou čáru. Tyto elvy,přímé následovatelky elv LOGO, nejsou součástí programového prostředí Delphi. Do tohotoprostředí musíme elvy nejprve přidat:

    Otevřeme novou aplikaci, kterou uloíme do zvlátního adresáře. Do tohoto adresářeuloíme také soubor ZelvaUnit.pas, jen obsahuje potřebné údaje pro pohyb elv.

    Na formulář aplikace umístíme grafickou plochu a tlačítko. V editovacím okně zapíeme za řádek

    {$R *.DFM}řádek: uses ZelvaUnit;Tento zápis předpokládá, e máme soubor ZelvaUnit.pas uloen ve stejné sloce, vekteré je uloena celá aplikace. Pokud budeme vytvářet víc aplikací s pouitím elv,budeme muset tento soubor kopírovat do sloky kadé z nich.

    Pouití nové elvy definujeme přímo v programu. Poklepeme na tlačítko na formulářia vepíeme následující kód:

    rad180

    *παα =°

  • procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i: Integer;begin z := TZelva.Create; z.Smaz; for i := 1 to 4 do begin z.vpred(150); z.vpravo(90); end;end;

    V programu nejprve deklarujeme proměnnou z typu TZelva, z její pomocí budeme elvuovládat. Příkazem TZelva.Create vytvoříme novou elvu. elva se vytvoří (narodí) ve středugrafické plochy a je otočena směrem nahoru (je připravena pohybovat se směrem nahoru).Příkaz z.Smaz smae grafickou plochu a připraví jí tak pro dalí kreslení.

    Ve FOR-cyklu se opakují dva příkazy: z.vpred řídí pohyb elvy z dopředu o počet kroků uvedených v závorce (v naem

    případě o 150 kroků), z.vpravo otočí elvu vpravo ve směru hodinových ručiček o úhel daný v závorkách

    (v naem případě o 90°).Princip elvy je následující: elva je umístěna na grafické ploe a je natočena určitým

    směrem. V této situaci jí není vidět. elva se můe procházet po grafické ploe a pokud másputěné pero, kreslí cestou, kterou prochází. Pokud pero zvedne, nekreslí, pouze seneviditelně přesouvá. Aby kreslení bylo zajímavějí, můeme měnit barvu a tlouťku peraelvy.

    Abychom mohli lépe pozorovat, co elva provádí, můeme vykonávání programuzpomalit pomocí příkazu Cekej, který je součástí elvího prostředí. Parametrem příkazuCekej je počet milisekund, po které se má vykonávání programu pozastavit.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i: Integer;begin z := TZelva.Create; z.Smaz; for i := 1 to 4 do begin z.vpred(150); z.vpravo(90); Cekej(500); // pozastavení programu na 0,5 s end;

    end;Pouití příkazu Cekej můe v prostředí MS Windows činit jisté potíe. Z toho důvodu jej

    nedoporučujeme pouívat ve větích aplikacích, pro nae potřeby vak postačí.

    elva se můe otáčet nejenom vpravo, ale také vlevo, proti směru hodinových ručiček.K tomu jí slouí příkaz z.vlevo, ve kterém opět zadáme počet úhlových stupňů, o které se máelva vlevo otočit.

    Pokud v uvedeném programu budeme měnit počet opakování a úhel otočení elvy,dostaneme mnoho zajímavých obrázků a tvarů. S některými z nich se seznámíme při řeenídalích úkolů.

  • Příklad 3.2.1:Vykreslíme pěticípou hvězdu. Budeme muset zvětit počet opakování FOR-cyklu na pět ataké změnit úhel otáčení elvy na 360/5 = 144°.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i: Integer;begin z := TZelva.Create; z.Smaz; for i:=1 to 5 do begin z.vpred(100); z.vlevo(144); Cekej(300); endend;

    Přehled elvích příkazůK tomu, abychom elví příkazy mohli pouít, musíme mít na formuláři umístěnou grafickouplochu. elvu musíme nejprve vytvořit příkazem z := TZelva.Create; elva se vytvoří vestředu grafické plochy a je natočena směrem nahoru. elva zná následující příkazy:Vytvoření elvy z:=Tzelva.Create; // vytvoří elvu uprostřed grafické plochy

    otočenou směrem vzhůru (na sever)Poloha elvy

    z.X, z.Y // x-ová a y-ová souřadnice aktuální polohy elvyz.H // aktuální úhel natočení elvy

    Pohyb elvyz.vpravo(120); // elva se otočí vpravo o 120 stupňůz.vlevo(45); // elva se otočí vlevo o 45 stupňůz.setuhel(330); // elva se na místě otočí do úhlu 330 stupňů

    0° - směr kladné části x-ové osy úhly měříme proti směru hodinových ručiček

    z.vpred(100); // elva se posune o 100 kroků vpředz.movexy(150, 280); // elva se přesune se zdvieným perem do bodu se

    sou5adnicemi [150, 180] - nekreslí čáruz.setxy(150, 280); // elva se přesune do bodu se sou5adnicemi

    [150, 180] - kreslí čáruz.bod; // elva vykreslí bod velikosti tlouťky pera

    Nastavení pera elvyz.pd; // elva spustí peroz.ph; // elva zvedne pero, nebude při dalím pohybu

    kreslitz.pc := clRed; // změna barvy pera na červenouz.pw := 5; // změna tlouťky pera na 5 bodů

    Ostatní příkazyz.smaz; // elva smae grafickou plochuz.vypln(clBlue); // elva vyplní ohraničenou plochu modrou barvouz.vzdal(100,150); // vzdálenost bodu [100, 150] od momentální polohy

    elvyCekej(300); // pozastaví běh programu na 300 milisekund

    Příklad 3.2.2:Vykreslíme rovnostranný trojúhelník čárkovanou (program vlevo) a tečkovanou čárou (vizprogram vpravo).

  • procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i, j: Integer;begin begin z := TZelva.Create; z.smaz; z := TZelva.Create; z.smaz; for i:=1 to 3 do z.ph; begin for i:=1 to 3 do for j:=1 to 10 do begin begin for j:=1 to 20 do z.pd; z.vpred(7); begin z.ph; z.vpred(7); z.bod; z.vpred(7); end; end; z.vlevo(120); z.vlevo(120); end endend; end;

    Srovnejte zápisy obou programů a vyzkouejte je. Který kreslí čárkovanou čáru a kterýtečkovanou? Poznáte to jetě před sputěním programu?

    3.3 Kreslení geometrických útvarů n-úhelník, krunice, spirálaVykreslení jednotlivých geometrických útvarů předvedeme prakticky na příkladech.

    Příklad 3.3.1:Vyzkoueli jsme ji kreslení trojúhelníku, čtverce, pěticípé hvězdy. Nyní vykreslímepravidelný n-úhelník

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i, n: Integer;begin z := TZelva.Create; z.Smaz; n:=9; for i:=1 to n do begin z.vpred(50); z.vpravo(360/n); end

    end;.

    Příklad 3.3.2:Krunici kreslíme jako speciální 360-úhelník s maloudélkou strany.

    procedure TForm1.Button1Click(Sender:TObject);var z: TZelva; i: Integer;begin z := TZelva.Create; z.Smaz; for i:=1 to 360 do begin z.vpred(2); z.vpravo(1); end

    end;.

  • Pokud bychom FOR-cyklus opakovali pouze 180-krát nebo 90-krát, nedostali bychomkrunici, ale pouze její část (půlkrunice, čtvrtkrunice). Následující příklad ukáe, jakpomocí čtvrtkrunic vykreslit květinu o 9-ti lupíncích.

    Příklad 3.3.3:Kadý lupínek květiny bude sestávat ze dvou čtvrtkrunic proti sobě (mezi nimi se elva otočío 90°). Jednotlivé lupínky umístíme stejnoměrně po krunici (elva se před vykreslenímkadého z 9-ti lupínků otočí o 360/9°).procedure TForm1.Button1Click(Sender:TObject);var z: TZelva; i, j, k: Integer;begin z:=TZelva.Create; z.Smaz; z.PC:=clRed; z.PW:=3; for k:=1 to 9 do begin for j:=1 to 2 do // jeden lupínek begin for i:=1 to 90 do // čtvrtkrunice begin z.vpred(2); z.vpravo(1) end; z.vpravo(90) end; z.vpravo(360/9) end;end;

    Úkol k textu 3.3.1:Doplňte řeení příkladu 3.3.3 o vykreslení celé květiny vybarvěte lupínky (pouitím příkazu z.vypln(clYellow)),přikreslete stonek a zelený lístek (viz obrázek).

    Pokud umíme namalovat kruhové objekty, vytvoříme z nich spirálovitě zatočené objektytak, e budeme ve FOR-cyklu měnit se změnou proměnné cyklu měnit i délku kroku elvy.Situaci předvedeme opět na příkladu.

    Příklad 3.3.4:Čtverec do spirály.procedure TForm1.Button1Click

    (Sender: TObject);var z: TZelva; i: Integer;begin z:=TZelva.Create; for i:=1 to 50 do begin z.vpred(i*2+10); z.vpravo(90); // vyzkoušejte i jiné úhly 91, 71, 123, 145 apod. endend;

  • Spirálový objekt dostaneme i tehdy, kdy budeme s proměnnou cyklu měnit úhel otočeníelvy.procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; r: Real; i: Integer;begin z:=TZelva.Create; r:=20; // vyzkoušejte 5, 10 apod. for i:=1 to 2000 do begin z.vpred(2); z.vpravo(r); r:=r*0.99; // vyzkoušejte 0.995, 0.999 apod. endend;

    Nebo také jiná moná změna úhlu:procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i: Integer;begin z:=TZelva.Create; for i:=1 to 2000 do begin z.vpred(5); z.vpravo(i); // vyzkoušejte i+0.1, i+0.2 apod. endend;

    3.4 Víc elv v jednom programuV jednom programu (proceduře) nemusíme obecně pouít pouze jednu elvu. Příkazem

    z:=TZelva.Create; můeme vytvořit libovolný počet el. Kadá z nich můe kreslit něcojiného a společně vytvořit zajímavý obrázek.

    Příklad 3.4.1:Vyzkouejte činnost následujícího programu, který vyuívá tří elv ke lreslení tří různýchkrunic. Porovnejte parametry nastavené pro jednotlivé elvy.

    procedure TForm1.Button1Click(Sender: TObject);var z1, z2, z3: TZelva; i: Integer;begin z1:=TZelva.Create; z1.PC:=clRed; z1.PW:=2; z1.movexy(150, 150); z2:=TZelva.Create; z2.PC:=clBlue; z2.movexy(150, 190); z3:=TZelva.Create; z3.PC:=clGreen; z3.PW:=5; z3.movexy(300, 150); for i:=1 to 360 do begin z1.vpred(2); z1.vlevo(1); z2.vpred(150); z2.vlevo(91); z3.vpred(2); z3.vlevo(1); Cekej(100) end;end;

  • Cvičení:1. Upravte program pro vykreslování paprsků (příklad

    3.1.1) tak, aby se délka paprsků měnila se změnouhodnoty proměnné FOR-cyklu.

    2. Upravte program pro vykreslování paprsků (příklad 3.1.1 tak, aby sepaprsky do poloviny kruhu prodluovaly a pak se zase zpět zkracovaly.Vznikne tvar podobný srdíčku (viz obrázek).

    3. Vykreslete paprsky (příklad 3.1.1) pomocí objektu elva.Paprsky pouijte pro vykreslení sluníčka.

    4. Z dvou čtvrtkrunic (objekt elva) lze vytvořit siluetu letícího ptáka (vizobrázek). Zabarvěte grafickou plochu bleděmodrou barvou a vytvořteprogram, který po stisku tlačítka vykreslí na nebe (modrou grafickouplochu) ptáka na náhodné pozici. Můete měnit také sklon ptáka pozor

    vak, aby neletěl hlavou dolů.5. Pomocí elví grafiky vykreslete osmičku (dvě krunice nad sebou).

    Úkol řete pro různé počáteční pozice elvy v osmičce viz červenákolečka na obrázku. Pokuste se vykreslit osmičku také naleato.

    6. Vytvořte program, který po stisku tlačítka vykreslí rozkvetlou loukus deseti náhodně rozmístěnými květy. Při vykreslování květů vyjdětez příkladu 3.3.3, počet lupínků jednotlivých květů můete generovatnáhodně.

    7. Vykreslete spirálu z příkladu 3.3.4 barevně dvě sloky RGB paletyfixujte, jednu sloku měňte se změnou proměnné FOR-cyklu.

    8. Vytvořte program, kterýpomocí objektu elva vykreslí po stisku tlačítka 3,5, 10 nebo jiný počet čtverců stejnoměrně dokruhu (viz obrázek). Upravte program tak, aby semísto čtverců vykreslovali trojúhelníky. Jak sezmění výsledný obrazec?

  • 9. Pomocí objektu elva vykreslete následující ornament:

    10. Nakreslete graf funkce f(x) = sin(x) tak, e jedna elva bude chodit po krunici a druhábude přebírat její y-ovou souřadnici a x-ovou bude rovnoměrně zvyovat (viz obrázek).Pro větí názornost můou elvy své cesty vykreslit barevně.

    11. Pomocí objektu elva vykreslete mrak. Obvod mrakutvoří půlkrunice stejnoměrně rozmístěné po kruhu. Mrakvybarvěte vhodnou barvou příkazem elví grafiky.12. Vygenerujte tři elvy na grafickou plochu a vytvořte

    program, ve kterém tyto elvy budou kreslit následovně: jedna spirálu do čtverce, druháspirálu do trojúhelníku a třetí bude kráčet po spirále sem a tam. Kadá elva kreslí jinoubarvou a jinou tlouťkou pera, kadá začíná v jiné části grafické plochy, aby si při kresleníco nejméně zavazeli.

  • 4 Podmínky podmíněný cyklus a podmíněný příkaz

    Prozatím jsme se seznámili s objektem elva. Naučili jsme se deklarovat číselnéproměnné (celá a reálná čísla) a přiřazovat jim hodnoty. Seznámili jsme se s FOR-cyklem anaučili se ho vyuívat při kreslení jednoduchých grafických objektů.

    Vytvářené grafické objekty sestávaly z jednoduchých geometrických útvarů čtverec,trojúhelník, krunice apod. Tyto jsme různě natáčeli, posouvali a překreslovali. Snad jste zdetaké přili na mylenku definovat pro tyto jednoduché útvary příkazy, kterým by se elva nagrafické ploe doučila. Mohla by je vyuívat při kreslení dalích objektů.

    V této kapitole si ukáeme, jak toto provést. Zavedeme pojem podprogramu, naučíme sedeklarovat a volat procedury. Předtím se ale naučíme definovat podmínky, které vyuijemev deklaraci podmíněných cyklů a pro řízení pohybu elvy při jejich náhodných procházkáchpo grafické ploe.

    4.1 Podmíněný cyklusFOR-cyklus, s kterým jsme a doposud pracovali, opakoval posloupnost příkazů (tělo

    cyklu) podle hodnoty proměnné cyklu. Podle počátečné a koncové hodnoty proměnné cyklujsme předem věděli, kolikrát se tělo cyklu zopakuje. To bylo za jistých okolností výhodné.

    V jiných situacích se vak můe stát, e potřebujeme opakovat tělo cyklu pouze přisplnění jisté podmínky. Pokud tato podmínka přestane platit, tělo cyklu by se ji neměloopakovat. Počet opakování těla cyklu zde není pevně určen a dokonce nemusí být ani shoraohraničen (nemusíme znát maximální počet opakování těla cyklu). V takových případechnevystačíme pouze s FOR-cyklem.

    Příklad 4.1.1:Následující program vykreslí hvězdu do spirály.procedure TForm1.Button1Click(Sender:

    TObject);var z: TZelva; d: Integer;begin z:=TZelva.Create; z.movexy(250,200); d:=5; while d

  • Pokud je podmínka v deklaraci WHILE-cyklu nepravdivá ji při prvním testování, tělocyklu se nevykoná ani jednou. Pokud je tato podmínka pravdivá vdy, cyklus nikdy neskončí takový cyklus nazýváme nekonečný cyklus.

    Úkol k textu 4.1.1:iV příkladu 4.1.1 není pouití WHILE-cyklus nutné. Pokuste se přepsat uvedené řeení pomocíFOR-cyklu. Vylaďte program tak, aby počet opakování těla cyklu byl v obou příkladechstejný.

    Podmínky v deklaraci WHILE-cyklu jsou logické výrazy. Jak bylo ji uvedeno, mohoubýt pro dané hodnoty pouitých proměnných buď pravdivé nabývají pravdivostí hodnotytrue (pravda) nebo nepravdivé pak nabývají pravdivostní hodnoty false (nepravda).

    Při definici podmínek můeme vyuít aritmetické, logické a relační operátory, přičemdbáme priority jednotlivých operátorů:- největí prioritu má unární operátor not (negace),- následují multiplikativní operátory * (násobení), / (dělení), div (celočíselné dělení), mod

    (zbytek po celočíselném dělení) a and (logická spojka a),- aditivní operátory + (sčítání), - (odčítání) a or (logické spojka nebo),- nejnií prioritu mají relační operátory =, =, (uvádíme zápis jednotlivých

    relačních operátorů jak je pouíváme při zápisu programů).Naznačenou prioritu jednotlivých operací můeme ovlivnit vhodným uzávorkováním

    jednotlivých částí podmínek pomocí kulatých závorek ( ) jiné typy závorek při konstrukcipodmínek a výrazů nepouíváme (jsou vyhrazeny pro jiné účely).

    Příklad 4.1.2:Podmínku x < 50 or x >= 100 vyhodnotíme podle naznačených priorit tak, e nejprvevyhodnotíme výraz 50 or x. Jeho výsledek srovnáme s x (zda je větí) a získanou hodnotuporovnáme s číslem 100.Protoe toto řeení je moné a odpovídá naznačené prioritě operací, Delphi neohlásí chybu.Přesto jsme tento výraz sestavili pravděpodobně s jiným úmyslem, který programovémuprostředí Delphi předáme vhodným uzávorkováním daného výrazu: (x < 50) or (x >= 100).

    Příklad 4.1.3:iUpravíme řeení příkladu 4.1.1 tak, aby vykreslované spirálovité útvary měly pokadé jinýtvar budeme náhodně měnit úhel pohybu elvy. Aby nám elva neutekla z grafické plochy,upravíme zároveň podmínku ukončení WHILE-cyklu.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; i, d, u: Integer;begin z:=TZelva.Create; z.Smaz; z.movexy(250,200); d:=5; u:=90+random(100); // náhodné úhly v rozmezí 90° a 189° while sqrt(sqr(z.X-250)+sqr(z.Y-200))

  • endend;

    Abychom se vyhnuli příli malým úhlům, při kterých by vykreslený objekt mohl být málozajímavý, generujeme velikost úhlů příkazem u:=90+random(100). Tím dostáváme náhodnáčísla v rozmezí 90° a 189°.

    Podmínka, která nyní omezuje vykonávání WHILE-cyklu vyjadřuje potřebu, abyvzdálenost aktuální pozice elvy (bodu [z.X, z.Y]) od bodu [250, 200] (přibliného středugrafické plochy) byla mení ne 200:

    Srovnáním uvedeného vzorce s jeho zápisem v programu (viz příklad) zjistíme, e druhéodmocnině odpovídá funkce sqrt a druhé mocnině funkce sqr. U obou funkcí uvádímev závorce hodnotu, z ní má být výsledek vypočítán.

    Objekt elva má pro výpočet vzdálenosti vlastní prostředky s jejich pomocí můemepodmínku ve WHILE-cyklu upravit na while z.vzdal(250, 200) < 200 do. Vyzkouejtenavrhovanou úpravu.

    4.2 Podmíněný příkazPodmíněné příkazy (jejich smysl a pouití) si přiblííme na náhodných procházkách.

    elvu necháme donekonečna procházet se po grafické ploe: v kadém bodu své cesty sielva náhodně vybere směr, kterým vykoná nejblií krátký krok (viz příklad).

    Příklad 4.2.1:Náhodná procházka.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; while true do begin z.vpravo(random(360)); z.vpred(5); Cekej(1); endend;

    Pokud jste se pokusili uvedený program spustit, moná jste byli překvapeni, e neeluzavřít kříkem na litě vpravo nahoře. WHILE-cyklus pouitý v příkladu má v podmínceuvedeno pouze slovo true, a tedy podmínka je vdy splněna. Jedná se o nekonečný cyklus.Přeruení takovéhoto programu je moné pouze z programového prostředí Delphi stiskemkombinace kláves Ctrl-F2 nebo násilným přeruením běhu programu (restartem počítače).

    Abychom se vyhnuli problémům s ukončováním aplikace, umístíme na plochu formulářetlačítko pro ukončení programu. Aplikaci ukončíme příkazem halt, který násilně přeruívechny běící procesy a aplikaci přeruí. Takovéto ukončení ve sluných aplikacíchnepouíváme, nebo pouze výjimečně. Od této zásady upustíme pouze pro nae potřebynáhodných procházek.

    procedure TForm1.Button2Click(Sender: TObject);begin Haltend;

    ( ) ( ) 200200.250. 22

  • Pokud jste chvíli sledovali náhodnou procházku elvy, nakonec Vám z grafické plochyunikla a ji se nevrátila. Dále se pokusíme omezit prostor pro pohyb elvy pouze na vhodnéčásti grafické plochy. Pouijeme k tomu podmíněný příkaz if (má dvě varianty, pouijemezatím pouze tu jednoduí):

    if podmínka then vnořený_příkazPodobně jako ve WHILE-cyklu: Je-li podmínka splněna, vykoná se vnořený příkaz.

    Pokud by podmínka splněna nebyla, vnořený příkaz se nevykoná a vykonávání programupokračuje za vnořeným příkazem. Vnořený příkaz můe být uzavřen mezi begin a end.

    Příklad 4.2.2:Náhodná procházka v ní se elva nevzdálí od bodu [250, 200] (z kterého vychází) o více ne50 kroků. V opačném případě se vrátí zpět.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; z.moveto(250, 200); while true do begin z.vpravo(random(360)); z.vpred(5); if z.vzdal(250, 200)>50 then z.vpred(-5); Cekej(1); endend;

    Protoe mnoina bodů, jejich vzdálenost od bodu [250, 200] je mení nebo rovna 50,tvoří kruh, vyplní postupně při své náhodné procházce elva právě tento prostor (viz obrázek).

    Úkol k testu 4.2.1:Podmínky v podmíněném příkazu mohou být i komplikovanějí. Uvedeme několik příkladů: kosočtverec se středem v bodě [250, 200]:

    if abs(z.X-250)+abs(z.Y-200) > 100 then z.vpred(-5);

    obdélník se středem v bodě [250, 200] a stranami 2*70 a 2*50:if (abs(z.X-250) > 70) or (abs(z.Y-200) > 50) then z.vpred(-5);

    sněhulák jako sjednocení tří krunic:if (z.vzdal(250, 350) > 100) and (z.vzdal(250, 190) > 80) and(z.vzdal(250,60) > 60) then z.vpred(-5);

    Vyzkouejte uvedené podmínky a pozorujte plochy, které vyplní elva náhodnou procházkou.

    Poznámka 4.2.1:Příkaz Cekej(1) je v programu nezbytný. Pokud bychom ho vyhodili, aplikaci by se námnepodařilo zastavit ani příkazem halt (k vykonání příkazu halt by vůbec nemohlo dojít).Abychom urychlili náhodnou procházku elvy, můeme omezit počet volání příkazu Cekej.To můeme udělat například tak, e v jisté proměnné budeme počítat počet přechodůWHILE-cyklu a příkaz Cekej zavoláme pouze pokud tato hodnota bude dělitelná tisíci. Jinámonost je náhodně generovat čísla v rozmezí 0-999 a příkaz Cekej zavolat pokudvygenerujeme jedničku. Účinek bude stejný jako v prvním případě, program vak zde budejednoduí. Příkaz Cekej tedy v programu nahradíme příkazem:

    if random(1000)=1 then Cekej(1);

  • Příklad 4.2.3:Náhodnou procházkou vyplníme plochu ve tvaru měsíce.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; z.movexy(300, 200); z.vypln(clBlue); // modré pozadí z.PC:=clYellow; // lutý měsíc while true do begin z.vpravo(random(360)); z.vpred(5); if (z.vzdal(250, 200) > 100) or (z.vzdal(150, 200) < 100) then

    z.vpred(-5); if random(1000)=1 then Cekej(1); endend;

    4.3 Výběr z více monostíProzatím jsme se seznámili s podmíněným příkazem pouze v jeho jednoduí variantě

    if podmínka then vnořený_příkaz1;(je-li podmínka splněna, vykoná se vnořený příkaz 1, v opačném případě se pokračujevykonáváním příkazů za podmíněným příkazem).

    Mají-li se některé příkazy vykonat v případě, e podmínka podmíněného příkazu neplatí,můeme uvedenou konstrukci upravit následovně:

    if not podmínka then vnořený_příkaz2;(není-li podmínka splněna, vykoná se vnořený příkaz 2).

    Obě uvedené konstrukce můeme spojit v moné variantě podmíněného příkazuif podmínka then vnořený_příkaz1else vnořený_příkaz2;

    Je-li podmínka podmíněného příkazu splněna, vykoná se vnořený příkaz 1, jinak (slovo else)se vykoná vnořený příkaz 2. Takovýto podmíněný příkaz nabízí výběr ze dvou moností:pokud podmínka platí a pokud podmínka neplatí. Vyuití předvedeme na příkladu.

    Upozornění 4.3.1:Před slovem else středník nedáváme!!! Pokud bychom za vnořený příkaz 1 dali středník,předpokládá se ukončení podmíněného příkazu (bez části else). Část za else ztrácí v programusmysl a programové prostředí Delphi ohlásí chybu.

    Příklad 4.3.1:elva se bude náhodně procházet v kruhu. Barva jejího pera sebude měnit podle její vzdálenosti od středu kruhu do polovinybude lutá, od poloviny červená.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz;

  • z.movexy(200,200); z.PC:=clYellow; while true do begin z.vpravo(random(360)); z.vpred(5); if z.vzdal(200,200)>100 then z.vpred(-5); if z.vzdal(200,200) 100 then z.vpred(-5)) nepustíelvu za hranice kruhového prostoru (střed kruhu je v bodě [200, 200], poloměr kruhu je 100).Druhý podmíněný příkaz mění barvu pera elvy podle její vzdálenosti od středu kruhu pokud se elva nachází ve vnitřním kruhu (poloměr vnitřního kruhu je 50), je barva pera lutá,ve vnějím kruhu elva kreslí červenou barvou.

    Příklad 4.3.2:Upravíme program z příkladu 4.3.1 tak, vznikly tři soustředné kruhy vnějí zelený,prostřední lutý a vnitřní červený (výběr ze tří moností barvy pera).

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; z.movexy(200,200); z.PC:=clRed; while true do begin z.vpravo(random(360)); z.vpred(5); if z.vzdal(200, 200)>100 then z.vpred(-5); if z.vzdal(200, 200) < 30 then z.PC:=clRed else if z.vzdal(200,200) < 70 then z.PC:=clYellow else z.PC:=clLime; if random(1000)=1 then Cekej(1); endend;

    Pokud chceme pouít výběr ze tří moností, pouijeme dva podmíněné cykly vnořené dosebe (viz řeení příkladu).

    Úkol k textu 4.3.1:Upravte řeení příkladu 4.3.2 tak, aby vznikly čtyři soustředné kruhy vybarvené střídavěčervenou a lutou barvou. Kolik podmíněných cyklů pouijete? Lze tento počet zmenit?Pokud ano, navrhněte způsob řeení.

    Příklad 4.3.3:Upravíme program z příkladu 4.3.1 tak, aby vzniklo desetsoustředních kruhů v barvách duhy.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; z.movexy(200,200); z.PC:=clRed;

  • while true do begin z.vpravo(random(360)); z.vpred(5); if z.vzdal(200, 200)>100 then z.vpred(-5); if z.vzdal(200, 200) < 10 then z.PC:=clRed else if z.vzdal(200, 200) < 20 then z.PC:=RGB(255,150,0) else if z.vzdal(200, 200) < 30 then z.PC:=clYellow else if z.vzdal(200, 200) < 40 then z.PC:=clLime else if z.vzdal(200, 200) < 50 then z.PC:=clGreen else if z.vzdal(200, 200) < 60 then z.PC:=RGB(0,255,255) else if z.vzdal(200, 200) < 70 then z.PC:=RGB(0,150,255) else if z.vzdal(200, 200) < 80 then z.PC:=clBlue else if z.vzdal(200, 200)< 90 then z.PC:=RGB(255,0,255) else z.PC:=clRed; if random(1000)=1 then Cekej(1); endend;

    V tomto případě jsme museli pouít ji devět do sebe vnořených podmíněných příkazů.Program tím ztrácí přehlednost. Rovně vzdálenost aktuální pozice elvy od středu kruhu sevyčísluje i několikrát (podle velikosti této vzdálenosti).

    Uvádíme elegantnějí způsob řeení daného příkladu pomocí příkazu case. Tento příkazumoňuje podle nějaké hodnoty vykonat jeden z moných alternativních příkazů (nebo takéádný alternativní příkaz).

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;begin z:=TZelva.Create; z.Smaz; z.movexy(200,200); z.PC:=clRed; while true do begin z.vpravo(random(360)); z.vpred(5); if z.vzdal(200, 200) > 100 then z.vpred(-5); case Round(z.vzdal(200,200)) div 10 of 1 : z.PC:=RGB(255,150,0); 2 : z.PC:=clYellow; 3 : z.PC:=clLime; 4 : z.PC:=clGreen; 5 : z.PC:=RGB(0,255,255); 6 : z.PC:=RGB(0,150,255); 7 : z.PC:=clBlue; 8 : z.PC:=RGB(255,0,255) else z.PC:=clRed end; if random(1000)=1 then Cekej(1); endend;

  • Výraz Round(z.vzdal(200,200)) div 10 určuje pořadí daného mezikruí. Kruh nejvícvevnitř (s poloměrem 10) má číslo 0, vnějí kruh má číslo 9. Kruhy nejvíc vevnitř a nejvíc vnějsou vybarveny červenou barvou, kterou nastavujeme peru elvy v monosti else (jinak).

    Obecní tvar příkazu case:case výraz of konstanta1: příkaz1; konstanta2: příkaz2; ... konstantaN: příkazN else příkazy;end;

    Podle hodnoty výraz rovnající se konstatnta1, konstatnta2, se vykoná jedenz alternativních příkazů příkaz1, příkaz2, Příkazy za slovem else se vykonajív případě, e výraz nenabývá ádnou z hodnot konstatnta1, konstatnta2, Část elsemůe v příkazu chybět. Samostatný výraz i hodnoty vech konstant konstatnta1,konstatnta2, musí být celočíselného typu (později uvidíme, e mohou být i jiných typů).

    Cvičení:1. Naprogramujte náhodnou procházku tři elv. Vechny se

    budou pohybovat ve stejném kruhu o poloměru 50. elvybudou mít tlusté pero s barvami lutou, červenou a modrou.

    2. Upravte program (viz příklad 4.2.3) pro vykreslení měsíce tak,e zobrazíte i tu část měsíce, která není osvětlena (viz obrázek).

    3. Naprogramujte pomocí náhodné procházky jedné elvy kří (dvaobdélníky zkříené přes sebe).

    4. Naprogramujte pomocí náhodné procházky jednéelvy květinu (viz obrázek). lutý (barva clYellow)středový kruh má střed v bodě [200, 200], červenékruhy (barva clRed) mají středy v bodech [120, 200],[240, 130], [240, 270] a růové kruhy (barvaRGB(255, 204, 255)) mají středy v bodech[280, 200], [160, 130], [160, 270]. Vechny kruhymají poloměr 50. Dbejte na vhodné překrývání kruhů.

  • 5. Pomocí náhodné procházky jedné elvyvykreslete olympijské kruhy.

    6. Zjistěte vzhled vlajek jednotlivých států. Vykreslete některé z vlajek pomocí náhodnéprocházky jedné elvy. Pod vlajku připite název státu, jemu vlajka náleí.

    7. Definovali jsme podmínky pro vykreslování nejrůznějích obrazců pomocí náhodnýchprocházek. Vyberte si pět z těchto podmínek (obrázků) a pomocí příkazu case vykresletepo stisku tlačítka náhodně jeden z nich vygenerujte náhodně číslo od 1 do 5 a vykresletepřísluný tvar. Při opětovném stisku tlačítka se vykreslí jiný z pěti tvarů.

  • 5 Podprogramy - procedury a funkce

    Prozatím jsme vytvářeli větinou pouze jednoduché krátké programy, jejich rozsahnepřesáhl 10-20 řádků. Pokud některý z Vámi vytvářených programů přesahoval tento rozsah,stával se nepřehledným, těko se v něm nacházely a opravovaly chyby. Snad jste v tétosouvislosti uvaovali o monosti rozdělit program na mení, přehlednějí části. Těmto částemse říká podprogramy. Jejich deklaraci a vyuití je věnována tato kapitola.

    Podprogramy jsou části programu, jen mají své jméno, pomocí kterého je můemezavolat. Podprogramy nám umoňují řeit problém jeho rozdělením na dílčí podúlohy v tétosouvislosti hovoříme o programování shora dolů. Podprogramy v Pascalu mohou být dvoutypů: procedury posloupností příkazů, funkce posloupnosti příkazů, jejich výsledkem je nějaké hodnota.Podprogramy vyuijeme tehdy, kdy: nějakou část programu chceme kvůli přehlednosti a logice algoritmu vytáhnout do

    samostatné části mimo vlastní program program se zpřehlední, lehčeji ho odladíme, se nějaká část programu víckrát opakuje na různých místech (není myleno pouze v cyklu)

    definovaný podprogram zavoláme jeho jménem z různých části vlastního programu, nějakou část programu naprogramoval někdo jiný podprogram ke své práci připojíme a

    ve vhodný okamik jej zavoláme jeho jménem, pouijeme rekurzivní volání (bude vysvětleno později).

    5.1 Deklarace procedurObecný tvar deklarace procedury:

    procedure jméno;

    ... // lokální deklarace proměnných náleících proceduřebegin

    ... // tělo proceduryend;

    Při deklaraci procedur platí následující pravidla: procedura má své jméno, které podobně jako pojmenování proměnné sestává z písmen

    abecedy bez diakritiky a číslic (číslice nesmí být na prvním místě), hlavička procedury začíná slovem procedure, za kterým následuje jméno procedury

    (například procedure ctverec;), za hlavičkou procedury následují deklarace lokálních proměnných, tj. takových

    proměnných, které se pouívají pouze v dané proceduře, tělo procedury mezi begin a end obsahuje příkazy procedury.Deklaraci a volání procedury předvedeme na konkrétním příkladu. Deklarujeme proceduructverec, pomocí které vykreslíme čtyři čtverce.

    Příklad 5.1.1:Proceduru ctverec deklarujeme vevnitř procedury TForm1.Button1Click. Vimněte si, eproměnnou pro elvu deklarujeme jetě před deklaraci procedury ctverec, která pak elvuvyuívá pro vyreslení.

  • procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;

    procedure ctverec; var i: Integer; begin for i:=1 to 4 do begin z.vpred(100); z.vpravo(90); end end;

    begin z:=TZelva.Create; z.movexy(100, 150); ctverec; // *** z.movexy(210, 150); ctverec; z.movexy(100, 260); ctverec; z.movexy(210, 260); ctverec;end;

    Proceduru ctverec jsme deklarovali pouze jednou a pouili (volali) čtyřikrát. Postup prácepočítače při volání procedury (viz například řádek označený v poznámce ***) je následující: počítač si zapamatuje návratovou adresu místo volání procedury a místo, kam se po

    jejím vykonání počítač opět vrátí, vytvoří se místo v paměti pro lokální proměnné (ty zatím nemají definovanou hodnotu) a

    pro formální parametry (jak uvidíme později), řízení programu se převede do těla procedury za přísluné begin, vykoná se tělo procedury vechny příkazy a po přísluné end, zruí se vechny lokální proměnné (vymaou se z paměti) a vechny formální parametry

    (jak bude vysvětleno později), řízení programu se vrátí na místo návratové adresy, vykonávání programu následuje

    příkazem za příkazem volání procedury.Důleité je rovně si uvědomit vnoření jednotlivých procedur do sebe a rozsah platnosti

    procedur a proměnných definovaných v programu. Zde platí následující pravidla: Proměnné deklarované v procedurách mají platnost pouze v dané proceduře nazýváme

    je lokální proměnné.Například proměnná i (viz příklad 5.1.1) platí pouze v proceduře ctverec. Proměnnáz (typu TZelva) platí v celé proceduře TForm1.Button1Click. Procedura ctverec je do nívnořena, a tedy proměnná z platí i v této proceduře.Pokud bychom deklarovali v proceduře ctverec proměnnou z (typu TZelva), program byvypsal chybové hláení. Příkazy, pouité v této proceduře pro práci se elvou, počítajís deklarovanou lokální elvou, která vak zde nebyla vytvořena (příkazemz:=TZelva.Create), tudí se nemůe posunout vpřed ani otočit vpravo.

    Proměnné a procedury můeme pouít pouze tehdy, byli-li předtím zadeklamovány.Proměnnou z (viz příklad 5.1.1) bychom nemohli v proceduře ctverec pouít, pokud bynebyla deklarována před touto procedurou.

    Standardní deklarace (standardní typy, procedury, funkce, které programová prostředíDelphi nabízí) jsou pro program deklarovány jetě před jeho začátkem. Říkáme, e jsoudeklarovány na 0. úrovni. Na této úrovni je pro nae programy deklarován i celý objektelva. Tyto deklarace nazýváme globální deklarace.

  • Formulář a vechny procedury formuláře (procedury označené typem formuláře TForm1)jsou na 1. úrovni. Procedura ctverec a proměnná z jsou deklarovány na 2. úrovni,proměnná i procedury ctverec je deklarována a na 3. úrovni.

    Proměnné a procedury deklarované na vyích úrovních (na úrovních s niím číslem)jsou viditelné a pouitelné v procedurách deklarovaných na niích úrovních. Proměnnéa procedury deklarované na vyích úrovních nazýváme globální proměnné, resp.globální procedury.

    Pouívání globálních proměnných a procedur se snaíme minimalizovat z důvodůminimalizace pouité paměti, kvůli přehlednosti programového kódu, pro vyínezávislost procedur (zapouzdření) od ostatního programového kódu apod.

    Příklad 5.1.2:Vraťme se jetě jednou k příkladu 5.1.1. Strana vykreslovaného čtverce je v tomto případěkonstantní, rovna 100. Pokud bychom měnit délku strany čtverce, museli bychom pro tentoparametr pouít globální proměnnou (vzhledem k proceduře ctverec).

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva; d: Integer;

    procedure ctverec; var i: Integer; begin for i:=1 to 4 do begin z.vpred(d); z.vpravo(90); end end;

    begin z:=TZelva.Create; z.movexy(100, 150); d:=100; ctverec; z.movexy(210, 150); d:=70; ctverec; z.movexy(100, 260); d:=80; ctverec; z.movexy(210, 260); d:=90; ctverec;end;

    5.2 Formální parametryAbychom nemuseli pouívat globální proměnné (například pro určení velikosti strany

    čtverce v příkladu 5.1.2), jejich pouívání se snaíme minimalizovat, můeme při voláníposílat podprogramu nějaké hodnoty pomocí tzv. formálních parametrů. Situacipředvedeme nejprve na příkladu.

    Příklad 5.2.1:Různě velké čtverce z příkladu 5.1.2 vykreslíme pomocí procedury, které předáme délkustrany čtverce pomocí formálního parametru.

    procedure TForm1.Button1Click(Sender: TObject);var z: TZelva;

    procedure ctverec(d: Integer); var i: Integer; begin

  • for i:=1 to 4 do begin z.vpred(d); z.vpravo(90); end end;

    var j: Integer;begin z:=TZelva.Create; for j:=1 to 24 do begin ctverec(j*5); z.vlevo(360/24); Cekej(1000) endend;

    Formální parametry procedury definujeme v závorce za názvem procedury. Zde kroměpojmenování formálního parametru uvádíme i jeho typ viz hlavička procedury procedurectverec(d: Integer);

    Parametr d procedury ctverec je pouze formálním (zástupným) parametrem. Jeho hodnotanení známa při spoutění programu. Formálnímu parametru se přiřazuje hodnota a přivolání podprogramu! Tento parametr se vytvoří a při volání podprogramu (podobně jakolokální proměnné) a přiřadí se mu hodnota odpovídajícího výrazu (v naem případě j*5).Formální parametry jsou v těle podprogramu (procedury) obyčejnými lokálními proměnnými,jen mají na začátku procedury (slovo begin) inicializovanou hodnotu podle skutečnéhoparametru, podle hodnoty odpovídajícího výrazu ve volání procedury.

    Formální parametr je pouze zástupnou proměnnou skutečného parametru (výrazu vevolání procedury). V těle procedury odpovídá formální parametr svým postavením lokálnímproměnným. Procedura můe mít i více formálních parametrů.

    Příklad 5.2.2:Na grafické ploe vytvoříme dvěelvy, které se budou pohybovat pokrunicích (kadá jinou rychlostí, pokrunici s jiným poloměrem). Třetíelvu vytvoříme uprostřed mezi nimi.Třetí elva se bude neustále snait býtmezi zbývajícími dvěma přesněuprostřed úsečky vymezené prvnímidvěmi elvami. Pro výpočet středuúsečky pouijete proceduru.

    procedure TForm1.Button1Click(Sender: TObject);var z1, z2, z3: TZelva; b1, b2: Integer; // barva pera elvy z1 a z2 x, y: Real;

    procedure UrciStred; // souřadnice středu úsečky mezi z1 a z2 begin x:=(z1.X+z2.X)/2; y:=(z1.Y+z2.Y)/2; end;

  • begin z1:=TZelva.Create; z1.movexy(200,200); b1:=0; z2:=TZelva.Create; z2.movexy(300,200); b2:=0; z3:=TZelva.Create; z3.PC:=clRed; UrciStred; z3.movexy(x,y); while true do begin z1.vpred(4); z1.vlevo(3); // pohyb elvy z1 if Round(z1.H)=90 then begin b1:=150-b1; z1.PC:=RGB(b1, b1, b1) end; z2.vpred(3); z2.vpravo(2); // pohyb elvy z2 if Round(z2.H)=90 then begin b2:=150-b2; z2.PC:=RGB(b2, b2, b2) end; UrciStred; z3.setxy(x,y); // pohyb elvy z3 Cekej(10); end;end;

    Proměnné b1 a b2 slouí ke změně barvy pera elv z1 a z2 tak, aby bylo mono lépesledovat jejich pohyb elvy po oběhnutí krunice mění barvu pera z černé na edou anaopak. V dalích úpravách programu tyto proměnné nebudeme pouívat.

    Úkol k textu 5.2.1:Podle uvedeného programu vykreslí prostřední elva maličkovou pěticípou hvězdu (vizobrázek). Změnou úhlů otáčení elv z1 a z2 se mění i obrazec vykreslený prostřední elvou.Vyzkouejte moné změny.Upravte program z příkladu 5.2.2 tak, aby elvy, jdoucí po krunicích, li obě stejnýmsměrem. Jak se v tomto případě změní dráha třetí elvy?

    Procedura UrciStred vyuívá proměnné z1, z2, x, y, které nejsou deklarovány v tétoproceduře (nejsou lokálními proměnnými procedury). Tyto proměnné jsou pro proceduruUrciStred globální. Pouití globálních proměnných nemusí být vdy moné a optimální dané globální proměnné se budeme snait z programu odstranit.

    procedure TForm1.Button1Click(Sender: TObject);

    procedure UrciStred(z1, z2: TZelva; xx, yy: Integer); begin xy:=(z1.X+z2.X)/2; yy:=(z1.Y+z2.Y)/2; end;

    var z1, z2, z3: TZelva; x, y: Real;begin z1:=TZelva.Create; z1.movexy(200,200); z2:=TZelva.Create; z2.movexy(300,200); z3:=TZelva.Create; z3.PC:=clRed; UrciStred; z3.movexy(x,y); while true do begin z1.vpred(4); z1.vlevo(3); z2.vpred(3); z2.vpravo(2); UrciStred(z1, z2, x, y); z3.setxy(x,y); Cekej(10); end;end;

  • Vyzkouíte-li takto zapsaný program zjistíte, e nebude fungovat. Pouití formálníchparametrů z1 a z2 je v pořádku tyto proměnné pouíváme v proceduře UrciStred pouze pročtení x-ové a y-ové souřadnice aktuální polohy elvy, tedy pouze jako lokální proměnné.

    Proměnné xx a yy jsou v uvedené deklaraci rovně pouze lokální proměnné proceduryUrciStred. Hodnoty těchto proměnných bychom vak potřebovali po skončení proceduryUrciStred přiřadit proměnných x a y pro nastavení aktuální pozice elvy z3.

    Zde ji nevystačíme s formálními parametry tak, jak jsme se s nimi seznámili doposud.V proceduře UrciStred musíme pouít tzv. var parametry:

    procedure UrciStred(z1, z2: TZelva; var xx, yy: Integer);begin xy:=(z1.X+z2.X)/2; yy:=(z1.Y+z2.Y)/2;end;

    Tři typy formálních parametrů v PascaluPodle monosti přístupu k parametrů procedury rozeznáváme následující typy parametrů: Hodnotové parametry volání hodnotou umoňují přístup pouze k duplikátu

    skutečného parametru. Při volání procedury se hodnotové parametry vytvoří (podobnějako lokální proměnné) a jejich hodnota se inicializuje podle hodnoty skutečnéhoparametru. Po skončení volané procedury jsou tyto parametry zrueny a jejich hodnotynenávratně zapomenuty.

    Proměnné parametry (var parametry) volání adresou umoňují úplný přístupk hodnotám parametrů. Proměnné parametry se při volání procedury nevytváří, jsou topouze dočasná jména skutečných parametrů. Při volání procedury musí být na místechproměnných parametrů proměnné (u nás x a y), jejich hodnoty se prostřednictvímzástupních jmen proměnných parametrů (xx a yy) mohou v průběhu procedury měnit. Poskončení procedury jsou hodnoty skutečných parametrů rovny hodnotách zástupnýchproměnných parametrů.

    Konstantní parametry (const parametry) volání konstantou umoňují přístup pouzepro čtení hodnoty skutečného parametru. Jejich hodnota se v těle procedury nemění.

    Ve vech uvedených případech se jedná o formální (zástupné) parametry. Skutečná hodnota jeparametrům přiřazena při volání procedury.

    Postup práce počítače při volání procedury můeme tedy upravit následovně: počítač si zapamatuje návratovou adresu, vytvoří se místo v paměti pro lokální proměnné:

    • opravdové lokální proměnné dostávají nedefinovanou hodnotu,• hodnotové formální parametry jsou lokální proměnné, jejich hodnota je rovna

    hodnotě skutečného parametru (duplikát),• konstantní formální parametry jsou lokální konstanty, jejich hodnota je rovna

    skutečnému parametru a tato hodnota se v průběhu procedury nemění,• proměnné formální parametry se nevytváří, jsou pouze dočasnými jmény skutečných

    parametrů, řízení programu se převede do těla procedury, vykonají se vechny příkazy těla procedury,

  • zruí se vechny lokální proměnné (vymaou se z paměti) a hodnotové a konstantníformální parametry,

    řízení programu se vrátí na místo návratové adresy, vykonávání programu následujepříkazem za příkazem volání procedury.

    Příklad 5.2.3:Proceduru UrciStred z příkladu 5.2.2pozvedneme na 1.úroveň a pohyb elvupravíme tak, e jedna se bude pohybovat pokrunici a druhá po čtverci (trojúhelníku,pěticípé hvězdě apod.). Postavení třetí elvy senemění.

    procedure UrciStred(z1, z2: TZelva; var xx, yy: Real);begin xx:=(z1.X+z2.X)/2; yy:=(z1.Y+z2.Y)/2;end;

    procedure TForm1.Button1Click(Sender: TObject);var z1, z2, z3: TZelva; x, y: Real; i: Integer;begin z1:=TZelva.Create; z1.movexy(200,200); z2:=TZelva.Create; z2.movexy(300,200); z3:=TZelva.Create; z3.PC:=clRed; UrciStred(z1,z2,x,y); z3.movexy(x,y); while true do begin for i:=1 to 30 do // zkuste jiný počet opakování: 20, 40... begin z1.vpred(4); z2.vpred(3); z2.vpravo(2); UrciStred(z1,z2,x,y); z3.Setxy(x,y); Cekej(10); end; z1.vlevo(90) // vyzkoušejte jiné úhly: 120, 144 apod. end;end;

    5.3 FunkcePomocí proměnných parametrů můeme získat hodnoty proměnných, jen byly vypočteny

    v dané proceduře. Pokud daná procedura počítá pouze jednu hodnotu (má jeden proměnnýformální parametr), je větinou výhodnějí pouít funkci.

    Příklad 5.3.1:Procedura s proměnným parametrem vracejícím hodnotu větího ze dvou čísel.

    procedure max(a,b:integer; var m:integer);begin if a>b then m:=a else m:=b