Tehdään pelistä sellainen, että taivaalta tippuu kiviä, joita täytyy väistää, ja kolikoita, joita täytyy kerätä. Pelissä ei ole vielä maata. Sen voi luoda näin:

ground_color = (171, 237, 130)
ground_start_y = 550
ground = pygame.Rect(0, ground_start_y, window_width, window_height - ground_start_y)

Ensin määritellään maan väri, sitten sen y-koordinaatti, ja sitten sitä edustava suorakulmio. Suorakulmion luova funktio ottaa argumentiksi suorakulmion x-koordinaatin, y-koordinaatin, leveyden ja korkeuden. Suorakulmio on siis yhtä leveä kuin ikkuna, ja korkeus on ikkunan korkeuden ja maan y-koordinaatin erotus.

Lisätään while-silmukkaan koodirivi joka piirtää suorakulmion:

pygame.draw.rect(window, ground_color, ground)

Suorakulmion piirtämisfunktio ottaa argumentiksi ikkunan, johon suorakulmio piirretään, suorakulmion värin, ja itse suorakulmion. Muista lisätä tämä rivi sopivaan kohtaan, niin että maa ei jää taustavärin taakse.

Nyt leppiksen y-koordinaatti saattaa olla väärässä kohtaa maahan nähden. Vaihda y-koordinaatti tähän:

leppis_y = ground_start_y - leppis_image.get_height() + 12

Y-koordinaatti muodostuu kolmesta osasta. Jos se olisi vain maan y-koordinaatti niin leppis olisi maan alapuolella, joten y-koordinaatista vähennetään leppiksen korkeus. Lisäksi koordinaattiin lisätään 12 pikseliä (leppistä siirretään 12 pikseliä alaspäin), jotta leppiksen kuvassa näkyvä taaempi jalka osuisi myös maahan.

Luodaan sitten kolikot ja kivet. Voit käyttää näitä kuvia:

kiven kuva kolikon kuva

Anna kivelle nimeksi rock.png ja kolikolle coin.png. Ladataan kuvat näin:

rock_image = pygame.image.load("rock.png")
coin_image = pygame.image.load("coin.png")

Muista laittaa nämä muuttujat while-silmukan ulkopuolelle. Kuvia ei tarvitse ladata montaa kertaa.

Tämän jälkeen määritellään funktio, joka palauttaa satunnaisen x-koordinaatin. Tarkoitus on siis luoda välillä satunnaiseen kohtaan kivi tai kolikko. Satunnaisen numeron generoimista varten täytyy importata random-kirjasto. Eli lisää import pygame-rivin jälkeen toinen rivi:

import random

Nyt voimme määritellä satunnaisen x-koordinaatin palauttavan funktion. Määrittele funktio kuvien lataamisen jälkeen. Funktio random.randint() ottaa kaksi numeroa argumentikseen, ja palauttaa satunnaisen numeron näiden väliltä. Tähän tarkoitukseen sopii numero, joka on nollan ja ikkunan leveyden välillä. Jos et halua, että kivet tai kolikot saattavat ilmestyä ikkunan oikean reunan ulkopuolelle, vähennä toisesta luvusta kiven kuvan leveys:

def random_x():
    return random.randint(0, window_width - rock_image.get_width())

Sitten luodaan kaksi listaa. Ensimmäiseen listaan tulee kivien koordinaatit, ja toiseen kolikoiden koordinaatit. Nämä listat sisältävät kahden numeron listoja, siis tähän tapaan:

[ [122,201], [530,32], [209,423] ]

Määritellään listat. Aluksi niissä täytyy olla vain yksi kivi/kolikko. X-koordinaatiksi tulee satunnainen luku, ja y-koordinaatiksi -50. Y-koordinaatti on negatiivinen sen takia, että uusien kivien ja kolikoiden ilmestyminen ei näy pelaajalle (ne ilmestyvät ikkunan ulkopuolelle).

rocks = [ [random_x(), -50] ]
coins = [ [random_x(), -50] ]

Näihin listoihin lisäämme siis uudet kivet ja kolikot. Tehdään while-silmukan sisälle koodi, joka lisää joskus uusia kiviä ja kolikoita. Tämän voi tehdä vaikka niin, että ensin generoidaan satunnainen numero väliltä 0-100. Jos numero on pienempi kuin 5, niin luodaan uusi kivi. Jos numero on suurempi kuin 95, luodaan uusi kolikko. Useimmiten ei luoda mitään. Koodi näyttää tältä:

while running:
    # ...

    random_num = random.randint(0,100)
    if random_num < 5:
        rocks.append([random_x(), -50])
    elif random_num > 95:
        coins.append([random_x(), -50])

    # ...

Append-komento lisää listaan uuden alkion.

Sitten meidän täytyy kirjoittaa koodi, joka siirtää kiviä ja kolikoita alaspäin. Määritä koodin alkuun gravity-muuttuja, joka määrää, kuinka paljon niitä siirretään jokaisella while-silmukan kierroksella:

gravity = 6

Kirjoitetaan for-silmukka, joka siirtää jokaista kiveä alaspäin painovoiman verran.

