Kategória: Python gyerekeknek.
Űrhajós játék
Az alábbiakban több lépésben elkészítjük az űrhajós játékot, amit a Scratch-ben is elkészítettünk.
- Scratch űrhajós játék
- https://scratch.mit.edu/projects/238821682/: ez a végeredmény Scratch-ben.
- https://repl.it/talk/share/Urhajos-jatek/118631: ez pedig a végeredmény Pythonban.
Mozgassuk az űrhajót!
Első lépésben a következőt hajtjuk végre:
- Létrehozunk egy TK programot.
- Beállítjuk a fejlécet.
- Létrehozunk egy 480 képpont széles, 360 képpont magas vásznat.
- A hátteret feketére állítjuk.
- Feltöltünk egy űrhajós képet (ld. lejjebb), és betöltjük.
- Figyeljük a billentyűzetet: a bal nyilat lenyomva balra, a jobb nyilat lenyomva jobbra mozgatjuk az űrhajót.
- Ügyelünk arra, hogy nem tudjuk kimenni a képernyőről.
Mivel a Pythonban (ill. a TK-ban) egyáltalán nincsenek szereplők, azokról nekünk kell gondoskodnunk. A legjobb erre egy átlátszó hátterű png típusú fájlt használni, lehetőleg négyzet alakú, és nem túl nagy, de nem is túl kicsi, pl. 100x100-as méretben. Az alábbit töltöttem le erre a célra: https://pngtree.com/freepng/flying-rocket_3718748.html, ami átméretezve és átnevezve a következő:
Ezt töltsétek le, és másoljátok be abba a könyvtárba, ahova a program is kerül. A korábbiak alapján próbáljuk meg elkészíteni a programnak ezt a változatát. Ha valakinek nem sikerül, az innen lemásolhatja:
from tkinter import * def key_pressed(event): rocketship_coords = canvas.coords(rocketship) if event.keysym == 'Left' and rocketship_coords[0] > 0: canvas.move(rocketship, -5, 0) if event.keysym == 'Right' and rocketship_coords[0] < 480: canvas.move(rocketship, 5, 0) root = Tk() root.title('Űrhajós játék') root.bind('<KeyPress>', key_pressed) canvas = Canvas(root, width=480, height=360, bg='black') canvas.pack() rocketship_image = PhotoImage(file='rocketship.png') rocketship = canvas.create_image(240, 310, image=rocketship_image) root.mainloop()
A mozgatás finomítása
Működik, de kicsit "döcögősen" indul. A probléma ezzel az, hogy az operációs rendszer lenyomását használja, és ott az első betű lenyomása után kicsit többet vár, mint utána. Ez viszont rontja a játékélményt; ezt a problémát próbáljuk orvosolni. Az ötlet a következő:
- Használjuk ki azt, hogy nemcsak KeyPress, hanem KeyRelease eredmény is van, ami akkor következik be, amikor elengedünk egy billentyűt.
- Hozzunk létre egy változót, ami az űrhajó állapotát jelzi. Ez lehet bal (left), jobb (right) és áll (stand).
- A lenyomáskor állítsunk be a változót az irányra.
- Elengedéskor állítsuk be arra, hogy áll.
- Hozzunk létre egy mindig újra és újra lefutó belső magot, amely a fenti változót ellenőrzi, és szükség esetén mozgatja az űrhajót.
Hozzunk létre egy forrást, pl. rocketship01.py néven. Ez lesz az első lépésnek a végeredménye, a későbbiekben erre építve folytatjuk a rocketship02.py stb. változatokat.
from tkinter import * rocketship_state = 'stand' def key_pressed(event): global rocketship_state if event.keysym == 'Left': rocketship_state = 'left' if event.keysym == 'Right': rocketship_state = 'right' def key_released(event): global rocketship_state if event.keysym in ['Left', 'Right']: rocketship_state = 'stand' def play(): rocketship_coord = canvas.coords(rocketship) if rocketship_state == 'left' and rocketship_coord[0] > 0: canvas.move(rocketship, -1, 0) if rocketship_state == 'right' and rocketship_coord[0] < 480: canvas.move(rocketship, 1, 0) root.after(2, play) root = Tk() root.title('Űrhajós játék') root.bind('<KeyPress>', key_pressed) root.bind('<KeyRelease>', key_released) root.after(2, play) canvas = Canvas(root, width=480, height=360, bg='black') canvas.pack() rocketship_image = PhotoImage(file='rocketship.png') rocketship = canvas.create_image(240, 310, image=rocketship_image) root.mainloop()
Magyarázat:
- A root.after(2, play) azt jelenti, hogy 2 ezredmásodperc elteltével fusson le a megadott függvény, azaz a play. Talán egy kicsit furcsa, hogy nem írtunk oda zárójelet; ez azt jelenti, hogy nem a függvény végeredményét adtuk át paraméterül, hanem magát a függvényt.
- Ugyanez megjelenik a függvény végén is, mert különben egyszer lefutna és leállna.
- Két eseményre figyelünk: a billentyű lenyomása (<KeyPress>) és felengedése (<KeyRelease>).
- A globális rocketship_state változó tárolja az űrhajó állapotát. Azokban a függvényekben, amelyekben meg szeretnénk változtatni az értékét, a global kulcsszóval kell jeleznünk.
- Azt, hogy hány ezred másodpercenként fusson le, és hány képpontot lépjen egy-egy lépésben, ki kell kísérletezni. Nálam a 2 ill. az 1 azok az értékek, amelyek kellően dinamikus viselkedést biztosítanak, de nem túl gyorsak, és nem mellesleg a számok egészek.
A játék pillanatnyi állapota:
Érdemes összehasonlítani azzal, hogy ugyanez hogyan nézne ki Scratch-ben:
Egyszerű játékokat tehát lényegesen könnyebb Scratch-ben leprogramozni, mint Pythonban!
Önálló feladat
Meg lehet próbálni megvalósítani a fel és le mozgást is, ill. azt is, hogy két nyíl lenyomásakor átlósan is haladjon. A következő lépésekben viszont a fenti, csak balra és jobbra haladni képes változatot folytatjuk. Így ha valakinek nem sikerült befejezni, az nem marad le, mivel elég, ha a fenti programot kimásolja.