
Minulou část jsme končili příkladem objektových domečků v grafice TKinter. Dnes se podíváme na to, jak ve stejné grafice vytvořit pohybující se objekty a jak je spravovat.
Začněme základním grafickým oknem vytvořeným pomocí knihovny TKinter, ve kterém bude jen popisek okna, plátno a tlačítko na zavření okna:
from tkinter import *
from hra import *
hlavni_okno = Tk()
popisek = Label(hlavni_okno, text="POHYBLIVE OBJEKTY")
popisek.pack(side=TOP)
tlacitko1 = Button(hlavni_okno, text="KONEC", fg="red", command=hlavni_okno.destroy)
tlacitko1.pack(side=BOTTOM)
platno_sirka = 400
platno_vyska = 400
platno = Canvas(hlavni_okno, width=platno_sirka, height=platno_vyska)
platno.pack()
### zde budou objekty na plátně ###
platno.focus_set()
hlavni_okno.mainloop()
Nyní si vytvoříme nový soubor hra.py, do kterého si přidáme úplně abstraktní objekt, který bude rodičem všech ostatních objektů na plátně. Každý objekt bude
- mít svou aktuální pozici (atributy x a y)
- si hlídat změnu svého stavu (atribut stav a metoda zmen_stav)
- vědět, ke které hře patří (hru si nadefinujeme záhy)
- se umět vykreslit na plátno (metoda kresli):
class HObjekt:
def __init__(self, x, y, stav, hra, platno):
self.x = x
self.y = y
self.stav = stav
self.hra = hra
self.platno = platno
def zmen_stav(self):
pass
def kresli(self):
pass
Metody zmen_stav() a kresli() jsou zatím prázdné, konstruktor __init__() si jen uloží předané parametry do atributů.
Všechny objekty budeme potřebovat někde spravovat a řídit. Proto si vytvoříme další abstraktní objekt Hra. Hra si vedle výšky a šířky herního okna bude evidovat všechny objekty v poli objekty. Registrované herní objekty bude vykreslovat pomocí metody hraj, poté, co je vykreslí, sama naplánuje další volání herního cyklu za dobu rychlost v milisekundách:
class Hra:
def __init__(self, sirka, vyska, rychlost, platno):
self.sirka = sirka
self.vyska = vyska
self.objekty = []
self.platno = platno
self.rychlost = rychlost
def hraj(self):
for objekt in self.objekty:
objekt.zmen_stav()
objekt.kresli()
self.platno.after(self.rychlost, self.hraj)
Aby interakce mezi hrou a herními objekty byla dokonalá, přidáme do konstruktoru třídy HObjekt jeden řádek, kterým se objekt sám registruje do pole objektů hry:
class HObjekt:
def __init__(self, x, y, stav, hra, platno):
self.x = x
self.y = y
self.stav = stav
self.hra = hra
self.platno = platno
self.hra.objekty.append(self)
Nyní je na čase vymyslet nějaký konkrétní objekt, vezměme si například kuličku (oválek), která se bude periodicky nafukovat a praskat, říkejme jí Blob. K jejímu vykreslování a mazání z plátna použijeme další atribut obr, k tomu přidáme atribut pro barvu a velikost kuličky.
class HBlob(HObjekt):
def __init__(self, x, y, stav, hra, barva, platno):
HObjekt.__init__(self, x, y, stav, hra, platno)
self.velikost = 10
self.barva = barva
self.obr = None
def zmen_stav(self):
if self.stav <= 3:
self.stav += 1
else:
self.stav = 0
def kresli(self):
if self.obr != None:
self.platno.delete(self.obr)
self.obr = self.platno.create_oval(self.x-self.stav, self.y-self.stav, self.x+self.velikost+self.stav, self.y+self.velikost+self.stav, fill=self.barva)
A konečně přidáme už konkrétní hru, nazvěme ji BlobHra:
class BlobHra(Hra):
def __init__(self, sirka, vyska, rychlost, platno):
Hra.__init__(self, sirka, vyska, rychlost, platno)
self.blob = HBlob(sirka/2, vyska/2, 0, self, "blue", platno)
Do hlavního programu už přidáme jen dva řádky za komentář, a je hotovo:
### zde budou objekty na plátně ###
Game = BlobHra(400,300,100,platno)
Game.hraj()

Další:
- vše v Pythonu jsou objekty
- dědičnost, polymorfismus
- veřejné, chráněné a soukromé atributy, atributy objektu a třídy