2018. szeptember 3., hétfő

Python alapok

Hagyományos számológép használata

http://f-labor.mkt.bme.hu/~madas/index.php?rst=mp&rid=itpypr

(Szia! Ha még nem telepítetted volna föl a gépedre a Pythont és a Pygamet, akkor ugorj ide, az "előszó" részhez, hogy letöltsd és telepítsd, és készen állj a kezdésre.



1.1 Bevezetés

fig.trajectory

Az egyik legegyszerűbb dolog, amire a Python használható, az a csinos kis számológép funkciója. Várjunk csak, a számológép nem is játék. Mégis miért beszélünk róla? Uncsi...



Nos, ahhoz, hogy kiszámoljuk a tárgyak esését, a lövedék röppályáját, és a legjobb pontszámokat, ahhoz számológép kell. Plussz, bármely igazi kocka úgy tekint a számológépre, mint egy játékra. Inkább, mint egy kínzóeszközre. Szóval, kezdjük el a tanulást a számológéppel. Ne aggódj, a grafikát már az ötödik fejezetnél tárgyaljuk.



Egy egyszerű számológép program már használható arra, hogy a felhasználó infót kapjon unalmas dolgokról, mint amilyen az ingatlanhitel utalása, vagy mondjuk izgalmasabb dolgokról, mint például a röppályája egy sárgolyónak.



Ahogyan azt az első példa mutatja, mozgási energiát fogunk számolni, valami olyasmit, ami majd kell nekünk is a játék fizikai motorjába.



fig.kinetic_energy

Figure 1.1: Python használata mozgási energia kiszámolásához

A legjobb dolog a programozásban, hogy a bonyolultságot el tudjuk rejteni egy egyenletbe. A többi felhasználónak csak a szükséges információt kell megadni, és már meg is kapta a szükséges eredményt egy könnyen érthető formában. Bármilyen egyszerű, hagyományos számológép el tud futni egy okostelefonon, ami lehetőséget ad a felhasználónak, hogy bármikor elővegye, és számoljon.



1.2 Megjelenítés

1.2.1 Szöveg kiírása

Hogyan ír ki a programunk bármit is a képernyőre?



print("Hello World.")

fig.printing_calculator

Ez a program kiírja a képernyőre a "Hello World"("Helló Világ!") szöveget. Rajta, és írjuk be az IDLE készenléti jel(prompt) után! Lássuk, hogyan működik! Próbálj kiírni más szöveget és karaktereket is! A számítógép boldogan kiír bármit, amit szeretnél, akár igaz, akár nem.



Hogyan néz ki a "Hello World" program más számítógépes nyelveken? Nézzük meg a Wikipediában. Elég szép mennyiségű "Hello World" programot gyűjtöttek össze más nyelveken:

http://en.wikipedia.org/wiki/Hello_world_program_examples



Érdekes látni, hogy mennyi különböző nyelv létezik. Képet lehet alkotni arról, hogy milyen összetett egy másik nyelv, a "Hello World" programja alapján.





Videó: A print függvény

Emlékeztetőül: a Pythonban a képernyőre kiíratás könnyű, csak használd ezt a parancsot: print. A print parancs után tegyél zárójelet ( ). A zárójelbe írd bele, mit szeretnél viszontlátni a képernyőn. A zárójel használata az információ átadásra alapvető gyakorlat a matematikában és a számítógépes nyelvekben.



A matek hallgatók úgy tanulják, hogy a zárójelbe egy kifejezés értékadását tüntetjük fel. Például,. és  függvények. Az adat a zárójeleken belülről jut el a függvényekhez. Ami a mi esetünkben másabb, az az, hogy mi szöveget íratunk ki.



Jegyezzük meg, hogy idézőjel van a szöveg elején és végén. Ha idézőjelbe tesszük, akkor a számítógép úgy jeleníti meg az adatot, ahogy leírtuk. Például, ez a program azt írja ki, hogy 2+3:



print("2 + 3")

1.2.2 Kifejezések eredményeinek kiíratása

A következő programban nincs idézőjel a  kifejezés körül, és így a számítógép össze fogja adni, matematikai kifejezésként. Szóval 5-t fog kiírni és nem 2+3-t.



print(2 + 3)

Az alább látható kód viszont egy hibaüzenetet fog generálni, mivel a számítógép megpróbálja matematikai kifejezésként értelmezni a "Hello World" -t, és így nem igazán működik:



print(Hello World)

A fenti kód hatására egy hibaüzenetet kapunk. SyntaxError: invalid syntax, ami a számítógép nyelvén azt jelenti, hogy nem ismeri a "Hello" és a "World" jelentését.



Mostantól tartsd észben, hogy ez egy aposztrófjel (egyszeres-idézőjel): ', ez pedig egy idézőjel: ". Amikor dupla-idézőjelet kérnek, olyankor gyakori hiba, hogy ezt írják "", ami egy dupla dupla-idézőjel. (az angolban - a ford.)



1.2.3 Több elem kiírása

A print paranccsal több dolgot is kiírathatunk egyszerre, minden egyes elemet vesszővel választunk el. Például, az alábbi kód eredménye ez lesz: Your new score is 1040



print("Your new score is", 1030 + 10)

A következő egysoros kód eredménye ez lesz: Your new score is 1030+10. A számokat nem adja össze, mivel azok az idézőjel közt vannak. Bármi, ami idézőjelek közt van, a számítógép szövegnek értelmez. Bármi, ami azon kívül, az a számítógépnek egy matematikai művelet, vagy számítógépes kód.



print("Your new score is", "1030 + 10")

A vessző az idézőjelen belülre vagy kívülre kerüljön?

A következő példa nem működik rendesen. Ez azért van, mivel a vessző nem különíti el a két kifejezést. Ez pedig azért van, mert a vessző az idézőjelen belülre került. Ha vesszővel akarjuk elválasztani a megjeleníteni kívánt elemeket, akkor azt az idézőjelen kívülre kell írnunk. Ha a programozó a vessző ki akarja íratni, akkor persze az idézőjelen belülre írjuk:



print("Your new score is," 1030 + 10)

Ez a példa már működik, mivel a vessző a kifejezéseket különíti el. Az eredmény:

Your new score is, 1040

Megjegyzem, hogy csak egy vessző lett kiírva. Tehát a vesszők az idézőjelen kívül elkülönítik a kifejezéseket, míg azon belül kiíratásra kerülnek. Az első vessző meg lett jelenítve, a másodikkal elkülönítettük a kifejezéseket.



print("Your new score is,", 1030 + 10)

1.3 Escape kódok(Escape Codes)

Ha az idézőjel arra való, hogy megmondja a számítógépnek, hogy hol kezdődik és végződik egy szöveg, amit meg akarok jeleníteni, akkor hogyan fogja kinyomtatni a program az idézőjelet? Például:



print("I want to print a double quote " for some reason.")



Ez a kód nem működik. A számítógép a szöveg közepén lévő idézőjelet a szöveg befejezésének veszi. Azután nem sok ötlete van arra nézve, hogy mit kezdjen a for some reason paranccsal, és az idézőjellel a végén. Sikerült összezavarni a számítógépet.



Fontos elmondani a számítógépnek, hogy mi a középső idézőjelet szövegként akarjuk megjeleníteni, és nem befejezéseként az előző idézőjelnek. Ez egyszerű, csak tegyél egy fordított perjelet az idézőjel elé, és a számítógép így megérti, hogy ez a szöveg része, és nem egy karakter ami megszakítja a szöveget. Például:



print("I want to print a double quote \" for some reason.")

fig.escape_codes

Ez a kombinációja két kódnak: \", ezt nevezik kikerülő kódnak. Majdnem minden nyelvben léteznek ilyenek. De, mivel a fordított perjel egy escape kód, ezért a perjel nem lesz megjelenítve. Például ez a kód sem működik:



print("The file is stored in C:\new folder")

Miért? Mivel a \n is egy escape kód. Ahhoz, hogy kiírathassuk a perjelet, meg kell kerülnünk, valahogy így:



print("The file is stored in C:\\new folder")

Van még egy pár fontos escape kód, amit érdemes ismerni. Itt van egy táblázat a fontosabb kódokról:



Escape kód Leírás

\' Aposztróf, egyszeres idézőjel

\" idézőjel

\t Tabulátor

\r CR: Carriage Return (kocsi visszatérése, balra/sor elejére mozgatás)

\n LF: Linefeed (sornövelés, lefelé mozgatás)

Mi az a “Carriage Return” (kocsivisszatérés) és “Linefeed”(sornövelés)? Próbáld ki ezt a példát:



print("This\nis\nmy\nsample.")

A parancs kimenete:



This

is

my

sample.

A \n egy sornövelés. El fogja mozgatni a "kurzort" egy sorral lejjebb a nyomtatáshoz képest. A számítógép minden szöveget egy hatalmas, hosszú vonalban tárolja. Onnan tudja, hogy hol vannak a sorok, hogy felismeri a \n karaktert.



Hogy bonyolultabb legyen, a különböző operációs rendszereknek különböző standardjai vannak azt meghatározni, hogy a sor hol ér véget.



Escape kódok Leírás

\r\n CR+LF: Microsoft Windows

\n LF: UNIX alapú rendszerek, és újabb Mac.

\r CR: Régebbi Mac alapú rendszerek

Általában a szövegszerkesztő odafigyel erre helyetted. A MS notepad nem igazán mondjuk, és ha UNIX fájlt nyitunk meg notepadban, akkor borzalmasan néz ki, mivel a sorok vége nem látszik, vagy fekete dobozok láthatók ott.



1.4 Megjegyzések, kommentálás

A kommentálás fontos (mégha a számítógép nem is foglalkozik vele)

Néha a kód némi magyarázatra szorul, ha valaki más olvassa. Ezért adunk "kommentelést" a kódhoz. A megjegyzések az embereknek készülnek, nem a gépnek.



Kétféleképpen hozhatunk létre kommentet. Az egyik, hogy a # szimbólumot használjuk. A gép átugrik minden szöveget, ami a kettőskereszt után található. Például:



# This is a comment, it begins with a # sign

# and the computer will ignore it.



print("This is not a comment, the computer will")

print("run this and print it out.")

A kettőskereszt jel idézőjelek közt persze nem minősül kommentnek. Ha egy sor kódot nem akarunk figyelembe venni, akkor egész egyszerűen a sor elejére írjuk a kettőskeresztet. Lehetséges a sor végére tenni a kommentunket.



print("A # sign between quotes is not a comment.")



# print("This is a comment, even if it is computer code.")



print("Hi") # This is an end-of-line comment

Lehetséges továbbá több sornyi kódot is kommentelni, ehhez három aposztrófot kell egymás után beírnunk. delimit.



print("Hi")

'''

This is

a

multi

line

comment. Nothing

Will run in between these quotes.

print("There")

'''

print("Done")

A legtöbb profi Python programozó ezt a többsoros kommentelést fogja előnyben részesíteni, valami olyasmiért, amit úgy neveznek, hogy docstrings(szövegfüzér) A docstring megengedi, hogy a kód mellé írjuk a megjegyzéseinket, dokumentációnkat, és később akár automatikusan kinyomtathatjuk dokumentumba, weboldalra, vagy IDE-be. Az általános kommenteléshez a kettőskereszt a legjobb.



Mégha te is vagy az egyetlen, aki olvashatja a kódot, akkor is írj kommentet, hogy időt takaríthass meg később. Olyan kommenteket írni, mint "földönkívűliek bombájának a kezelése" segít később gyorsan emlékezni arra, hogy az a kódrész mire vonatkozik.



1.5 Értékadás műveletek



Videó: Az értékadás művelet

Hogyan tároljuk a pontszámokat a játékunkban? Vagy hogyan követjük nyomon az ellenség életerejét? Ami ehhez kell, az egy értékadás műveletek. (Ez egy olyanművelet, ami szimbólumokat tárol, mint pl. + vagy - ) Ez aztán eltárol egy értéket egy változóban, amit később használhatunk. Az alábbi kód például az x változóra a 10-t vonatkoztatja, és kiírja az eltárolt értéket.



Lásd a lenti példát. Click on the “Step” button to see how the code operates.

Értékadás és változók használata

1

2

3

4

5

6

7

8

9

10

11

12

# Create a variable x

# Store the value 10 into it.

x = 10



# This prints the value stored in x.

print(x)



# This prints the letter x, but not the value in x

print("x")



# This prints "x= 10"

print("x=",x)

Step

Variables:

x=

Output:

10

x

x= 10

Változók amik kívül kerülnek az idézőjelen:

Megjegyzés:A listázás fentebb bemutatta a különbséget aközött, amikor x idézőjelen belül van, és amikor x idézőjelen kívül van. Ha az x az idézőjelen belül van, akkor a számítógép azt írja ki, hogy x. Ha az x az idézőjelen kívül van, akkor a számítőgép az x értékét írja ki. Azok közt, akik először tanulnak programozást gyakori, hogy zavaró ez az idézőjelen kívül és idézőjelen belül dolog.



fig.pi

Egy értékadás művelet (olyan kódsor, ami használja az = műveletet.) különbözik az algebrai egyenlőségtől, amit matekból tanultál. Ne mosd össze a kettőt. Az értékadás műveletnél a bal oldalon csak egy változó lehet, semmi más.



A bal oldalán az egyenletnek műveleti jel/értékadás művelet lehet, ami egy kifejezés. Egy kifejezés bármi, ami egy értéket ad vissza értékadás által. Lásd az alábbi kódot.



x = x + 1

A fenti kód nyilván nem lehet algebrai egyenlet. De ez érvényes a számítógép számára, mivel ez egy értékadó állítás. A matematikai egyenletek különböznek az értékadó műveletektől, mégha van is bennük változó, szám, vagy egyenlőség jel.



A fenti kifejezés esetében a kód az x jelenlegi értékét adja meg, egyet hozzáad, és eltárolja az eredményt az x-ben.



A példánkat kiterjesztbe, a kifejezés lent kiírja a hatos számot.



x = 5

x = x + 1

print(x)

Részenként futnak az értékadások. A számítógép nem néz a jövőbe. A lenti kódban, a számítógép kiírja az 5-t a második sorban, és aztán a negyedik sorban kiírja a 6-t. Azért, mert a második sorban a kód, ami egyet adna az x-hez, még nem futott le.



1

2

3

4

x = 5

print(x) # Prints 5

x = x + 1

print(x) # Prints 6

A következő értékadás érvényes és futni is fog, de értelmetlen. A gép adni fog egyet x-hez, de se ki nem írja, se el nem tárolja.



x + 1

Az alábbi kód 5-t fog kiírni, és nem 6-t, mivel a programozó elfelejtette eltárolni azx + 1 eredményét az x változóban.



x = 5

x + 1

print(x)

Az állítás alább nem érvényes, mivel a bal oldal többet tartalmaz egy darab változónál.



x + 1 = x

A Pythonban van más típusú értékadási művelet is. Ezek lehetővé teszik, hogy a programozó könnyedén változtassa meg a változó értékét. Például:



x += 1

A fenti értékadás egyenlő az alábbival:



x = x + 1

Vannak még értékadó műveletek összeadáshoz, kivonáshoz, szorzáshoz, és osztáshoz.



1.6 Változók

A változók kisbetűvel kezdődnek:

A változóknak kisbetűvel kellene kezdődniük. A változók kezdődhetnek nagybetűvel, vagy aláhúzással, de ezek speciális esetek, és nem történhetnek meg normál esetekben. Az első kisbetű után a változó tartalmazhat nagybetűt, kisbetűt, számot, aláhúzást. A változók nem tartalmazhatnak space karaktert.



A változók betűtípusra érzékenyek. Ez összezavarhatja a programozót, aki nem készül erre fel. A lenti példában az eredmény 6 lesz és nem 5, mivel két különböző változót használunk, a x-t és a X-t.



x = 6

X = 5

print(x)

A hivatalos Python stílus kézikönyv (igen, a programozók tényleg írtak egy könyvet a stílusról) azt mondja, hogy a többszavas változónevek a Pythonban el kellene legyenek választva, aláhúzással. Például használjuk a hair_style és ne a hairStyle alakot. Személy szerint, ha te az én tanítványom vagy, akkor tudnod kell, hogy engem nem érdekel különösebben ez a szabály, mivel a következő nyelv, amit a Python után tanítunk, az a Java, és ott pont fordítva van. Megpróbáltam a Java stílusú szabályokat tanítani ezen a kurzuson, de akkor gyűlölködő leveleket kaptam a Python szerelmeseitől. Ezek az emberek meglátogatták a weboldalamat, és sokkot kaptak, sokkot kaptak, mondom, a szegényes stílusom miatt.



Joan Rivers-nek semmi köze ezekhez az emberekhez, szóval feladtam és megpróbáltam a helyes stílust követni immár.



Itt van néhány példának, hogy mi elfogadható és mi nem változónévként:



Elfogadható változónév Nem elfogadható változónév Elfogadható, de nem helyes

first_name first name FirstName

distance 9ds firstName

ds9 %correct X

Minden nagybetűs változónév, mint amilyen a MAX_SPEED megengedett, de csak akkor, ha a körülmények miatt a változó sosem változtatja meg az értékét. Azt a változót, ami nem változtatja meg az értékét állandónak/konstansnak hívjuk.



1.7 Műveletek

A bonyolultabb matematikai műveletekhez, a mindennapi matematikai műveletek elérhetők. Köztük néhány nem túl gyakorival:



műveleti jel művelet példa egyenlet példa kód

+ összeadás  a = 3 + 2

- kivonás  a = 3 - 2

* szorzás  a = 3 * 2

/ osztás  a = 10 / 2

// egész osztás N/A a = 10 // 3

** hatványozás  a = 2 ** 3

% modulus/törtrész N/A a = 8 % 3



Videó: Műveletek

Az egész osztás mindig lefelé fogja kerekíteni az eredményt, a legközelebbi egész felé. Például a 11//2 egyenlő lesz 5-tel, és nem 5.5-tel, és 99//100 egyenlő 0.



Szorzás művelet műveleti jel nélkül nem működik a Python alatt. A következő két sornyi kód nem működik:



# This does not work

x = 5y

x = 5(3/2)

A szorzás műveleti jelét muszáj használni ezekben a sorokban, ha azt akarjuk, hogy működjenek:



# This does work

x = 5 * y

x = 5 * (3 / 2)

1.7.1 Műveletek elválasztása

Bármennyi space lehet a műveleti jelünk előtt és után, és a számítógép még akkor is meg fogja érteni. Például az alábbi 3 sor teljesen egyenértékű.



1

2

3

x=5*(3/2)

x = 5 * ( 3 / 2 )

x      =5     *(    3/   2)

A hivatalos Python stílus kézikönyv azt mondja, hogy lennie kell egy space-nek az operátor előtt és után is. (Majd meghaltatok, hogy megtudjátok, igaz? Oké, a hivatalos stílus kézikönyvnek az elérhetősége itt van: PEP-8.) A három fenti kód közül a legstílusosabb a második.



1.8 Műveletek sorrendje

A Python a kifejezéseknek úgy ad értéket, hogy követi a műveleti sorrendet, ahogyan azt egy alap matematikai kifejezésnél is találjuk. Például ez az egyenlet nem korrekt módon számolja ki az átlagot:



average = 90 + 86 + 71 + 100 + 98 / 5





Az első művelet, amit végrehajt az a 98/5. És így számol:





ahelyett, hogy a vágyott eredményt adná:







Zárójel használatával a probléma orvosolható:

average = (90 + 86 + 71 + 100 + 98) / 5

1.9 Trigonometrikus függvények

A trigonometrikus függvényeket arra használják, hogy velük szinuszt és koszinuszt számoljanak. Alapértelmezett állapotban a Python nem tudja a sin/cos függvényeket számolni, de ha a helyes könyvtárat importáljuk neki, akkor már igen. Az egységek radiánban lesznek megadva.



# Import the math library

# This line is done only once, and at the very top

# of the program.

from math import *



# Calculate x using sine and cosine

x = sin(0) + cos(0)

1.10 Szokványos egyenletek kiszámítása

Egy Python program kiszámolhatja fogyasztását egy autónak, ami 294 mérföldet tesz meg, 10.5 gallon gázolajjal.



m = 294 / 10.5

print(m)

Ez a program kicsit fejleszthető változók használatával. Ez lehetővé teszi, hogy az értékeket könnyedén megváltoztathassuk a kódban, anélkül, hogy az egyenlethez nyúlnánk.



m = 294

g = 10.5

m2 = m / g # This uses variables instead

print(m2)

A jó változó nevek fontosak.

Magától ezt a programot megérteni nehézkes.Az m és g változók nem jelentenek túl sokat önmagukban. A program megcsinálható úgy is, hogy könnyen érthető legyen a működése a változók alapján:



milesDriven = 294

gallonsUsed = 10.5

mpg = milesDriven / gallonsUsed

print(mpg)

Most már, ha egy nem-programozó ránéz a kódra, neki is lesz ötlete, hogy mit csinálhat a program. Egy másik példa a jó és a rossz változó elnevezésre:



# Hard to understand

ir = 0.12

b = 12123.34

i = ir * b



# Easy to understand

interestRate = 0.12

accountBalance = 12123.34

interestAmount = interestRate * accountBalance



Videó: Egy szokványos számoló program készítése

Az IDLE szerkesztőben lehetőség van arra, hogy szerkesszük az adott sort, annak újragépelése nélkül. Ezt úgy tehetjük meg, hogy a kurzort felvisszük a választott sorra, és ütünk egy entert. Ezzel másoljuk az adott sort.



A Python kódot bevinni a >>> prompttal lassú, és csak egy sort lehet egyszerre. Valamint nem lehetséges lementeni, hogy más is használhassa. Szerencsére, van egy sokkal egyszerúbb módja is a Python kód bevitelének.



A Python kódot bevihetjük script által is. A script Python kódsorok sorozata ami egyszerre lesz végrehajtva. Ahhoz, hogy egy scriptet készíthessünk, nyissunk egy új ablakot, ahogy az ábra mutatja 1.2.



fig.entering_a_script

Figure 1.2: Szkript bevitele

Vigyük be a gázolaj fogyasztást számoló programunkat, aztán mentsük el a fájlt. Elmenthetjük a fájlt flash drive-ra, network drive-ra, vagy bármilyen más helyre. A Python programok mindig .py kiterjesztésre végződnek. Lásd az ábrát: 1.3.



fig.saving_mpg_calculator

Figure 1.3: Szkript mentése

Futtassuk a programot, egyszerűen klikkeljünk a "Run" menüre és válasszuk a "Run Module" parancsot. Próbáljuk meg frissíteni a programot úgy, hogy új értékeket adunk a mérföldre, és gallonra.



Vigyázat, gyakori hiba!

Ettől a ponttól kezdve, szinte minden kódot vigyél be a script/modul-ba. Ne gépeld be a programodat az IDLE >>> prompton kívülre. Az ide beírt kód nem lesz elmentve. Ha ez történne, újra kell kezdeni. Ez az egyik leggyakoribb hibája a kezdő programozóknak.



Ez a program sokkal hasznosabb lenne, ha képes volna párbeszédre a felhasználókkal és megkérdezné a felhasználót a vezetett mérföldekről és a felhasznált gallonokról. Ez megtehető az input paranccsal. Lásd az alábbi kódot:



# This code almost works

milesDriven = input("Enter miles driven:")

gallonsUsed = input("Enter gallons used:")

mpg = milesDriven / gallonsUsed

print("Miles per gallon:", mpg)

Ennek a programnak a futtatása során a felhasználó meg lesz kérdezve a mérföldekről és a gallonokról, de egy furcsa hibát is generálunk, amit az alábbi ábrán láthatsz 1.4.



fig.mpg_program_error

Figure 1.4: Az MPG program futtatásakor megjelenő hiba

Ezt kijavítandó, kicsit módosítsuk a programunkat:



milesDriven = input("Enter miles driven:")

gallonsUsed = input("Enter gallons used:")

x = milesDriven + gallonsUsed

print("Sum of m+g:", x)

A fenti kódot futtatva ez lesz a kimeneti üzenet 1.5.



fig.mpg_incorrect_addition

Figure 1.5: Hibás összeadás

A program nem adja össze a két számot. Csak egymás után teszi őket. Ez azért történik, mert a program nem tudja, hogy itt két számot kértünk be. A felhasználó azt is beütheti, hogy Bob, vagy Mary. Ezek összege BobMary lenne. Elég érdekes.



Az adatbrvitelt számokká kell alakítanunk.

Ahhoz, hogy elmondjuk a számítógépnek, hogy ezek számok, szükséges az input funkciónkat kiegészíteni egy int( )-rel vagy egy float( )-tal. Az első esetben egész-, a másodikban törtszámokat várunk eredményül.



A végső, működő program:



calculate_miles_per_gallon.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# Sample Python/Pygame Programs

# Simpson College Computer Science

# http://programarcadegames.com/

# http://simpson.edu/computer-science/



# Explanation video: http://youtu.be/JK5ht5_m6Mk



# Calculate Miles Per Gallon

print("This program calculates mpg.")



# Get miles driven from the user

miles_driven = input("Enter miles driven:")

# Convert text entered to a

# floating point number

miles_driven = float(miles_driven)



# Get gallons used from the user

gallons_used = input("Enter gallons used:")

# Convert text entered to a

# floating point number

gallons_used = float(gallons_used)



# Calculate and print the answer

mpg = miles_driven / gallons_used

print("Miles per gallon:", mpg)

Step

Variables:

milesDriven=

gallonsUsed=

mpg=

Output:

This program calculates mpg.

Enter miles driven:288

Enter gallons used:15

Miles per gallon: 19.2

És egy másik példa arra, hogyan számoljuk ki a mozgási energiáját egy tárgynak:



calculate_kinetic_energy.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

# Sample Python/Pygame Programs

# Simpson College Computer Science

# http://programarcadegames.com/

# http://simpson.edu/computer-science/



# Calculate Kinetic Energy



print("This program calculates the kinetic energy of a moving object.")

m_string = input("Enter the object's mass in kilograms: ")

m = float(m_string)

v_string = input("Enter the object's speed in meters per second: ")

v = float(v_string)



e = 0.5 * m * v * v

print("The object has " + str(e) + " joules of energy.")

Ha le akarjuk rövidíteni a programot, akkor egymásba ágyazhatjuk az input parancsunkat, és float utasítást. Példa erre:



milesDriven = input("Enter miles driven:")

milesDriven = float(milesDriven)

Ugyanazt fogja adni eredményül ez is:



milesDriven = float(input("Enter miles driven:"))

Ezesetben, a kimenete az input utasításnak közvetlenül van üsszekötve a float utasítással. Mindkettő működik, és a programozón múlik, hogy melyiket választja. Fontos, továbbá, hogy megértsük mindkét formát.



A játékok készítés komoly feladat több szempontból is. Először is a játékok intenzív interakciót követelnek meg a felhasználóval, hasonlóan a grafikus felületű szoftverekhez. A játék típusától és a játékmenettől függően megfelelően jól kell kinéznie, hogy közönséget kapjon, ezenkívül a játékoknak egy bizonyos szintű mesterséges intelligenciát kell nyújtania (gondoljunk akár egy szimpla amőbára). A játékoknak szórakoztatónak kell lenniük, mindamellett megfelelő kihívást kell nyújtania a játékosoknak. Ezek igen összetett követelményrendszert jelentenek.
A komoly és látványos játékok sosem egy ember munkájának az eredményei, hiszen a megalkotásukhoz szükséges szakmai ismeret annyira szerteágazó (nem beszélve az emberek saját adottságairól, tehetségéről), hogy azokat megfelelő szinten elsajátítani egy embernek egy életre szóló feladat - és akkor még semmit sem csinált. Ezeket a játékokat több emberből álló csapatok készítik (producer, designer, artist, coder, marketinges, webfejlesztő, és sok esetben PR-os is kell) igen nagy ráfordításokkal.
Ha valaki a játékiparban szeretne dolgozni, mindenképpen ki kell választania magának egy testhez álló szakirányt, majd keresnie vagy építenie kell egy csapatot. A játékfejlesztés kemény munka, ami lassan térül meg, hiszen néha egy játék fejlesztése több évig is eltart, addig finanszírozni kell a készítők bérét, és a fejlesztés infrastruktúráját.



Gondolom most kellőképpen sikerült mindenkit elijeszteni a témától, de nem eszik olyan forrón a kását, egy ember is készíthet jó, érdekes és jól kinéző játékokat, csak tudomásul kell venni, hogy ezek bonyolultsága és/vagy színvonala azért messze el fog maradni a fent említett komoly alkotásokétól :D A DRY (Don't Repeat Yourself) és DNRTW ( Do Not Reinvent The Wheel) elvet szem előtt tartva, a legokosabb ha valamilyen keretrendszert alkalmazunk a játékok készítése során (a komolyabb és összetettebb keretrendszereket már játékmotornak hívják). Ezek leveszik a terhet a vállunkról egy csomó olyan dologgal kapcsolatban, mint pl. képadatok tárolása, átalakítása, képernyőre rakása, hangok, zenék kezelése, stb.

Pythonhoz, az egyszerű gyalogbéka hobbiprogramozónak a pygame (ejtsd: pájgém), esetleg a pyglet (ejtsd: piglet) áll rendelkezésére, vagy komolyabb dolgokhoz az ogre, vagy a crystalspace. A pygame-en kívül a többinél konyitani kell valamennyire az opengl-hez, ha valaki nem foglalkozott vele, akkor mindenképpen a pygame-et ajánlanám kezdésnek.

Mi is ez a pygame? Nos létezik linuxon egy programkönyvtár (lib) amely elvben hasonló hozzáférést enged a gép video, hang és input elemeihez, mint a winen a directx. Simple Directmedia Layer a becsületes neve, de SDL-ként közismertebb. Ez egy C-ben írt lib, amit tud azt jól tudja, bár nem annyira sokrétű, mint a wines párja (egyébként elérhető win alatt is, így a pygame is).

 Lelkes pythonosok megírták a pygame-et, ami tulajdonképpen pár általuk hozzáadott plusz dologtól eltekintve az SDL pythonos nyelvi kötése. Habár opengl mutatványokra is felhasználható, a pygame elsősorban 2D játékok készítésére készült. Ennyi unalmas bevezető után csapjunk a sűrűjébe, is próbáljunk meg valamit kezdeni a pygame-mel!

Természetesen fel kell telepíteni használat előtt, ubuntu, debian alatt van a repóban, sudo apt-get install python-pygame, más rendszereknél nézzétek meg a telepítési leírásokat. Használatához be kell importálnunk a pygame modult a programunkba. Mindjárt két importot is érdemes elvégezni, ezzel egy csomó gépeléstől kímélhetjük meg magunkat (pl. pygame.QUIT helyett elegendő QUIT-et írni), majd inicializálni kell a pygame összetevőket:


import pygame
from pygame.locals import *
pygame.init()

Az inicializálás során a pygame felkészíti az SDL réteget a működésre, ami egyben a hardverek inicializálását is magában foglalja. Ha ezt elmulasztjuk, a programunk működésképtelen lesz.

Ahhoz, hogy legyen egy ablakunk, ahol a játék grafikáját, elemeit megjelenítjük, meg kell kérnünk az SDL-t, hogy készítsen nekünk egyet. És itt jön a pygame és az SDL első korlátja, mert meg kell adni neki, hogy mekkorát készítsen. Ezzel nincs semmi baj, a baj azzal van, hogy ezen utána nem tudunk változtatni :(
Ezért már a játék kezdetekor ki kell találni, hogy mekkora ablakban fogunk dolgozni.
Most egy 800x600-as ablakot hozunk létre, ez elfér manapság szinte minden képernyőn, ahol a pygame elfut (a telefonokat most hagyjuk ki ebből).


screen = pygame.display.set_mode((800,600))

A screen változóban egy pygame.surface objektum tárolódik el. Mi is ez a surface? A szó maga felületet jelent, a pygame-ben egy kicsit többet, de a lényeg az a mi szempontunkból, hogy egy olyan felület, amire rajzolni tudunk.

Nosza rajzoljunk rá! Csinálunk egy pattogó labdát. Nem egy hasznos dolog, és semmiképpen nem játék még, de kezdetnek jó lesz :) Itt a forráskód, és átbeszéljük.


#!/usr/bin/env python
# -*- coding:utf8 -*-

import sys,pygame
from pygame.locals import *

# pygame inicializálása
pygame.init()

# ablak megjelenítése és a játékadatok beállítás
SCREEN_SIZE = (800,600) # ablak mérete
screen = pygame.display.set_mode(SCREEN_SIZE) # ablak "surface"

BGCOLOR = (0,0,0) # háttérszín
BALLCOLOR = (255,0,0) # labda színe

d = 30 # labda átmérője
dh = d/2 # átmérő fele
x,y = dh,dh # labda kezdőpontja (középpont)
vx,vy = 12,18 # függőleges és vízszintes sebessége a labdának
fps = 30 # képkocka / másodperc

# ezek adják meg hol kell a labdának visszapattannia
xlimits = (dh,SCREEN_SIZE[0]-dh)
ylimits = (dh,SCREEN_SIZE[1]-dh)

def rajzol(x,y):
    """rajzol(x,y):
    letörli a képernyőt, és felrajzolja a labdát az x,y pozícióba"""
    screen.fill(BGCOLOR)
    pygame.draw.circle(screen,BALLCOLOR,(x,y),dh,0)

def mozgat(x,y,vx,vy):
    """mozgat(x,y,vx,vy):
    kiszámolja a labda következő pozícióját.
    megfordítja a labda mozgását az ablak szélénél"""
    x = x + vx
    y = y + vy
    if x < xlimits[0]:
        x = xlimits[0]
        vx = -vx
    if x > xlimits[1]:
        x = xlimits[1]
        vx = -vx
    if y < ylimits[0]:
        y = ylimits[0]
        vy = -vy
    if y > ylimits[1]:
        y = ylimits[1]
        vy = -vy
    return x,y,vx,vy

def kilep():
    """kilep():
    Megnézi, hogy megnyomták-e az ESC gombot
    vagy megpróbálták bezárni az ablakot"""
    for event in pygame.event.get():
        if event.type==QUIT:
            return True
        elif (event.type==KEYDOWN and event.key==K_ESCAPE):
            return True
    return False

# ezzel az objektummal tudjuk szabályozni a játék sebességét
clock = pygame.time.Clock()

# fő ciklus
# ismétlődik amíg ki nem lépünk
while True:
    # kirajzoljuk a játékunkat
    # és elvégezzük a mozgatását a labdának
    rajzol(x,y)
    x,y,vx,vy = mozgat(x,y,vx,vy)

    # ki akart lépni a felhasználó?
    if kilep():
        pygame.quit()
        sys.exit()

    # kirakjuk az ablak tartalmát a képernyőre
    pygame.display.flip()

    # szabályozzuk a futási sebességet
    clock.tick(fps)

    # infóként kinyomjuk a labda adatait a konzolra
    print x,y,vx,vy

Az 1-25 sorok magától értetődőek, de azért elláttam kommentekkel is a biztonság kedvéért. Mielőtt a rajzol és mozgat függvényeket megnéznénk, inkább foglalkozzunk a kód végén látható végtelenített ciklussal, a 67-87 sorokban.

Ez a programunk fő ciklusa. Mit is csinál? Kirajzolja az ablak tartalmát a rajzol() függvénnyel, kiszámolja a labda következő koordinátáját a mozgat() függvénnyel, megnézi, hogy kapott-e kilépési parancsot - ha igen, akkor kilép - , logolja a labda koordinátáit és sebességét a konzolra, és kezdődik minden előlről.
Van itt viszont egy fontos parancs, amiről fontos szót ejteni: pygame.display.flip()
Az SDL dupla pufferelést alkalmaz, minden rajzolási műveletet a képernyő egy másolatán végez a memóriában. Ahhoz, hogy ezt lássuk is, meg kell jeleníteni a képernyőn. Ezzel a paranccsal a puffer tartalmát villámgyorsan kiteszi a videomemóriába, így az számunkra is láthatóvá válik.
A clock.tick(fps) paranccsal a játék futásának sebességét állítjuk be, így minden hardveren azonos sebességel fog futni a ciklusunk, nevezetesen egy másodperc alatt fps alkalommal.

Ejtsünk szót még a rajzol() függvényünkről!
A függvény elején letöröljük a képernyőt, azaz kitöltjük a BGCOLOR színnel, majd a kapott x,y koordinátákra kirajzolunk egy BALLCOLOR színű kört. Ha nem törölnénk le a képernyőt, csak a kört rajzolnánk ki, akkor a labdánk gyakorlatilag csíkot húzna a képernyőre. Ebből is látható, hogy minden képkockán elő kell állítani a teljes képet. Ez bonyolult játékoknál elég időigényes feladat lehet, ezért mindenféle praktikához kell folyamodni a megfelelő teljesítmény elérése érdekében.

A mozgat() függvényünk egyszerű, "csak" számítási feladatot végez, a kapott x,y és vx,vy sebességadatok alapján kiszámolja hova kerül a labda. Ha a képernyőn kívülre kerülne, akkor visszateszi a képernyőre, és megfordítja a vízszintes vagy függőleges (vagy mindkettő) mozgási irányát.

A Python programozási nyelv
Pygame
A Pygame játékok fejlesztését segítő python modulok gyűjteménye. A platformfüggetlen SDL könyvtárra épül. Ez az oka annak, hogy a pygame programok szinte minden platformon és operációs rendszeren futtathatók.
A Pygame egy ingyenes bővítése a nyelvnek. Részleteket ld. az LGPL licensz leírásában.
A következőkben megpróbálom egyszerű példákkal bemutatni a pygame használatát, működését. Ezt a tutoriált Pete Shinners: Line By Line Chimp című munkája alapján készítettem. Többnyire annak fordítása, ill. saját tapasztalatokkal való kiegészítése.

Szükséges modulok
A következő kódrészlet tartalmazza a szükséges modulokat. Egyben példát láthatunk arra, hogyan ellenőrizhetjük egyes, opcionális modulok jelenlétét a futtató környezetben.

import os, sys
import pygame
from pygame.locals import *

if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'
Először importáljuk az "os" és "sys" python modulokat. Ezek sok mindenre használhatók, például lehetővé teszik platform független fájl-útvonalak megadását. A következő sorban importáljuk a pygame csomagot. Ezzel az összes pygame modult importáltuk. Van néhány opcionális modul is, melyek None értéket vesznek fel, ha nem sikerült őket beimportálni. Ezt ellenőrizzük az utolsó két sorban.
A "locals" egy speciális pygame csomag. Ez olyan gyakran használható konstansokat és függvényeket tartalmaz, melyeket célszerű a program globális névterébe elhelyezni. Ez a modul tartalmazza többek között a Rect függvényt, mellyel téglalap objektumokat hozhatunk létre, vagy olyan konstansokat, mint a 'QUIT, HWSURFACE', melyeket a pygame más részeivel való interakciókhoz használjuk. Természetesen nem kötelező ezt importálni. Ekkor a pygame modulon keresztül is elérhetjük.
Végül példát láthatunk arra, hogyan írassunk ki hibajelzéseket, ha egy adott modul pl. a font vagy a sound nem elérhető.
Erőforrások betöltése
Két függvényt adunk képek és hangok betöltésére.
Kép betöltése

def load_image(name, colorkey=None):
    fullname = os.path.join('data', name)
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'Cannot load image:', name
        raise SystemExit, message
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0,0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()

Az első paramétere a betöltendő kép nevét tartalmazza. A függvény rendelkezik egy második, opcionális paraméterrel is. Ezt a kép "színkulcsának" beállításához használhatjuk. A "színkulcsot" az átlátszó színek reprezentálására használjuk.
A függvény első sorában elkészítjük a fájlhoz tartozó teljes útvonalat. Ebben a példában az összes erőforrás a "data" alkönyvtárban van. Az os.path.join használatával olyan fájl-útvonalakat gyárthatunk, melyek bármilyen platformon használhatók.
A következő lépésben a pygame.image.load függvénnyel betöltjük a képet. Ezt a függvényhívást egy kivételkezelő részbe ágyaztuk, így a betöltés során fellépő hibákat könnyen lekezelhetjük. A betöltés után fontos a convert() függvény meghívása. Ez egy új másolatot készít az objektumról és a képernyőhöz igazítja a kép színformátumát és színmélységét. Ez azért kell, hogy a képernyőre való kirajzolás a lehető leggyorsabban menjen.
Végül beállítjuk a "színkulcsot" a képhez. Ha a felhasználó megadta a colorkey paramétert, akkor ez lesz a képhez rendelve. Általában ez egy szín RGB értéke, pl. a (255,255,255) tuple a fehér színt jelenti. Ezenkívül megadhatunk -1-et is színkulcsként. Ebben az esetben a kép bal-felső pixelének színe lesz a színkulcs.
Hang betöltése

def load_sound(name):
    class NoneSound:
        def play(self): pass
    if not pygame.mixer:
        return NoneSound()
    fullname = os.path.join('data', name)
    try:
        sound = pygame.mixer.Sound(fullname)
    except pygame.error, message:
        print 'Cannot load sound:', wav
        raise SystemExit, message
    return sound

Ezzel a függvénnyel egy hangfájlt tudunk betölteni. Az első dolog annak ellenőrzése, hogy sikerült-e rendesen importálnunk a pygame.mixer modult. Sikertelen esetben egy speciális osztálypéldányt adunk vissza, mely rendelkezik egy állejátszó metódussal. Ez az objektum ugyanúgy viselkedik és használható, mint egy normális Sound objektum azzal a kivétellel, hogy nem ad hangot. Ezáltal nincs is szükségünk további hiba ellenőrzésre.
A fenti két függvény nagyon hasonlít egymásra. Itt is először definiálunk egy teljes útvonalat a hangfájlhoz, majd a try-except részben betöltjük. Végül egy Sound objektumot adunk vissza.
Játék osztályok
A következőkben egy játék két lehetséges objektumait mutatjuk be. A játék "logikáját" ez a két osztály tartalmazza.

class Fist(pygame.sprite.Sprite):
    """moves a clenched fist on the screen, following the mouse"""
    def __init__(self):
        pygame.sprite.Sprite.__init__(self) #call Sprite initializer
        self.image, self.rect = load_image('fist.bmp', -1)
        self.punching = 0

    def update(self):
        "move the fist based on the mouse position"
        pos = pygame.mouse.get_pos()
        self.rect.midtop = pos
        if self.punching:
            self.rect.move_ip(5, 10)

    def punch(self, target):
        "returns true if the fist collides with the target"
        if not self.punching:
            self.punching = 1
            hitbox = self.rect.inflate(-5, -5)
            return hitbox.colliderect(target.rect)

    def unpunch(self):
        "called to pull the fist back"
        self.punching = 0

A fenti osztály reprezentálja a játékos öklét. Ezt a pygame.sprite modul Sprite osztályából származtattuk. Az __init__ függvény új példány létrehozásakor hívódik meg. Ebben a függvényben először a bázisosztály __init__ függvényét hívjuk. A játékunkban a sprite-ok kirajzolásához Group osztályokat használunk. Ezen osztályok olyan sprite-ok megjelenítésére használhatók, amelyek rendelkeznek image és rect attribútumokkal. Ezen attribútumok módosításával érhetjük el, hogy a megjelenítő egy adott képet egy adott helyre rajzoljon ki.
Minden sprite rendelkezik egy update() metódussal. Ezt a függvény általában képkockánként egyszer hívjuk. Ebbe helyezhetünk olyan kódokat, melyekkel mozgathatjuk és frissíthetjük a sprite változóit. Jelen esetben az update() metódus az öklöt az egér kurzor helyére mozgatja. Eltolást is alkalmaz, ha az objektum "punching" állapotban van.
A punch() és az unpunch() metódusokkal a "punching" állapot kapcsolható be és ki. A punch() függvény igaz értéket ad vissza, ha az ököl eltalálta a célt, azaz a két sprite ütközött.

class Chimp(pygame.sprite.Sprite):
    """moves a monkey critter across the screen. it can spin the
       monkey when it is punched."""
    def __init__(self):
        pygame.sprite.Sprite.__init__(self) #call Sprite intializer
        self.image, self.rect = load_image('chimp.bmp', -1)
        screen = pygame.display.get_surface()
        self.area = screen.get_rect()
        self.rect.topleft = 10, 10
        self.move = 9
        self.dizzy = 0

    def update(self):
        "walk or spin, depending on the monkeys state"
        if self.dizzy:
            self._spin()
        else:
            self._walk()

    def _walk(self):
        "move the monkey across the screen, and turn at the ends"
        newpos = self.rect.move((self.move, 0))
        if not self.area.contains(newpos):
if self.rect.left <  self.area.left or \
self.rect.right > self.area.right:
            self.move = -self.move
            newpos = self.rect.move((self.move, 0))
            self.image = pygame.transform.flip(self.image, 1, 0)
        self.rect = newpos

    def _spin(self):
        "spin the monkey image"
        center = self.rect.center
        self.dizzy += 12
        if self.dizzy >= 360:
            self.dizzy = 0
            self.image = self.original
        else:
            rotate = pygame.transform.rotate
            self.image = rotate(self.original, self.dizzy)
        self.rect = self.image.get_rect(center=center)

    def punched(self):
        "this will cause the monkey to start spinning"
        if not self.dizzy:
            self.dizzy = 1
            self.original = self.image

A chimp osztálynak egy kicsit több feladata van, mint a Fist-nek, de semmivel sem bonyolultabb annál. Az osztály feladata a csimpánz mozgatása a képernyőn, és ha eltaláljuk a majmot, akkor elkezd forogni. Ezt az osztályt is a Sprite osztályból származtatjuk, és a Fisthez hasonlóan inicializáljuk. Az inicializálás során az area attribútumot a képernyő méretéhez igazítjuk.
Az update függvény tevékenysége a csimpánz "dizzy" állapotától függ. Ez akkor igaz, ha eltalálták a majmot és éppen forog. Ennek függvényében vagy a _spin vagy a _walk metódusokat hívja. Az aláhuzás prefix a python függvények nevében azt jelenti, hogy ezt csak a tartalmazó osztály használhatja. Ez csupán egy konvenció, azaz nem nyelvi szintű deklarátum.
A walk metódus egy adott értékkel eltolja a csimpánz képét. Ha az új pozíció érinti a kép szélét, akkor az eltolás irányát megfordítjuk. Ezen kívül a csimpánz képét is tükrözzük a pygame.transform.flip függvénnyel. Ezzel elértük, hogy a csimpánz mindig testtel előrefelé mozogjon.
A spin metódust, akkor használjuk, amikor eltalálták a makit, és épp szédül, azaz a "dizzy" változó nem nulla (logikai értéke igaz). Ebben az attribútumban tároljuk a aktuális forgatás mértékét (0-360 fokig). Miután teljesen körbeforgattuk, ismét az eredeti, forgatás nélküli képet rajzoljuk a csimpi helyére. A pygame.transform.rotate hívása helyett, először egy referenciát állítunk erre a függvényre. Ez a rotate változó. Később - a rövidebb forma miatt - ezen keresztül végezzük a forgatást. Ezt nem kötelező így csinálnunk, de adunk erre is példát. Mindig az eredeti képet fogjuk forgatni. Erre azért van szűkség, mert a forgatás során romlik a kép minősége. Így egy forgatás sorozat jelentősen rontana a képminőségen. Ezen kívül a forgatással a kép mérete is változhat. A rotate függvény első paramétere a forgatandó kép, a második pedig a forgatás mértéke fokokban. A rotáció után a forgatás középpontja, a keletkezett kép középpontja kell, hogy legyen. Ezzel elérhetjük, hogy ne lépjen fel elmozdulás.
Végül nézzük meg a punched() metódust. Ennek meghívásával lép a sprite a forgó, szédült állapotba. Az aktuális képről készít egy másolatot az original attribútumba. Ez a kép lesz a forgatás alapja.
Inicializáljunk mindent
Mielőtt bármit is tennénk a pygame-mel, meg kell bizonyosodnunk, hogy minden szükséges modul inicializálva lett. Ha ez teljesült, akkor létrehozhatunk egy egyszerű grafikus ablakot. A következőket a main() függvénybe fogjuk elhelyezni.

pygame.init()
screen = pygame.display.set_mode((468, 60))
pygame.display.set_caption('Monkey Fever')
pygame.mouse.set_visible(0)

Az első sorral inicializáljuk a pygame-et. Ellenőrzi az importált pygame modulokat, és inicializálja azokat. Lehetőségünk van saját kezűleg is inicializálni és ellenőrizni a modulokat, de erre most nem térünk ki.
A következő lépésben a képernyőt állítjuk be. Jegyezzük meg, hogy a képernyő beállításokért a pygame.display modul felelős. Ezen keresztül tudjuk azokat módosítani, stb. Jelen esetben egy üres, 468x60-as felbontású ablakot készítünk. A képernyő módok beállításának témája meghaladná ennek a tutoriálnak a kereteit. A fenti esetben ezt a feladatot a pygame elvégzi helyettünk. Végül beállítjuk az ablak címét, és eltüntetjük az egérkurzort az ablak felett. Ezzel a módszerrel egy fekete ablakhoz jutottunk.
Csináljunk hátteret
A programunk hátterében különböző szöveges üzeneteket szeretnénk megjeleníteni. Jó lenne egy egyszerű felületet készíteni, ami a programunk hátterét reprezentálná, és a továbbiakban ezt használni. Készítsük el ezt a felületet!

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250, 250, 250))

Ezzel egy új felületet hoztunk létre, melynek mérete egyezik a képernyőével. Itt is szűkség van a convert() hívásra. Az argumentum nélküli convert függvénnyel a képernyő formátumával megegyező lesz a háttér. Ezzel a programunk hatékonyságát növeljük.
Végül fehérre színezzük a hátteret. A fill művelet egy RGB hármast, egy tuple-t vár paraméternek.
Szöveg elhelyezése a háttéren
Tehát rendelkezünk egy felülettel, és ezen szeretnénk szöveget megjeleníteni. Ezt csak akkor tehetjük meg, ha a pygame.font modult megfelelően importáltuk. Ha nem, akkor átugorjuk ezt a részt.

if pygame.font:
    font = pygame.font.Font(None, 36)
    text = font.render("Pummel The Chimp, And Win $$$", 1, (10, 10, 10))
    textpos = text.get_rect(centerx=background.get_width()/2)
    background.blit(text, textpos)

Látható, hogy egy egyszerű szöveg megjelenítéséhez is több lépésre van szükség. Először létrehozunk a font objektumot és megjelenítjük azt egy új felületen. Eztán megkeressük ennek a felületnek a középpontját, majd beillesztjük a háttérbe.
Font-ot a font modul Font() konstruktorával hozhatunk létre. Paramétereiben megadhatod egy truetype fontfájl nevét. None-nal jelezhetjük az alapértelmezett betűtípus használatát. A Font konstruktorának még meg kell adni a használni kívánt font méretét.
A render függvény egy új felületet hoz létre, mely megfelelő méretű a megjelenítendő szövegnek. A paraméterekben megadjuk, hogy antialiased, sötét szürke színű szöveget akarunk kirakni.
Eztán megkeressük a szöveg középpontját. Létrehozunk egy - a szöveg dimeziónak megfelelő - Rect objektumot, ami már egyszerűen felrakható a képernyő közepére.
Végül a blit művelettel feltesszük a háttérre.
Háttér megjelenítése
Mutassuk meg a hátteret, amíg a többi erőforrás betöltésére várunk.

screen.blit(background, (0, 0))
pygame.display.flip()

Ezzel a kódrészlettel a teljes hátteret megjelenítettük a képernyőn. A blit kiteszi a screen objektumra, míg a flip a screen objektum tartalmát jeleníti meg fizikailag az ablakban/képernyőn.
A pygame-ben nem közvetlenül a fizikai képernyőre rajzolunk, hanem egy screen objektumra. Ha mindent, amit meg akarunk jeleníteni feltettünk erre, akkor egy pillanat alatt ki tudjuk rajzolni a fizikai képernyőre.
Játékobjektumok elkészítése
Elkészítjük mindazokat az objektumokat, melyek a játék futtatásához szükségesek.

whiff_sound = load_sound('whiff.wav')
punch_sound = load_sound('punch.wav')
chimp = Chimp()
fist = Fist()
allsprites = pygame.sprite.RenderPlain((fist, chimp))
clock = pygame.time.Clock()

Először betöltünk két hang effektust a load_sound függvény segítségével. Eztán létrehozunk egy-egy példányt a sprite osztályainkból. Végül a spritejainkat elhelyezzük egy Group objektumba. Ez egy tároló, amivel egyszerűbbé válik a spriteok kezelése.
Egy speciális sprite Group-ot használunk, nevezetesen egy RenderPlain-t. Ez az összes benne elhelyezett spritot meg tudja jeleníteni. Vannak ennél sokkal összetettebb Render Groupok is. A mi kis játékunkban csak a megjelenítést kell elvégeznie. A Group objektumunkra hivatkozik az allsprites referencia.
A clock objektummal szabályozhatjuk a programunk framerátáját, azaz azt, hogy legfeljebb hány képkockát jelenítsen meg a program másodpercenként. Ezt majd a főciklusban fogjuk használni.
A fő ciklus
A főciklus egy végtelen ciklus lesz.

while 1:
    clock.tick(60)

Minden játék egy hasonló ciklusban fut. A clock.tick(60)-nal garantáljuk, hogy a programunk legfeljebb 60 képkocka per másodperces sebességgel fog futni/megjeleníteni.
Események kezelése
Az eseménysor nagyon egyszerű kezelésére mutatunk példát.

for event in pygame.event.get():
    if event.type == QUIT:
        return
    elif event.type == KEYDOWN and event.key == K_ESCAPE:
        return
    elif event.type == MOUSEBUTTONDOWN:
        if fist.punch(chimp):
            punch_sound.play() #punch
            chimp.punched()
        else:
            whiff_sound.play() #miss
    elif event.type == MOUSEBUTTONUP:
        fist.unpunch()

Először elkérjük a pygame-től a rendelkezésre álló eseményeket. Ez szerepel a ciklus fejlécében. Az elágazás első két ágában két egyszerű eseményt kezelünk. Az első: a felhasználó kilépett a programból. A második: lenyomták az esc billentyűt. Ezekben az esetekben kilépünk a programból.
Eztán ellenőrizzük, hogy az egér gombja le lett-e nyomva, vagy fel lett-e engedve. Ha lenyomták a gombot, akkor megkérdezzük a fist objektumot, hogy ütközik-e a chimp objektummal. Eztán lejátsszuk a megfelelő hangeffektet, és ha eltalálta a majmot, akkor hívjuk a chimp punched metódusát. (Erre ő bepörög.)
Spriteok frissítése

allsprites.update()

A sprite csoportoknak van egy update metódusa, melynek hívására az összes tartalmazott sprite update metódusát meghívja. Ennek hatására minden frissül, ahogy azt a játék objektumoknál leírtuk.
Rajzoljunk ki mindent
A következő utasításokkal kirajzolhatjuk az objektumainkat.

screen.blit(background, (0, 0))
allsprites.draw(screen)
pygame.display.flip()

Először kirakjuk a hátteret a screen objektumra. Ezt követően a allsprites csoportnak hívjuk a draw metódusát. Ezzel az összes benne tárolt objektumot kitesszük a screen objektumra. Végül a flip függvénnyel mindent megjelenítünk a fizikai képernyőn.

Nincsenek megjegyzések:

Megjegyzés küldése