Mivel az akasztófánk grafika lesz, az Akasztofa osztályunkat teljesen át kell szabnunk. A Szavak osztályunk viszont egy az egyben felhasználható az eddigi programunkból. Maga a Jatek osztály is erősen átalakul, bár nyomokban emlékeztetni fog a konzolosra.
A játék törzse a következőként fest:
if __name__=="__main__":
try:
optlist, args = getopt.getopt(sys.argv[1:], "hvf:", ["help", "version", "file="])
except getopt.GetoptError:
help()
sys.exit(2)
for opt,param in optlist:
if opt in ('-h','--help'):
help()
sys.exit(0)
elif opt in ('-v', '--version'):
print _("Hangman game %s")+VERZIO
sys.exit(0)
elif opt in ('-f','--file'):
SZOFAJL=param
j=Jatek()
j.frame.mainloop()
A --file paraméterrel továbbra is indíthatjuk saját, egyedi szó listával a játékot. A j változóban példányosítjuk a Jatek osztályunkat, majd a j.frame.mainloop() metódussal indítjuk a Tk feldolgozó hurkot.
Lássuk a Jatek osztályt, és részleteit:
class Jatek:
def __init__(self):
self.frame = Tk() # gyökér keret
self.frame.title("Hangman") # ablak címe
# létrehozzuk a felületet, ami egy canvas az akasztott embernek,
# egy label a tippeknek, és egy másik a szókiírónak, meg egy indítás gomb,
# egy label segédszövegnek, és egy a nyerési-vesztési szövegnek
# a gyökérkeretünket két oszlopra osztjuk, a balba rakjuk a canvast
# a jobb oldaliba pedig egy segédkeretet, amibe belepakoljuk a labeleket
self.rajz= Canvas(self.frame,width=300,height=400,bg='#fff',relief=RAISED)
self.rajz.grid(row=0,column=0)
self.jobboszlop = Frame(self.frame,padx=5,pady=5)
self.jobboszlop.grid(row=0,column=1,sticky=N+S)
self.tipplabel= Label(self.jobboszlop)
self.szokiirolabel = Label(self.jobboszlop,font=("Helvetica",16,"bold"),fg="#009800",pady=10)
self.segedszoveglabel = Label(self.jobboszlop,text="A kezdéshez kattints az\n\n\"Start\"\n\ngombra.",padx=15,pady=15)
self.nyertszoveg = Label(self.jobboszlop,pady=10,font=("Helvetica",14),fg="#F26F10")
self.startgomb = Button(self.jobboszlop,padx=10,pady=5,text="Start",command=self.start)
self.startgomb.grid(row=0,column=0)
self.segedszoveglabel.grid(row=1,column=0)
self.akasztofa = Akasztofa(self.rajz)
self.szavak=Szavak()
self.szokiirolabel.grid(row=2,column=0)
self.tipplabel.grid(row=3,column=0)
self.nyertszoveg.grid(row=4,column=0)
A konstruktorban létrehozzuk mindazokat az elemeket, amelyek a megjelenítéshez szükségesek, valamint a konzolos Hangman-hez hasonlóan a Szavak és Akasztofa egy-egy példányát (ne feledjük, itt az Akasztofa osztályunk nem azonos a régivel).
A következő metódusok képezik még a Jatek osztályunk részét:
def kilepes(self):
self.frame.quit()
def start(self):
self.segedszoveglabel.configure(text="Gondoltam egy szóra, próbáld kitalálni!")
self.startgomb.configure(command=self.ujrakezdes,text="Új játék")
self.vege=False
self.nyert=False
self.szo=unicode(self.szavak.valaszt(),'utf-8')
self.eredmeny=[0]*len(self.szo)
self.hiba=0
self.maxhiba=7
self.tippek=[]
self.szokiir()
self.tippkiir()
self.frame.bind_all('',self.beker)
def beker(self,event):
tipp=unicode(event.char,'utf-8')
if tipp in self.szo:
for c in range(len(self.szo)):
if tipp==self.szo[c]:
self.eredmeny[c]=1
if self.eredmeny.count(1)==len(self.szo):
self.vege=self.nyert=True
else:
self.hiba+=1
self.akasztofa.rajzol(self.hiba)
if self.hiba>=self.maxhiba:
self.vege=True
self.tippek.append(tipp)
self.szokiir()
self.tippkiir()
if self.vege:
self.frame.unbind_all('')
if self.nyert:
self.nyertszoveg.configure(text="Gratulálok! Kitaláltad!")
else:
self.nyertszoveg.configure(text=u"Vesztettél!\nÉrezd magad felakasztva :D\nA megfejtés: "+self.szo)
def szokiir(self):
szo=" "
for c in range(len(self.szo)):
if self.eredmeny[c]==0:
szo+="_ "
else:
szo+=self.szo[c]+" "
self.szokiirolabel.configure(text=szo)
def tippkiir(self):
self.tipplabel.configure(text="Eddigi tippjeid: %s" % ", ".join(self.tippek))
def ujrakezdes(self):
self.segedszoveglabel.configure(text="A kezdéshez kattints az\n\n\"Start\"\n\ngombra.")
self.startgomb.configure(command=self.start,text="Start")
self.szokiirolabel.configure(text="")
self.tipplabel.configure(text="")
self.nyertszoveg.configure(text="")
self.akasztofa.reset()
A kilepes metódust a miheztartás végett tettem be, ha netán teszek egy külön kilépés gombot a felületre, de végül nem tettem, így végülis ez feleslegesen maradt benn.
A start metódus átírja a "Start" gombot "Új játék"-ra, és az ujrakezdes metódust rendeli hozzá. Beállít pár változót, és választ egy szót a szókészletből, majd hozzárendeli a beker metódust a gombnyomás eseményhez.
A beker metódusunk aktivizálódik tehát minden gombnyomáskor. Megnézi a kapott karaktert, majd a tippnek megfelelően módosítja a kiírnivalókat (a szokiir és tippkiir metódusok segítségével), és az akasztófarajzot (self.akasztofa.rajzol(self.hiba) ). Ha a játék véget ér, kiírással értesíti a játékost, és eltávolítja a gombnyomás esemény kezelését.
Ezután a játék már csak az "Új játék" gombbal kezdhető újra. Az ujrakezdes metódusunk az alaphelyzetbe állítja az ablakot, és indulhat az egész újra.
És most lássuk az Akasztofa osztályunkat a Tkinter megoldáshoz igazítva:
class Akasztofa:
def __init__(self,canvas):
self.canvas = canvas
self.elemek = [ [],
['line',150,25,150,50,'black'],
['circle',125,50,175,100,'#f00'],
['line',150,100,150,160,'brown'],
['line',150,115,110,140,'#003700'],
['line',150,115,190,140,'#003700'],
['line',150,160,125,220,'blue'],
['line',150,160,175,220,'blue'],
]
self.alap()
def reset(self):
elemek=self.canvas.find_all()
for i in elemek:
self.canvas.delete(i)
self.alap()
def alap(self):
self.canvas.create_line(150,25,275,25,275,350,width=8,fill="#4E1B01",capstyle=ROUND,joinstyle=ROUND)
self.canvas.create_line(285,350,50,350,width=8,fill="#4E1B01",capstyle=ROUND,joinstyle=ROUND)
self.canvas.create_line(245,25,275,55,width=8,fill="#4E1B01",capstyle=ROUND,joinstyle=ROUND)
def rajzol(self,level):
e=self.elemek[level]
if e[0]=='line':
self.canvas.create_line(e[1],e[2],e[3],e[4],fill=e[5],width=4,capstyle=ROUND,joinstyle=ROUND)
elif e[0]=='circle':
self.canvas.create_oval(e[1],e[2],e[3],e[4],outline=e[5],width=4)
Konstruktorunk osztályváltozóvá teszi a kapott canvast, és az elemek listába felsorolja a kirajzolandó elemek adatait, majd meghívja az alap metódust az akasztófa kirajzolására (egyszerű vonalakról van szó). A reset metódus feladata a játék újrakezdésekor a canvas törlése. A rajzol metódusunk a kapott hibaszámnak megfelelő elemet rajzolja a vászonra, az elemek listában lévő adatok szerint.
Hát ennyi. Remélem érthető, ha mégsem, tegyétek fel a kérdéseiteket bátran.
Nincsenek megjegyzések:
Megjegyzés küldése