Ügyességi játékok programozása
Pythonnal és Pygame-mel

Chapter 16: Tömb háttérrel rendelkező (térkép)rácsok

16.1 Bevezetés

Videó: Tömb háttérrel rendelkező rácsok

Az olyan játékok, mint az aknakereső, vagy a tic-tac-toe, és más kaland játékok tartalmaznak adatokat egy számokkal ellátott rácsról. Például, a tic-tac-toe tábla:

 OO
 X 
X  

...használhatunk egy rácsot, számokkal, ami az üres helyeket jelzi, az 0 és X meg is teszi:

022
010
100

Ez a számrács más néven kétdimenziós tömb vagy mátrix. (Végre, tanulunk a Mátrixról.) A számok értéke a rácsban azt mutatják, hogy minek kell megjelennie az adott táblázati helyen. A fenti példa szerint, a 0 egy olyan helyet jelöl, ahol senki se játszott, az 1 az egy X, a 2 pedig egy O.

fig.minesweeper
Figure 16.1: Aknakereső játék, láthatjuk a háttérben lévő számrácsot

ábra 16.1 egy példa a klasszikus aknakereső játékra. Ebben a példában bal oldalt a klasszikus nézetet látjuk, míg jobbra a számrácsot figyelhetjük.

A 10-s szám aknát jelent, a 0-s meg olyat, ahová még nem kattintottak, és a 9-s szám egy megtisztított mezőt jelent. Az 1 és 8 számok azt jelentik, hogy mennyi akna van a körülötte lévő nyolc mezőn, és csak akkor jelenik meg, amikor a felhasználó rákattint.

Aknakeresőben valójában két rács van. Egyik az felhasználó által látható, a másik egy teljesen másféle, ahol nyomon követhető a mindenféle mozgás, és változás, és látható minden akna is.

Klasszikus kalandjátékok térképe is csempeszerű térképszerkesztőt használ. Ezek a hatalmas rácsok, ahol minden egyes szám egy tereptípust jelöl. A terep lehet kosz, út, ösvény, zöld fű, barna fű, és így tovább. Az olyan programok, mint a Tiled Qt látható az ábrán 16.2. Ez lehetővé teszi a játékkészítőnek, hogyan könnyebben készítse el ezeket a térképeket, és elmenthesse rács képében a lemezre.

fig.qt_tiled
Figure 16.2: Qt csempék használata egy kalandozó térkép megrajzolásakor

A kalandjátékok használnak megtöbbszörözött rácsokat, mint ahogyan az aknakereső is nyilvántartja az aknákat és elkülöníti a zászlós rácsokat. Egy rács, vagy réteg, a kalandjátékban jelképezheti a terepet, amin sétálhatsz, a másik dolog jelképezheti azt, amin nem sétálhatsz át, ilyen a fal, vagy a fa. Egy másik réteg azonnal megölhet, mint egy láva, vagy feneketlen gödör. Másik réteg létezhet, ahol tárgyakat vehetsz fel és mozgathatsz. És még egy, hogy szörnyeket tudj elhelyezni.

Az ilyen térképeket betöltheted a Python programba de sajnos az, hogy pontosan hogyan is kell, túlmutat ennek a könyvnek a határain. Az olyan projektek, mint a PyTMX biztosíthatják a kódokat, amikkel az ilyen térképek kezelhetők.

16.2 Alkalmazások

Elég volt a beszédből, írjunk kódot. Ez a példa egy rácsot fog készíteni, ami úgy jelenik meg, mint egy fehér vagy zöld négyzet. Meg leszünk képesek változtatni a rács értékét, zöldre, ha rákattintunk. Ez az első lépés egy rácson alapuló játékhoz, mint amilyen az aknakereső, csatahajó, connect four, stb. (Az egyik évben az egyik diákom úgy módosított egy programot, hogy az az én nevemet jelenített meg villogó fényekkel. Hát ez... elég zavaró volt. Szóval, kérlek használd ezt a tudást jóra!)

Irány a példa kód oldal és töltsd le az alap sablont:
ProgramArcadeGames.com/python_examples/f.php?file=pygame_base_template.py

