Dokončíme nástin práce s funkcemi tím, že se pokusíme pomocí jedné funkce namalovat stejné obličeje na různých místech. Dále je na pořadu přestavba programu a práce s argumenty uvnitř funkcí.
...dokončení obličeje i funkcí
Jak jsem říkal...
To všechno byla jen odbočka. Předtím, než jsem začal o funkcích, mluvili jsme o tom, jak namalovat dvě (nebo více) tváří. Možná již tušíte, co bude následovat: ta správná věc je teď napsat funkci, která namaluje obličej. Funkce by měla přijímat argumenty, které jí budou říkat, kam obličeje v grafickém okně patří. Jakmile to budeme mít, bude namalovat 5 obličejů prostě znamenat 5x použit naší funkci, namísto 5-ti kopírování našeho programu a děláním spousty změn v každé kopii.
Takže jak by měla vypadat naše funkce na kreslení obličeje?
Musí být schopna přijmout, kam má malovat obličej, předávejme ji
tedy 2 argumenty, které jí to budou říkat. Jako například ty dva argumenty
pro move
nebo draw
. Takže nyní již víme, že naše funkce bude vypadat asi takto:
def malujOblicej(x,y):
blah blah # Cokoliv co potřebujete k malování obličeje na (x,y)
Vyplnění blah blah
bude zřejmě trochu obtížnější.
Co přesně znamenají argumenty x
a y
?
Když jsme navrhovali obličej, tak jsme si za hlavní bod vzali střed
(pamatujete? - (300,200)) a všechny ostatní jsme relativně
vztahovali k němu. Rozumný nápad tedy bude říci, že x
a y
budou souřadnice středu obličeje.
Napsáním malujOblicej(300,200)
tedy řekneme, aby se
namaloval úplně stejný obličej, jako jsme již v programu udělali.
Úkol: Pokud jste odvážní a cítíte se na to, vraťte se zpět k našemu programu a zkuste ho přeměnit na funkci. Pak ji hned otestujte. --- Pokud se na to necítíte, pokračujte ve čtení a já se vás pokusím postupem provést.
Pokud se tedy chcete pokusit udělat úkol sami, měli byste přestat číst hned teď.
Začneme tím, že opravíme program tak, aby namísto
první řádka
druhá řádka
třetí řádka
atd
jsme tam měli
def malujOblicej(x,y):
první řádka
druhá řádka
třetí řádka
atd
S úspěchem používám na odsazování Tabulátor. Označím si myší, nebo raději pomocí klávesnice Shift+šipky nahoru/dolu všechny řádky, které potřebuji, a zmáčknu klávesu Tabulátor. Pro zpětný chod používám Shift+Tab.
Nyní tedy máte funkci, která sice přijímá dva
argumenty, ale ignoruje je a maluje obličej se středem (300,200), bez
závislosti na argumentech. Zkuste si to, že říkám pravdu: zkuste funkci zavolat na konci
celého programu, například malujOblicej(100,250)
. Funkce by měla argumenty
zcela ignorovat. Takže teď to spravíme, aby byl obličej centrován na souřadnicích
(x
, y
).
Obrys obličeje
První věc, kterou jsme původně kreslili, byl kruh kolem obličeje. Ten bude asi nejjednodušší přizpůsobit naší funkci.
Původně jsme měli kruh circle(300,200,40)
. První
dva argumenty pro circle
říkají, kde má být střed
kruhu, takže bychom je měli změnit na x,y
. Poslední
argument (40
) říká, jak velký bude kruh. Všechny naše
obličeje budou mít stejnou velikost, takže ho bychom měli nechat beze
změny. (Abych nezapomněl - všechno bude snazší, pokud si budete sledovat
obličej-na-mřížce v
5. lekci.
Změněná řádka tedy bude circle(x,y,40)
.
Oči
Dále jsme malovali oči. Původně oči byly (285,310) a (315,310) a byly 15 pixelů od vodorovného středu (na každou stranu) a 10 pixelů nad středem. Tak to je docela snadné. Tady je, jak namalovat levé oko; snad přijdete sami již na to, jak namalovat pravé oko.
circle(x-15, y+10, 5)
Nos
Nos je tvořen dvěma čárami. První začíná 10 pixelů nad samotným středem obličeje a končí 10 pixelů nalevo a 10 pixelů dolu od středu. To je jednoduché.
move(x, y+10)
draw(x-10, y-10)
Druhá čára začíná tam, kde první skončila, a směřuje 10 pixelů dolů a 10 pixelů vpravo od středu obličeje. Namalování čáry nechávám na vás.
Pusa
Asi si myslíte, že tohle bude těžší, než cokoliv jiného. Ne,
skutečně nebude. Jen je třeba řádně si rozmyslet, jaké jsou všechny ty
čísla ve vztahu ke středu obličeje. Levý koncový bod byl, například, na (280,180). To je 20 pixelů
vlevo a 20 pixelů dolu od středu na (300,200), takže výsledek je
(x-20,y-20)
. Budu protivný a nechám vás samostatně vypracovat, jak přesně
opravit řádku programu, která maluje pusu. Skutečně to není těžké.
Funguje to?
Funkci otestujte. Přidejte pod ní několik řádek, např.:
malujOblicej(300,200)
malujOblicej(400,200)
malujOblicej(350,270)
a spusťte program. Vidíte tři obličeje? Nebo příšerný zmatek rozházených částí obličeje? Je tam vůbec něco?
Je důležité umístit tyto řádky pod
definici funkce malujOblicej()
, protože počítač neví co to
je malujOblicej()
, dokud si ji nepřečte.
Celý člověk
Pokud již máte dost grafiky, následující pasáž přeskočte. Pokud vás to stále ještě baví, možná by stálo za to, použít vaši funkci kreslící obličej na vytvoření funkce kreslící celého člověka.
Tady je namalován jednoduchý obrázek. Nakreslete něco podobného na
čtverečkovaný nebo milimetrový papír a použijte to pro design funkce,
která bude malovat celou osobu. Tam, kde je namalovaná hlava, byste
vlastně měli použít funkci malujOblicej()
.
Možná to bude chvíli trvat. Musíte si pořádně rozmyslet jaké
parametry předávat funkci malujOblicej()
, aby hlava a tělo
seděli pěkně na sobě. Ujistěte se, že vaše funkce fungují jak mají, a to namalováním několika
osob na různých místech obrazovky. Možná bude jednodušší začít s malováním jednoduché postavy kdekoliv
a pak ji přeměnit na funkci podobným způsobem, jako jste to udělali u
tváře.
Pár pěkných vzorů
Následující nemá nic společného s malováním postaviček. Dávám to sem pouze proto, protože si myslím, že to vypadá pěkně. Zkuste si to. Přidejte třeba barvy, náhodnou délku paprsků, jemnější dělení, ....
# -*- coding: cp1250 -*-
import livewires, math # math je modul pro matematické funkce
DELKA=150 # jak bude dlouhá čára
def hvezda(stredX, stredY): # definice funkce
for uhel in range(0,360,5): # uhel bude postupne: 0,5,10,15,....
x=DELKA*math.cos(math.radians(uhel)) # matematika 9. třídy
y=DELKA*math.sin(math.radians(uhel))
print uhel, x,y # pro kontrolu
livewires.move(stredX, stredY) # začínat vždy ze středu
livewires.draw(stredX+x,stredY+y) # to je to hlavní
livewires.sleep(0.1) # spinkej
# --------- hlavni část programu ------------------------
livewires.begin_graphics()
hvezda(200,100) # voláme funkci hvězda
livewires.sleep(1) # spinkej
livewires.end_graphics()# konči
Vše ukončíme
Možná budete chtít, aby se na konci okno, po nějaké chvíli samo zavřelo:
sleep(2) # pockej 2 sekundy
end_graphics() # okno zavri
Co dál?
- Přečtěte si funkce modulu livewires, abyste se dozvěděli více.
- Vymyslete, jak namalovat obličej a tělo v různých velikostech a/nebo na různých místech.
- Vymyslete, jak pootočit hlavu. Potom můžete namalovat scénu, ve které budou jakoby některé postavy spolu hovořit nebo jen tak postávat. Prostě cokoliv.
Úkol:
Úkol je více než zřejmý. Kdo ještě nerezignoval na posílání úkolů :-), může mi poslat svůj výtvor. Kdo z vás úkol udělá, ale nepošle, protože se bojí špatné známky nebo ostudy, je zbabělec ;-)