Skip to content

Kaikki WordPressistä, web-kehityksestä — ja paljon muuta

🎮 Ensimmäinen peli Pygamella: kirjoitetaan Pythonilla alusta alkaen

🎮 Ensimmäinen peli Pygamella: kirjoitetaan Pythonilla alusta alkaen

Haluatko kirjoittaa ensimmäisen pelisi, mutta et tiedä, mistä aloittaa pelinkehityksessä? Pygame poistaa tuon esteen. Kirjoitat puhdasta Pythonia ja näet tuloksen heti ruudulla: liikkuvan hahmon, näppäimistön vasteen, elävän mekaniikan. Ei raskaita moottoreita, ei tuhansia rivejä pohjakoodia.

Useimpien tutoriaalien ongelma on, että ne joko hautaavat sinut 40 sivun teoriaan tai jättävät sinut "tee loppuun itse" -vaiheeseen. Tässä valitsemme keskitien: selitämme juuri sen verran, että ymmärrät jokaisen rivin, ja rakennamme heti toimivan pelin, jossa hahmo liikkuu ruudulla WASD-näppäimillä. Koko koodi mahtuu 60 riviin.

💡 Pikakatsaus:

  • Asenna Pygame pipin kautta ja luo pelitiedosto, siihen menee pari minuuttia
  • Ymmärrä pelisilmukka: tapahtumat, laskenta, piirtäminen, kolme vaihetta, jotka elävät ikuisessa while True -silmukassa
  • Kirjoita pelaajaluokka ja herätä se henkiin: WASD-näppäimet liikuttavat spriteä, ruutu piirtyy uudelleen 60 kertaa sekunnissa
  • Ymmärrä koordinaatisto ja värien käsittely, kaksi kulmakiveä, jotka tukevat mitä tahansa 2D-grafiikkaa

Mikä Pygame on ja miksi valita se

Pygame on Python-kirjasto, joka käärii multimedia-SDL:n (Simple DirectMedia Layer) kätevään Python-rajapintaan. SDL hoitaa matalan tason grafiikan, äänen ja syötelaitteiden työn, kun taas Pygame tarjoaa pääsyn tuttujen luokkien ja metodien kautta. Nykyinen versio 2.6.0 on aktiivisesti ylläpidetty ja toimii Windowsilla, macOS:llä ja Linuxilla.

Aloittelijalle Pygamessa on kolme kiistatonta etua. Ensinnäkin matala aloituskynnys: käytät tavallista Python-koodia, ei uutta kieltä tai visuaalista editoria. Toiseksi välitön palaute: kirjoitat pygame.draw.rect(...) ja suorakulmio ilmestyy ruudulle, ei taikuutta. Kolmanneksi perustan ymmärtäminen: Pygame ei piilota pelisilmukkaa ja tapahtumajonoa sinulta, näet miten mikä tahansa peli toimii sisältä. Pygamen jälkeen Godotiin tai Unityyn siirtyminen on helpompaa, koska tiedät jo, mitä delta-aika ja tapahtumien pollaus ovat.

Kirjasto ei yritä olla pelimoottori. Siinä ei ole skenejärjestelmää, fysiikkaa eikä sisäänrakennettua kenttäeditoria, ja se on tietoinen päätös. Hallitset jokaista pikseliä ja jokaista tikitystä, mikä tarkoittaa, että opit ajattelemaan kuin pelinkehittäjä, et kuin jonkun toisen työkalun käyttäjä.

Pygamen asennus kahdessa minuutissa

Onko sinulla jo Python 3.9 tai uudempi? Avaa sitten pääte ja aja yksi komento:

1pip install pygame

Projektin eristämiseksi on parempi luoda virtuaaliympäristö:

1python -m venv game_env
2game_env\Scripts\activate # Windows
3source game_env/bin/activate # macOS / Linux
4pip install pygame

Tarkista, että kirjasto on asennettu:

1import pygame
2print(pygame.version.ver)

Jos vastauksena tulee 2.6.0 (tai uudempi, voit tarkistaa nykyisen version osoitteesta pygame.org), olet valmis. Luo projektikansio, laita sinne mikä tahansa 80×80 pikselin sprite-kuva nimellä player.png ja tekstitiedosto game.py, aloitamme siitä.

Miten pelisilmukka toimii: tapahtumat, laskenta, piirtäminen

