Návod na Python – třídy a objekty 2

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