for rock_coords in rocks:
    rock_coords[1] += gravity

Tässä siis rock_coords tarkoittaa rocks-listan alkiota, eli kaksialkioista listaa jossa on kiven x- ja y-koordinaatti. Rivillä rock_coords[1] += gravity lisätään listan toiseen alkioon eli y-koordinaattiin painovoima. Numero on 1 eikä 2 sen takia, että listan järjestysluvut alkavat nollasta ykkösen sijaan.

Haluamme myös poistaa kiviä, jos ne osuvat maahan. Maahan osumisen tunnistaa siitä, että kiven y-koordinaatti on suurempi kuin maan y-koordinaatin ja kiven kuvan korkeuden erotus. Listasta poistetaan alkioita remove-komennolla. Listasta ei kuitenkaan saa poistaa alkioita sellaisen for-silmukan sisällä, joka käy listaa läpi, koska for-silmukka menee sekaisin listan pituuden muuttuessa. Tehdään siis uusi lista, johon kerätään kaikki poistettavat kivet, ja for-silmukan jälkeen tehdään uusi for-silmukka, joka poistaa listasta poistettavat kivet. Siis näin:

deleted_rocks = []
for rock_coords in rocks:
    rock_coords[1] += gravity 
    if rock_coords[1] > ground_start_y - rock_image.get_height():
        deleted_rocks.append(rock_coords)
for rock in deleted_rocks:
    rocks.remove(rock)

Huomaa, että += tarkoittaa sitä, että muuttujaan lisätään jokin arvo, ja uusi arvo tallennetaan muuttujaan. Eli nämä kaksi riviä tarkoittavat samaa asiaa:

muuttuja = muuttuja + 5
muuttuja += 5

Sitten kirjoitetaan samanlainen silmukka kolikoille:

deleted_coins = []
for coin_coords in coins:
    coin_coords[1] += gravity    
    if coin_coords[1] > ground_start_y - coin_image.get_height():
        deleted_coins.append(coin_coords)
for coin in deleted_coins:
    coins.remove(coin)

Nyt kiviä ja kolikoita ilmestyy välillä, ja ne liikkuvat alaspäin kunnes osuvat maahan. Kuitenkaan niitä ei voi vielä nähdä, koska niitä ei piirretä ikkunaan. Lisätään kaksi silmukkaa, jotka piirtävät jokaisen kiven ja kolikon ikkunaan:

for rock_coords in rocks:
    window.blit(rock_image, rock_coords)
for coin_coords in coins:
    window.blit(coin_image, coin_coords)

Laita nämä silmukat sen rivin viereen, jossa piirretään leppis.

Voit säätää leppiksen nopeutta isommaksi, jos haluat.

Nyt pelissä näkyy paljon putoavia kiviä ja kolikoita. Koko koodi näyttää tältä:

import pygame
import random

window_width = 1000
window_height = 800
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Leppispeli")

fps = 60
clock = pygame.time.Clock()

white = (255, 255, 255)

ground_color = (171, 237, 130)
ground_start_y = 550
ground = pygame.Rect(0, ground_start_y, window_width, window_height - ground_start_y)

leppis_image = pygame.image.load("leppis.png")
leppis_x = 350
leppis_y = ground_start_y - leppis_image.get_height() + 12
leppis_speed = 7

rock_image = pygame.image.load("rock.png")
coin_image = pygame.image.load("coin.png")

def random_x():
    return random.randint(0, window_width - rock_image.get_width())

rocks = [ [random_x(), -50] ]
coins = [ [random_x(), -50] ]

gravity = 6

running = True

while running:
    clock.tick(fps)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    rand_num = random.randint(0,100)
    if rand_num < 5:
        rocks.append([random_x(), -50])
    elif rand_num > 95:
        coins.append([random_x(), -50])

    pressed_keys = pygame.key.get_pressed()

    if pressed_keys[pygame.K_LEFT] and leppis_x - leppis_speed > 0:
        leppis_x = leppis_x - leppis_speed
    right_boundary = window_width - leppis_image.get_width()
    if pressed_keys[pygame.K_RIGHT] and leppis_x + leppis_speed < right_boundary:
        leppis_x = leppis_x + leppis_speed
    
    deleted_rocks = []
    for rock_coords in rocks:
        rock_coords[1] += gravity 
        if rock_coords[1] > ground_start_y - rock_image.get_height():
            deleted_rocks.append(rock_coords)
    for rock in deleted_rocks:
        rocks.remove(rock)

    deleted_coins = []
    for coin_coords in coins:
        coin_coords[1] += gravity    
        if coin_coords[1] > ground_start_y - coin_image.get_height():
            deleted_coins.append(coin_coords)
    for coin in deleted_coins:
        coins.remove(coin)
    
    window.fill(white)
    pygame.draw.rect(window, ground_color, ground)
    window.blit(leppis_image, (leppis_x, leppis_y))
    for rock_coords in rocks:
        window.blit(rock_image, rock_coords)
    for coin_coords in coins:
        window.blit(coin_image, coin_coords)
    pygame.display.update()

Seuraava artikkeli: Elämät ja pisteet