Minkä tahansa pelin sydän on pääsilmukka. Pelin ollessa käynnissä ikuisen while True -silmukan sisällä vuorottelee kolme vaihetta:

  • Tapahtumien käsittely, mitä on tapahtunut edellisen ruudun jälkeen? Näppäintä painettu? Hiirtä liikutettu? Ikkuna suljettu? Pygame kerää kaikki tapahtumat jonoon, ja käymme sen läpi for event in pygame.event.get() -silmukalla.

  • Logiikan laskenta, miten maailma muuttui vasteena tapahtumiin? Pelaaja painoi W:tä, kasvata Y-koordinaattia. Luoti törmäsi asteroidiin, merkitse molemmat poistettaviksi.

  • Piirtäminen, piirrä kaikki, minkä pitäisi olla ruudulla. Täytä tausta, aseta spritet uusiin koordinaatteihin, kutsu pygame.display.update(), ja pelaaja näkee yhden ruudun.

Nämä kolme vaihetta toistuvat 60 kertaa sekunnissa, juuri se kuvataajuus (FPS), jonka asetamme ajastimeen. Liikkeen illuusio rakentuu siitä, että sprite siirtyy muutaman pikselin ruutujen välillä, kun silmä havaitsee tämän jatkuvana animaationa.

Ensimmäisen koodin kirjoittaminen: spriten liikuttaminen ruudulla

Tässä on koko pelin koodi. Tallenna se nimellä game.py ja laita player.png samaan kansioon:

1#!/usr/bin/env python3
2
3import pygame
4import sys
5
6WIDTH, HEIGHT = 360, 480
7WHITE = (255, 255, 255)
8
9class Player(pygame.sprite.Sprite):
10
11 def __init__(self, image_path):
12 super().__init__()
13 self.image = pygame.image.load(image_path)
14 self.x = WIDTH / 2
15 self.y = HEIGHT / 2
16 self.speed = 5
17
18 def move(self, dx, dy):
19 self.x += dx
20 self.y += dy
21
22def main():
23 pygame.init()
24 screen = pygame.display.set_mode((WIDTH, HEIGHT))
25 pygame.display.set_caption("First Game on Pygame")
26
27 clock = pygame.time.Clock()
28 fps = 60
29
30 player = Player("player.png")
31 dx, dy = 0, 0
32
33 running = True
34 while running:
35 for event in pygame.event.get():
36 if event.type == pygame.QUIT:
37 running = False
38
39 elif event.type == pygame.KEYDOWN:
40 if event.key == pygame.K_d:
41 dx = player.speed
42 elif event.key == pygame.K_a:
43 dx = -player.speed
44 elif event.key == pygame.K_w:
45 dy = -player.speed
46 elif event.key == pygame.K_s:
47 dy = player.speed
48
49 elif event.type == pygame.KEYUP:
50 if event.key in (pygame.K_d, pygame.K_a):
51 dx = 0
52 elif event.key in (pygame.K_w, pygame.K_s):
53 dy = 0
54
55 player.move(dx, dy)
56 screen.fill(WHITE)
57 screen.blit(player.image, (player.x, player.y))
58 pygame.display.update()
59 clock.tick(fps)
60
61 pygame.quit()
62 sys.exit()
63
64if __name__ == "__main__":
65 main()
80x80 pelaajahahmo ruudulla liikkumista varten

Aja python game.py, niin avautuu ikkuna, jossa on valkoinen tausta ja spritesi keskellä. Pidä W, A, S tai D pohjassa, hahmo liikkuu. Vapauta näppäin, se pysähtyy. Tämä on jo oikea peli, vaikkakin minimaalinen.

Mitä on parannettu verrattuna klassisiin tutoriaaleihin: KEYUP-käsittelijä on lisätty näppäimen vapauttamista varten. Ilman sitä sprite matkaisi ikuisesti pois ruudulta ensimmäisen painalluksen jälkeen. Ja koodi on kääritty if __name__ == "__main__" -rakenteeseen, hyvä käytäntö, joka sallii tiedoston tuomisen moduulina käynnistämättä peliä.

Koordinaatisto ja värien käsittely

Pygamessa koordinaatit lasketaan vasemmasta yläkulmasta: (0, 0) on aivan vasen yläkulma. Oikealle liikkuminen kasvattaa X:ää, alas liikkuminen kasvattaa Y:tä. Tämä poikkeaa koulun koordinaatistosta, jossa Y kasvaa ylöspäin, muista tämä ja tarkista itsesi kahdella ensimmäisellä ajokerralla: painoit S:ää, sprite liikkui alas, painoit W:tä, ylös.