Kezdjük az üres sablon fájlunkkal, gyártsuk újra ezt a programot azáltal, hogy követjük az itt leírtakat. A végső program a fejezet végén lesz, de ne ugorj egyből oda, hogy csak átmásold. Ha ezt teszed, akkor semmit sem fogsz tanulni. Bárki képes lemásolni és beilleszteni egy kódot. De, ha újra akarod írni a programot, akkor kövesd a példákat, amiket itt leírok. Ha csak másolsz és beillesztesz, akkor az idődet vesztegeted itt.

    16.2.1 A rács kirajzolása

  1. Állítsuk be az ablak méretét 255x255 pixelre.
  2. Hozzunk létre változókat és nevezzük el őket úgy, hogy width(szélesség) és height(magasság), és margin(margó). Állítsuk be a szélességet és magasságot 20-ra. Ez fogja mutatni, hogy milyen nagy lesz egy rács. Állítsuk be a margót 5-re. Ez fogja mutatni, hogy mennyi lesz a margó nagysága két rács között. Még a főprogram előtt hozzuk létre ezeket a változókat.
  3. Rajzoljunk egy kicsi fehér dobozt, a bal felső sarokba. Rajzoljuk ki úgy, hogy a korábban létrehozott szélesség és magasság változókat használjuk. (Nyugodtan adj hozzá tetszőleges színt.) Ha készen vagy a program ablakával, akkor vess egy pillantást az ábrára: 16.3.
    step_03
    Figure 16.3: Harmadik lépés
  4. Használj for ciklust, hogy kirajzold a 10 dobozt, a sorban. Azután használd a column (oszlop) nevű változót a ciklusban. A kimenet olyan lesz, mint egy hosszú doboz, de még hozzá kell adnunk a margót a dobozokhoz. Ábra 16.4.
    step_04
    Figure 16.4: Negyedik lépés
  5. Egészítsük ki a rajzunkat a margó változó hozzáadásával. Most már lesz egy kis hely a négyszögek közt. Lásd az ábrát: 16.5.
    step_05
    Figure 16.5: Ötödik lépés
  6. Add hozzá a margót mielőtt kirajzolnád a négyszöget. Minden négyszöghöz. Ez képes a dobozokat a képernyőn belül tartani. Lásd a következő ábrát: 16.6.
    step_06
    Figure 16.6: Hatodik lépés
  7. Adj még egy for ciklust, ami végig megy majd minden soron. Nevezd ezt a változót a for ciklusban úgy, hogy row/sor. Most már megvan az összes kis dobozod a rácsban. Lásd az ábrát: 16.7.
    step_07
    Figure 16.7: Hetedik lépés

    16.2.2 A rácsok feltöltése

  8. Most már szükségünk van egy kétdimenziós tömbre. Egy kétdimenziós tömb létrehozása a Pythonban, sajnos, nem olyan könnyű mint más nyelvekben. Vannak olyan könyvtárak, melyeket letöltve megkönnyíthetjük a dolgunkat, de ezt a példát muszáj megismernünk. Ahhoz, hogy egy kétdimenziós tömböt készítsünk, használjuk az alábbi példát:
    # --- számokból álló rács készítése
    # készítsünk egy üres listát
    grid = []
    # minden soron menjünk át egy ciklussal
    for row in range(10):
        # minden sorban hozzunk létre egy listát, ami
        # egy teljes sort fog jeölni
        grid.append([])
        # menjünk át minden oszlopon
        for column in range(10):
            # adjunk nulla értéket az adott sorhoz
            grid[row].append(0)
    

    Egy sokkal rövidebb példa látható lentébb, és ez a példa néhány sajátos Python részt is tartalmaz, amivel nem foglak zaklatni ebben a könyvben.

    grid = [[0 for x in range(10)] for y in range(10)]
    

    Használjuk a két példa közül az egyiket, hogy megalkossuk a saját tömbünket, a főprogramunkhoz.

  9. Az egyik tetszőleges helyet a tömbben állítsuk 1-re.

    Kétdimenziós tömbök általában az első sortól számoljuk, és azután az oszloptól. Ezt nevezik sor-fontossági tárolásnak. A legtöbb nyelvben sor-fontossági tárolás történik. A kivételek a Fortran és a MATLAB. Ezek oszlop-fontossági tárolást valósítanak meg.

    # Állítsuk az első sort, és az ötödik oszloport nullára
    grid[1][5] = 1
    

    Tegyük ezt a kódot valahová főprogramunkba.

  10. Válasszuk ki a négyzet színét, amit a color változónk határoz meg. Ezt tegyük meg minél előbb. Ehhez, készítsünk egy változót, amit majd elnevezünk color/színnek, állítsuk ezt be fehérre. Azután módosítsuk a fehér színt, a color értékének megváltoztatásával.
  11. Válasszuk ki a színt, amit az adott rácsponton szeretnénk látni. Azután változtassuk a színt fehérre, majd tegyünk be egy if feltételt, ami eldönti, hogy a színt zöldre változtatja, a grid[row][column] rácson, ha a rács értéke egy. Most lennie kéne egy zöld rácsnak. Lásd ábra: 16.8.
    step_11
    Figure 16.8: Tizenegyedik lépés
  12. írjuk ki, hogy "click" a képernyőre, amikor a felhasználó kattint egyet az egérrel. Lásd a
    bitmapped_graphics.py-t azzal kapcsolatban, hogyan kezeljünk egérgomb kattintást, és hogyan ismerje fel azt a kód.
  13. Írassuk ki az egér koordinátáját, amikor a felhasználó kattint egyet.
    Lásd a move_mouse.py azért, hogy meg tudd határozni az egér helyzetét. Lásd az ábrát 16.9.
    step_13
    Figure 16.9: Tizenharmadik lépés
  14. Alakítsuk át az egér koordinátáit rács koordinátákká. Írassuk most már ki ezeket. Ne felejtsd el használni a magasság és szélesség értékeket minden rácshelynél, valamint a margókat. Még az eredményt át kell alakítani egész számmá. Ezt úgy tehetjük meg, hogy használjuk az int-t, vagy pedig az egész részes osztás operandust: //. Lásd a következő ábrát: 16.10.
    step_14
    Figure 16.10: Tizennegyedik lépés
  15. Adjuk meg a rácshely értékét a sor/oszlop szerint, amire rákattintottak egynek. Lásd az ábrát 16.11.
    step_15
    Figure 16.11: Tizenötödik lépés

