V dnešní lekci si vysvětlíme některé vlastnosti udělátka Canvas a vytvoříme si hru, ve které budeme sestřelovat letadla.
Dnes si vytvoříme hru, ve které budou donekonečna létat letadla a my je budeme muset sestřelit. Takže to dnes bude o udělátku Canvas a jeho metodách. Pro úplnost přikládám seznam všech metod a nastavení udělátka Canvas. A takto asi bude náš výtvor vypadat:
Seznam použitých metod
Tk.after(cas, akce)
Tato metoda se sice netýká udělátka Canvas, ale v našem programu bude plnit nemalou roli. Pomocí této metody můžete za určitý čas zavolat funkci:
okno.after(1000, funkce)
Pozor, čas se zadává v milisekundách.
Canvas.move(objekt, x,y)
Posune objekt na plátně o x a y souřadnicí.
self.platno.move(objekt,20,0)#pohne objektem o 20 pixelů doprava
self.platno.move(objekt,−5,5)#pohne objektem o 5 pixelů doleva a o 5 pixelů dolů
Canvas.create_image(x,y,obrázek,tags=())
Vytvoří obrázek na souřadnicích x a y.
self.obr=PhotoImage(file="ufo.gif")#nebo se dá použít modul PIL
self.platno.create_image(10,10,image=self.obr)
Canvas.coords(objekt)
Tato funkce umožňuje přesunout nějaký objekt na vámi zadané souřadnice, nebo získat aktuální souřadnice objektu:objekt=self.platno.create_rectangle(10,10,20,20,fill="red")
print self.platno.coords(objekt)#vytiskne souřadnice objektu.
self.platno.coords(objekt,20,20,30,30)#posune objekt.
Canvas.find_withtag(ukazatel)
Najde všechny prvky obsahující daný identifikátor prvku. Identifikátor může být buď jméno některého tagu, nebo speciální parametr CURRENT. Pokud tento parametr využijete, vrací metoda prvek na plátně nejblíže myši.
Canvas.tag_bind(jméno, akce, funkce)
Sváže plátno s nějakou akcí. A protože těch různých akcí, které by se měly stát například při kliknutí, může být více, poskytuje tato metoda také parametr jméno. Pro parametr akce platí stejné akce, jako když použijete bind.
Samotný program
Nejprve bychom si měli vytvořit hrací plochu. A abychom nemuseli používat anglického slova canvas, budeme mu říkat plátno.
class Plocha:
def __init__(self,parent):
self.sirka=640
self.vyska=480
self.body=0
self.platno=Canvas(parent, bg="black", width=self.sirka, height=self.vyska)
self.platno.pack()
self.seznam_objektu=[]
self.obr=PhotoImage(file="ufo.gif")
if __name__=="__main__":
root=Tk()
Plocha(root)
root.mainloop()
Proměnné sirka, vyska určují velikost okna. Do seznamu self.seznam_objektu budeme přidávat letadla, abychom s nimi pak mohli pohybovat. Dále by to chtělo vytvořit nějaký štítek, kam budeme moci zaznamenávat počet úspěšných zásahů. K tomu bych použil udělátko Label.
Pohyb objektem
Nyní můžeme přistoupit k funkci, která nám bude vytvářet letadýlka. Fotku letadýlka si samozřejmě můžete stáhnout . Obrázek je ve tvaru gif, ale můžete ho samozřejmě nahradit nějakým jiným. Za předpokladu, že chcete použít jiný formát než GIF, budete muset použít knihovnu PIL.
def vytvor_objekt(self,x,y):
objekt=self.platno.create_image(x,y,image=self.obr)
self.seznam_objektu.append(objekt)
Přičemž x bude vždy 0 a y bude číslo náhodně generované z intervalu (0,výška plátna).
Teď můžeme vytvořit libovolné množství letadýlek, ale stále se nehýbou. K pohybu objektu na plátně se používá metoda move(objekt,x,y). Jako parametry přijímá objekt pohyb ve směru x a pohyb ve směru y. Nám bude stačit, když se bude letadýlko pohybovat pořád ve stejné výšce, měnit se bude jenom x. Tento pohyb budeme muset opakovat každých 200 milisekund. K tomuto opakování použijeme funkci after
Ke správnému chodu našeho programu budeme muset samozřejmě vytvořit funkci pohyb. Funkce pohyb bude volat sama sebe, aby se naše letadýlko pořád pohybovalo:
def pohyb(self):
for objekt in self.seznam_objektu:
self.platno.move(objekt,10,0)
self.platno.after(200,self.pohyb)
Abychom zbytečně nevykreslovali příliš mnoho letadel, dal by se použít mechanizmus, že když letadlo opustí obrazovku, posune se opět na začátek, takže kód upravíme takto:
def pohyb(self):
for objekt in self.seznam_objektu:
self.platno.move(objekt,10,0)
x,y=self.platno.coords(objekt)#zjisti souřadnice letadla
if x > self.sirka:
self.platno.coords(objekt,-10,random.randint(0,self.vyska))
self.platno.after(200,self.pohyb)
Na čtvrtém řádku zjišťujeme polohu obrázku. Na pátém kontrolujeme, zda je obrázek mimo obrazovku, a za předpokladu, že je, posune obrázek opět na začátek.
Tak teď jsme vyřešili pohyb. Ještě bude potřeba nastavit rychlost pohybu letadla, aby se všechna nepohybovala stejně. Ale na to již jistě sami přijdete. Napovím, že by to chtělo generovat velikost x z náhodného intervalu, o kterou se objekt posune.
Teď, když jsme obrázky rozpohybovali, musíme zařídit , aby program poznal, že jsme vystřelili a trefili se. Nejprve si připravíme funkci self.klik. V této funkci přičteme počet sestřelených letadel a posuneme ho na začátek:
def klik(self,akce):
self.body=self.body+1
objekt=self.platno.find_withtag(CURRENT)
self.platno.coords(objekt,−10,random.randint(0,self.vyska))
Teď zbývá dodělat aby program poznal, kdy zavolat funkci klik. K tomu použijeme tag_bind. Do funkce __init__ po vytvoření plátna musíme přidat řádek:
self.platno.tag_bind("klik","<1>",self.klik)
Ještě musíme trochu upravit vytváření obrázku, aby obsahoval tag klik:
objekt=self.platno.create_image(x,y,image=self.obr,tags="klik")
Konečně jsme dokončili hlavní část programu. Teď stačí dodělat lištu, kde se budou znázorňovat body, a je to.
Pro vylepšení programu by se daly dodělat zvuky při střílení či změnit šipkový kurzor za nějaký vhodnější.