Väri määritellään kolmen luvun monikkona (R, G, B), kukin väliltä 0-255. Valkoinen vastaa arvoa (255, 255, 255), musta vastaa arvoa (0, 0, 0), punainen vastaa arvoa (255, 0, 0). screen.fill(WHITE)-metodi täyttää koko ruudun valitulla värillä ennen jokaisen ruudun piirtämistä. Jos et tee tätä, sprite jättää jälkeensä vanan aiemmista sijainneista.

Mitä konepellin alla tapahtuu: rivi riviltä -purku

Player-luokka perii pygame.sprite.Sprite-luokan, Pygamen sisäänrakennetun luokan peliobjekteille. Konstruktorissa lataamme kuvan pygame.image.load()-metodilla ja asetamme aloituspaikan ruudun keskelle: WIDTH / 2 ja HEIGHT / 2. move(dx, dy)-metodi vastaanottaa siirtymän ja lisää sen nykyisiin koordinaatteihin, puhdasta aritmetiikkaa, ei taikuutta.

main()-funktio kokoaa kaiken yhteen. pygame.init() käynnistää sisäiset alijärjestelmät. pygame.display.set_mode() luo ikkunan, ja screen on Surface, jolle piirrämme. pygame.time.Clock() luo ajastimen: sen tick(fps)-metodi silmukan lopussa kertoo Pygamelle "odota, kunnes 1/60 sekuntia on kulunut edellisestä ruudusta", näin kiinnitämme kuvataajuuden emmekä tuhlaa suoritinta.

Pääsilmukka while running pyörii, kunnes running-lippu muuttuu arvoon False. Sisällä kolme vaihetta, joista puhuimme yllä:

Pygame-peli-ikkuna ja hahmosprite valkoisella taustalla

for event in pygame.event.get() -silmukassa pollaamme tapahtumajonoa. pygame.QUIT on signaali "käyttäjä klikkasi ikkunan sulkemispainiketta": aseta running = False, ja seuraavalla iteraatiolla silmukka päättyy. pygame.KEYDOWN laukeaa, kun näppäintä painetaan, ja KEYUP, kun se vapautetaan. D:lle ja A:lle muutamme dx:ää, W:lle ja S:lle muutamme dy:tä. Kun näppäin vapautetaan, nollaamme vastaavan nopeuskomponentin, sprite pysähtyy.

screen.blit(player.image, (player.x, player.y)), metodi, joka "liimaa" yhden kuvan toisen päälle. Meidän tapauksessamme pelaajan spriten pääruutupinnalle nykyisiin koordinaatteihin. pygame.display.update() päivittää ikkunan, ja pelaaja näkee valmiin ruudun.

Huomio: player.move() kutsutaan ennen screen.fill()-metodia. Jos vaihdat niiden järjestyksen, sprite pyyhkiytyy pois samalla millisekunnilla kun se ilmestyy, et yksinkertaisesti näe sitä ruudulla. Operaatioiden järjestys pelisilmukassa on kriittinen.

Klikkaa sulkemispainiketta, pygame.quit() purkaa Pygamen alijärjestelmät oikein, ja sys.exit() lopettaa Python-prosessin. Ilman pygame.quit()-kutsua ikkuna voi jäätyä suljettaessa, pieni yksityiskohta, mutta koodin tulisi olla siistiä.

Lyhyt video aiheesta

Jos tekstiohje ei aivan avaudu, tässä on erinomainen englanninkielinen videokurssi, jossa rakennetaan Space Invaders Pygamella askel askeleelta. Kaikki artikkelin käsitteet näytetään livenä:

⁉️🤔 Usein kysytyt kysymykset

Tarvitseeko minun osata olio-ohjelmointia Pygamea varten?

Kyllä, perustasolla. Luokkia, metodeja, perintää ja self-viitettä tarvitset heti ensimmäisestä päivästä lähtien: pelaaja, viholliset, luodit ja bonukset asettuvat luontevasti oliomalliin. Jos olet suorittanut minkä tahansa Pythonin peruskurssin, joka selitti class- ja __init__-käsitteet, se riittää. Loput opit matkan varrella: Pygame ei vaadi suunnittelumalleja, tavallinen perintä Sprite-luokasta riittää kymmeniin prototyyppeihin. Peliobjekti Pygamessa on luokka, joka perii pygame.sprite.Sprite-luokan. Konstruktorissa lataat spriten pygame.image.load()-metodilla, asetat alkukoordinaatit ja nopeuden. update()-metodi (tai oma metodisi, kuten move()) muuttaa sijaintia joka ruudulla. Pääsilmukka kutsuu update()-metodia kaikille objekteille ja piirtää ne sitten screen.blit()-metodilla. Ei taikuutta, vain metodien kutsumista oikeassa järjestyksessä 60 kertaa sekunnissa.