16.2.3 Végső program

"""
 Example program to show using an array to back a grid on-screen.

 Sample Python/Pygame Programs
 Simpson College Computer Science
 http://programarcadegames.com/
 http://simpson.edu/computer-science/

 Explanation video: http://youtu.be/mdTeqiWyFnc
"""
import pygame

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 20
HEIGHT = 20

# This sets the margin between each cell
MARGIN = 5

# Create a 2 dimensional array. A two dimensional
# array is simply a list of lists.
grid = []
for row in range(10):
    # Add an empty array that will hold each cell
    # in this row
    grid.append([])
    for column in range(10):
        grid[row].append(0)  # Append a cell

# Set row 1, cell 5 to one. (Remember rows and
# column numbers start at zero.)
grid[1][5] = 1

# Initialize pygame
pygame.init()

# Set the HEIGHT and WIDTH of the screen
WINDOW_SIZE = [255, 255]
screen = pygame.display.set_mode(WINDOW_SIZE)

# Set title of screen
pygame.display.set_caption("Array Backed Grid")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop -----------
while not done:
    for event in pygame.event.get():  # User did something
        if event.type == pygame.QUIT:  # If user clicked close
            done = True  # Flag that we are done so we exit this loop
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # User clicks the mouse. Get the position
            pos = pygame.mouse.get_pos()
            # Change the x/y screen coordinates to grid coordinates
            column = pos[0] // (WIDTH + MARGIN)
            row = pos[1] // (HEIGHT + MARGIN)
            # Set that location to one
            grid[row][column] = 1
            print("Click ", pos, "Grid coordinates: ", row, column)

    # Set the screen background
    screen.fill(BLACK)

    # Draw the grid
    for row in range(10):
        for column in range(10):
            color = WHITE
            if grid[row][column] == 1:
                color = GREEN
            pygame.draw.rect(screen,
                             color,
                             [(MARGIN + WIDTH) * column + MARGIN,
                              (MARGIN + HEIGHT) * row + MARGIN,
                              WIDTH,
                              HEIGHT])

    # Limit to 60 frames per second
    clock.tick(60)

    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit()

és kezdj bele a saját videó játékodba!

16.2.4 Kvízkérdések

Click here for a multiple-choice quiz.

16.2.5 Feladatlapok

Click here for the chapter worksheet.


You are not logged in. Log in here and track your progress.