Hidastuuko Pygame monimutkaisessa 2D-grafiikassa?

Kohtuullisella sprite-määrällä ei. Surfacen Pygamessa elävät RAM-muistissa, ja blit on nopeaa pikselikopiointia, ei ohjelmallista renderöintiä. Tuhannen samanaikaisesti liikkuvan objektin kanssa saatat törmätä Pythonin suorituskyvyn rajaan, mutta tasohyppelyyn, ylhäältä kuvattuun räiskintään tai tornipuolustuspeliin tehoa riittää. Jos haluat puristaa maksimaalisen suorituskyvyn, käytä pygame.sprite.Group-ryhmää automaattisella piirrolla ja dirty rectangle -tekniikkaa osittaisia ruudunpäivityksiä varten.

Voinko lisätä ääniä ja musiikkia Pygamessa?

Kyllä, suoraan paketista. pygame.mixer-moduuli voi toistaa WAV- ja MP3-tiedostoja. Laukauksen ääni käynnistetään pygame.mixer.Sound("shoot.wav").play()-kutsulla, ja taustamusiikki ladataan pygame.mixer.music.load("theme.mp3")- ja pygame.mixer.music.play(-1)-kutsuilla (-1-lippu toistaa sitä silmukassa). Ainoa huomio: pygame.mixer.init() täytyy kutsua ennen äänien lataamista, ja MP3-tiedostoille Linuxissa saatat tarvita libmpg123-kirjaston.

Onko Pygamen opettelussa mitään järkeä vuonna 2026, kun on Godot ja Unity?

Ehdottomasti. Pygame ei ole Godotin kilpailija, se on opetustyökalu ja kevyt kerros 2D-prototyyppeihin. Et opettele C#:ää vain liikuttaaksesi neliötä, etkä selvitä noodijärjestelmää Pongia varten. Pygame antaa sinulle ymmärryksen siitä, miten pelit toimivat alemmalla tasolla: pelisilmukka, ruutupuskurointi, törmäykset. Pygamella aloittaneiden ohjelmoijien on helpompi siirtyä Unityyn ja Godotiin, koska he näkevät elävän mekaniikan moottorin abstraktioiden takana. Pygamella kirjoitetaan oikeita indie-projekteja, myös kaupallisia, pienen tasohyppelyn tai pulmapelin voi julkaista Steamissa koskematta C++:aan.

Mitä tehdä, jos sprite menee ulos ruudulta?

Lisää reunojen tarkistus move()-metodiin: jos self.x < 0, aseta se nollaksi; jos self.x + sprite_width > WIDTH, aseta se arvoon WIDTH - sprite_width. Sama Y:lle. Tätä kutsutaan rajoittamiseksi, ja ilman sitä hahmo matkaa lopulta näkymättömälle alueelle. Kehittyneemmissä peleissä rajat ovat kentän seiniä, jotka on määritelty ruudukon tai törmäystaulukon avulla.

Valmis käynnistämään ensimmäisen pelisi?

Kopioi koodi "Ensimmäisen koodin kirjoittaminen" -osiosta, tallenna se nimellä game.py, laita viereen mikä tahansa sprite-kuva, ja muutamassa sekunnissa näet ikkunan, jossa on liikkuva hahmo. Tämä on sisäänkäynti pelinkehitykseen: ei lukemista, vaan käynnistämistä ja parametrien säätämisen aloittamista.

Muuta WIDTH ja HEIGHT, ikkuna suurenee. Aseta player.speed = 10, hahmo nopeutuu. Korvaa WHITE arvolla (35, 35, 35), saat tumman taustan. Kokeile, ja ymmärrät, että peliohjelma ei ole taikuutta, vaan askelsarja, jota hallitset.

Kun olet hallinnut liikkumisen, tartu törmäyksiin (pygame.sprite.collide_rect()), animaatioon (sprite-arkin ruudunvaihto) ja proseduraaliseen kenttägenerointiin. Alkuun riittää yksi game.py-tiedosto ja halu ymmärtää, miten se toimii.