Peliohjelmointi – Pygame

1. Perustehtävät

Asennukset ja Pygame tutuksi

Ensimmäinen Pygame-sovellus

Tehtävä 1
#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

# Peli-ikkunan määritys
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("Terve Pygame")

Ikkuna välähtää ja sulkeutuu heti, koska ohjelmassasi ei ole pelisilmukkaa eikä tapahtumankäsittelyä. Kun Python suorittaa viimeisen rivin, ohjelma päättyy välittömästi, koska Pygame-ikkuna pysyy “hengissä” vain kun ohjelma on käynnissä.

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

# Peli-ikkunan määritys
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("Terve Pygame")

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

# Pygame lopetus/sulku
pygame.quit()
c. Muokkaa koodia niin, että peli-ikkunan koko muuttuu ja vaihda peli-ikkunan otsikoksi oma nimi ja luokka. Kokeile useita eri kokoja peli-ikkunalle. Tee muutokset muuttujien avulla äläkä korvaa pohjakoodia.

Esimerkkiarvot:

Peli-ikkunan otsikko: Maija Meikäläinen 26A

Peli-ikkunan koko: leveys = 800 ja korkeus = 600

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

# Pygame lopetus/sulku
pygame.quit()
d. Muuta peli-ikkunan taustan väri punaiseksi.

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"
rgb = (255, 0, 0)#punainen

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill(rgb)#taustan värin määritys
    pygame.display.flip()

# Pygame lopetus/sulku
pygame.quit()

Piirtäminen ja koordinaatisto

Vastaus:
Pygamen dokumentaatiosta löytyy Most useful stuff -kohta, jonka vierstä löytyy draw-osio. Esimerkiksi funktio pygame.draw.line() toimii siten, että ensimmäinen parametri on surface, eli pinta, johon piirretään. Esimerkkikoodissa se on screen. Seuraava parametri on väri, joka annetaan RGB-muodossa. Tämän jälkeen määritetään viivan alku- ja loppupiste koordinaatteina, muodossa [alku x, alku y] ja [loppu x, loppu y]. Koordinaatit voidaan antaa joko hakasuluissa [] tai sulkeissa (). Viimeinen parametri on valinnainen ja määrittää viivan paksuuden. Jos sitä ei anneta, oletusarvona käytetään paksuutta 1.

Sivustolla alempana on esimerkki funktion käytöstä.

Kun hiiri viedään funktion line() päälle Visual Studio Codessa, ohjelma näyttää, mitä parametreja funktio tarvitsee.

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"
rgb = (255, 0, 0)#punainen

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0,0,0)) #taustan värin määritys
    pygame.draw.circle(screen, rgb, [600,300], 20) #pallon piirtäminen
    pygame.display.flip()

# Pygame lopetus/sulku
pygame.quit()

pygame.draw.circle(screen, rgb , [0,0], 20) #pallon piirtäminen

Origo on ruudun vasemassa yläkulmassa.

pygame.draw.circle(screen,(255, 0, 0), [leveys/2,korkeus/2], 20) #pallon piirtäminen

pygame.draw.circle(screen,rgb, [leveys-20,korkeus-20], 20) #pallon piirtäminen

pygame.draw.circle(screen,(255, 0, 0), [leveys+10,korkeus-20],20) #pallon piirtäminen

On siis mahdollista.

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"
rgb = (255, 0, 0)#punainen

säde = 20 # pallon säde
väli = 2 * säde  # pallojen väli
y = korkeus / 2 # haluttu korkeus

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0,0,0)) #taustan värin määritys
    
    for x in range(säde, leveys, väli):
        pygame.draw.circle(screen, rgb, [x, y], säde) #pallon piirtäminen
    pygame.display.flip()

# Pygame lopetus/sulku
pygame.quit()

#kutsutaan tarvittavat kirjastot
import pygame

# Alustetaan Pygame
pygame.init()

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"
rgb = (255, 0, 0)#punainen

säde = 20 # pallon säde
väli = 2 * säde  # pallojen väli

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)

# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0,0,0)) #taustan värin määritys
    
    for x in range(säde, leveys, väli):
        for y in range(säde, korkeus, väli):
            pygame.draw.circle(screen, rgb, [x, y], säde) #pallon piirtäminen
    pygame.display.flip()

# Pygame lopetus/sulku
pygame.quit()
  1. Lisää muuttujiin kuva = pygame.image.load("kaarme.png") # kuvan lataaminen
  2. Lisää pelisilmukkaan toiminto screen.blit(kuva, [x-koordinaatti, y-koordinaatti]). Lisää haluamasi koordinaatit.
  3. Kun kuva toimii, lisätään tekstit. Tuo fontit alussa pygame.font.init()-toiminnolla.
  4. Lisää muuttujiin fontti = pygame.font.SysFont('Arial', 40) # fontin luonti
  5. Kun fontti on ladattu, lisää teksti = fontti.render("Jokin teksti tähän", True, rgb) # tekstin muodostus
  6. Kutsu tekstiä samalla tavalla pelisilmukassa kuin kuvaa.

import pygame

# Alustetaan Pygame
pygame.init()
pygame.font.init() 

#muuttujat
leveys = 800
korkeus = 600
ruudun_kuvaus = "Testi-ikkuna"
rgb = (255, 0, 0)# punainen

kuva = pygame.image.load("kaarme.png")# kuvan lataaminen 
fontti = pygame.font.SysFont('Arial', 40) # fontin luonti
teksti = fontti.render("Lisää tähän jokin teksti", True, rgb) # tekstin muodostus

# Peli-ikkunan määritys
screen = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption(ruudun_kuvaus)


# Pelisilmukan määritys
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0,0,0)) #taustan värin määritys

    # Piirretään kuva ja teksti
    screen.blit(kuva, [100, 100])
    screen.blit(teksti, [300, 300])
    pygame.display.flip()

# Pygame lopetus/sulku
pygame.quit()

Liike ja aika

Tehtävä 3

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

neliön_nopeus = 0.5

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    neliö.x += neliön_nopeus
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

neliön_nopeus = 0.5

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    neliö.x += neliön_nopeus
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

neliön_nopeus = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    neliö.x += neliön_nopeus
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()

Huomataan, ettei nopeus juuri muutu. Neliö häviää edelleen melko nopeasti.

Tätä varten tarvitaan kelloa, eli määritä pygame.time.Clock() Katso dokumentaatiosta apua.

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

# Määritetään kello
kello = pygame.time.Clock()

neliön_nopeus = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    neliö.x += neliön_nopeus
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()
    kello.tick(60)
Tehtävä 4

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

# Määritetään kello
kello = pygame.time.Clock()

neliön_nopeus = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    if neliö.right <= leveys:
        neliö.x += neliön_nopeus
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()
    kello.tick(60)

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

# Määritetään kello
kello = pygame.time.Clock()

neliön_nopeus = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    if neliö.right <= leveys:
        neliö.x += neliön_nopeus
    if neliö.right >= leveys:
        neliön_nopeus *= -1
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()
    kello.tick(60)

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

# Määritetään kello
kello = pygame.time.Clock()

neliön_nopeus = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    if neliö.right <= leveys:
        neliö.x += neliön_nopeus
    if neliö.right >= leveys  or neliö.left <= 0:
        neliön_nopeus *= -1
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()
    kello.tick(60)

import pygame, sys


# Alustetaan Pygame
pygame.init()

leveys = 800
korkeus = 600

# Peli-ikkunan määritys
näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Neliö liukuu")

# Määritetään kello
kello = pygame.time.Clock()

neliön_nopeus_vaaka = 1
neliön_nopeus_pysty = 1

neliö = pygame.Rect(20, 20, 50, 50)

# Pelisilmukan määritys
käynnissä = True
while käynnissä:
    näyttö.fill((0, 0, 0,))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    neliö.x += neliön_nopeus_vaaka
    neliö.y += neliön_nopeus_pysty
    if neliö.right >= leveys or neliö.left <= 0:
        neliön_nopeus_vaaka *= -1
    if neliö.top <= 0 or neliö.bottom >= korkeus:
        neliön_nopeus_pysty *= -1
    
    pygame.draw.rect(näyttö, (255, 255, 0), neliö)
    pygame.display.flip()
    kello.tick(60)
Tehtävä 5
import pygame, sys

pygame.init()

leveys = 800
korkeus = 600

näyttö = pygame.display.set_mode((leveys, korkeus))
pygame.display.set_caption("Näytön päivitys")

käynnissä = True
neliö = pygame.Rect(0, 0, 50, 50)
while käynnissä:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    pygame.draw.rect(näyttö, (255, 0, 0), neliö)

    pygame.display.flip()
while käynnissä:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    pygame.draw.rect(näyttö, (255, 0, 0), neliö)

    pygame.display.update()
while käynnissä:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    pygame.draw.rect(näyttö, (255, 0, 0), neliö)

    pygame.display.update(neliö)
neliö2 = pygame.Rect(10, 10, 20, 20)
luku = 0
while käynnissä:
    luku += 1
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    if luku % 2 == 1:
        neliö2.x = neliö2.x+60
    else:
        neliö2.x = neliö2.x-60

    
    pygame.draw.rect(näyttö, (255, 0, 0), neliö)
    pygame.draw.rect(näyttö, (255, 255, 0), neliö2)

    pygame.display.update([neliö, neliö2])
    kello.tick(10)

Ohjaaminen ja vuorovaikutus

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 300))

rgb = (0, 0, 0)
running = True
kello = pygame.time.Clock()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        
        nappaimet = pygame.key.get_pressed()
    
        if nappaimet[pygame.K_SPACE] == True:
            rgb = (255, 0, 0)
        if nappaimet[pygame.K_SPACE] == False:
            rgb = (255, 255, 0)

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, rgb, (175, 125, 50, 50))
    pygame.display.flip()
    kello.tick(60)

pygame.quit()

Välilyöntinäppäimen painaminen saa muutoksen aikaiseksi. Painiketta painamalla ruudulla näkyvän neliön väri vaihtuu keltaisesta punaiseksi. Punainen väri näkyy niin kauan, kun välilyöntinäppäin on pohjassa.

Tehtävä 7

Esimerkki ratkaisu:

#kirjasto(t)
import pygame

#alustetaan Pygame
pygame.init()

#Peli-ikkunan määritys
screen = pygame.display.set_mode((400, 300))

#muuttujat
x, y = 175, 125
nopeus = 10
running = True

kello = pygame.time.Clock()

nelio = pygame.Rect(x, y, 50, 50)

#Pelisilmukka
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        
        nappaimet = pygame.key.get_pressed()
    
        if nappaimet[pygame.K_UP] or nappaimet[pygame.K_w]: #ylös
            nelio.y = nelio.y - nopeus
        if nappaimet[pygame.K_DOWN] or nappaimet[pygame.K_s]: #alas
            nelio.y = nelio.y + nopeus
        if nappaimet[pygame.K_RIGHT] or nappaimet[pygame.K_d]: #oikealle
            nelio.x = nelio.x + nopeus
        if nappaimet[pygame.K_LEFT] or nappaimet[pygame.K_a]: #vasemmalle
            nelio.x = nelio.x - nopeus

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), nelio)
    pygame.display.flip()
    kello.tick(60)

#Pygame sulku/lopetus
pygame.quit()

Tapa 1. Valmiilla Pygame funktiolla

Esimerkki ratkaisu:

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 300))

x, y = 175, 125
nopeus = 10
running = True

nelio = pygame.Rect(x, y, 50, 50)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
        nappaimet = pygame.key.get_pressed()

        if nappaimet[pygame.K_UP] or nappaimet[pygame.K_w]:
            nelio.y = nelio.y - nopeus
        if nappaimet[pygame.K_DOWN] or nappaimet[pygame.K_s]:
            nelio.y = nelio.y + nopeus
        if nappaimet[pygame.K_RIGHT] or nappaimet[pygame.K_d]:
            nelio.x = nelio.x + nopeus
        if nappaimet[pygame.K_LEFT] or nappaimet[pygame.K_a]:
            nelio.x = nelio.x - nopeus

    nelio.clamp_ip(screen.get_rect()) #varmistaa ettei hahmo poistu peli-ikkunasta

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), nelio)
    pygame.display.flip()

pygame.quit()
Tapa 2. Ehtorakenteella

Esimerkki ratkaisu:

import pygame

pygame.init()

x, y = 175, 125
nopeus = 10
running = True
korkeus = 300
leveys = 400

screen = pygame.display.set_mode((leveys, korkeus))
nelio = pygame.Rect(x, y, 50, 50)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
        nappaimet = pygame.key.get_pressed()

        if nappaimet[pygame.K_UP] and nelio.y > 0:
            nelio.y = nelio.y - nopeus
        if nappaimet[pygame.K_DOWN] and nelio.y < korkeus-50: #50 = neliön korkeus
            nelio.y = nelio.y + nopeus
        if nappaimet[pygame.K_RIGHT] and nelio.x < leveys-50: #50 = neliön leveys
            nelio.x = nelio.x + nopeus
        if nappaimet[pygame.K_LEFT] and nelio.x > 0:
            nelio.x = nelio.x - nopeus

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), nelio)
    pygame.display.flip()

pygame.quit()
c. Muokkaa koodia vielä niin, että näppäintä painettaessa liike jatkuu niin kauan kuin näppäin on pohjassa.

Esimerkki ratkaisu:

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 300))

x, y = 175, 125
nopeus = 10
running = True
kello = pygame.time.Clock()

nelio = pygame.Rect(x, y, 50, 50)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
        nappaimet = pygame.key.get_pressed()

    if nappaimet[pygame.K_UP] or nappaimet[pygame.K_w]:
        nelio.y = nelio.y - nopeus
    if nappaimet[pygame.K_DOWN] or nappaimet[pygame.K_s]:
        nelio.y = nelio.y + nopeus
    if nappaimet[pygame.K_RIGHT] or nappaimet[pygame.K_d]:
        nelio.x = nelio.x + nopeus
    if nappaimet[pygame.K_LEFT] or nappaimet[pygame.K_a]:
        nelio.x = nelio.x - nopeus

    nelio.clamp_ip(screen.get_rect())

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), nelio)
    pygame.display.flip()
    kello.tick(60)

pygame.quit()
d. Muuta ohjelman näppäinohjaus tapahtumapohjaiseksi (event-based). Korvaa siis aikaisempi tilakyselyyn (get_pressed) perustuva koodi tapahtumapohjaisella vaihtoehdolla. Ohjelman tulee edelleen toimia samalla tavalla kuin b-kohdassa.

Esimerkki ratkaisu:

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 300))

x, y = 175, 125
nopeus = 10
running = True
kello = pygame.time.Clock()

nelio = pygame.Rect(x, y, 50, 50)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key in (pygame.K_UP, pygame.K_w):
                nelio.y = nelio.y - nopeus
            if event.key in (pygame.K_DOWN, pygame.K_s):
                nelio.y = nelio.y + nopeus
            if event.key in (pygame.K_RIGHT, pygame.K_d):
                nelio.x = nelio.x + nopeus
            if event.key in (pygame.K_LEFT, pygame.K_a):
                nelio.x = nelio.x - nopeus

    nelio.clamp_ip(screen.get_rect())

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), nelio)
    pygame.display.flip()
    kello.tick(60)

pygame.quit()
Tehtävä 8

Esimerkki ratkaisu:

#kirjasto(t)
import pygame

# Alustus
pygame.init()
naytto = pygame.display.set_mode((800, 600))
rect = pygame.Rect(300, 200, 50, 50)
kello = pygame.time.Clock()

#muuttujat
raahata = False

kaynnissa = True

#Pelisilmukka
while kaynnissa:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            kaynnissa = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 3:
                raahata = True
        elif event.type == pygame.MOUSEBUTTONUP:
            raahata = False
        elif event.type == pygame.MOUSEMOTION:
            if raahata:
                rect.move_ip(event.rel) 

    naytto.fill((30, 30, 30))
    pygame.draw.rect(naytto, (0, 255, 0), rect)
    pygame.display.flip()
    kello.tick(60)

#peli lopetus/sulku
pygame.quit()

Pelilogiikka ja säännöt

Tehtävä 9

Esimerkkiratkaisu:

import pygame

pygame.init()
naytto = pygame.display.set_mode((650, 400))
kello = pygame.time.Clock()

running = True

kartta = [
    "xxxxxxxxxxxxx",
    "x  px     x x",
    "x xxxxx x x x",
    "x     x x x x",
    "x xxx   x   x",
    "x   xxxxxx xx",
    "x x      x mx",
    "xxxxxxxxxxxxx"
]

# Luo seinät
seinat = []
maali = None
pelaaja = None

for y in range(len(kartta)):
    for x in range(len(kartta[0])):
        if kartta[y][x] == "x":
            seinat.append(pygame.Rect(x*50, y*50, 50, 50))
        if kartta[y][x] == "m":
            maali = pygame.Rect(x*50, y*50, 50, 50)
        if kartta[y][x] == "p":
            pelaaja = pygame.Rect(x*50, y*50, 40, 40)

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

    for s in seinat:
        pygame.draw.rect(naytto, (100, 100, 100), s)

    if maali:
        pygame.draw.rect(naytto, (0, 255, 0), maali)

    pygame.draw.rect(naytto, (255, 255, 255), pelaaja)

    pygame.display.flip()
    kello.tick(60)

pygame.quit()

Esimerkkiratkaisu:

import pygame

pygame.init()
naytto = pygame.display.set_mode((650, 400))
kello = pygame.time.Clock()

running = True
nopeus = 1
seinat = []
maali = None
pelaaja = None
kartta = [
    "xxxxxxxxxxxxx",
    "x  px     x x",
    "x xxxxx x x x",
    "x     x x x x",
    "x xxx   x   x",
    "x   xxxxxx xx",
    "x x      x mx",
    "xxxxxxxxxxxxx"
]


for y in range(len(kartta)):
    for x in range(len(kartta[0])):
        if kartta[y][x] == "x":
            seinat.append(pygame.Rect(x*50, y*50, 50, 50))
        if kartta[y][x] == "m":
            maali = pygame.Rect(x*50, y*50, 50, 50)
        if kartta[y][x] == "p":
            pelaaja = pygame.Rect(x*50, y*50, 40, 40)

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

    nappaimet = pygame.key.get_pressed()
    vanha = pelaaja.copy()

    if nappaimet[pygame.K_UP]:
        pelaaja.y = pelaaja.y - nopeus
    if nappaimet[pygame.K_DOWN]:
        pelaaja.y = pelaaja.y + nopeus
    if nappaimet[pygame.K_RIGHT]:
        pelaaja.x = pelaaja.x + nopeus
    if nappaimet[pygame.K_LEFT]:
        pelaaja.x = pelaaja.x - nopeus

    for s in seinat:
        if pelaaja.colliderect(s):
            pelaaja = vanha


    naytto.fill((0, 0, 0))
    for s in seinat:
        pygame.draw.rect(naytto, (100, 100, 100), s)

    if maali:
        pygame.draw.rect(naytto, (0, 255, 0), maali)

    pygame.draw.rect(naytto, (255, 255, 255), pelaaja)

    pygame.display.flip()
    kello.tick(60)

pygame.quit()

Esimerkkiratkaisu:

import pygame

pygame.init()
naytto = pygame.display.set_mode((650, 400))
kello = pygame.time.Clock()

running = True
nopeus = 1
fontti = pygame.font.SysFont("Arial", 40)
nayta_teksti = False
kaynnissa = True
seinat = []
maali = None
pelaaja = None
kartta = [
    "xxxxxxxxxxxxx",
    "x  px     x x",
    "x xxxxx x x x",
    "x     x x x x",
    "x xxx   x   x",
    "x   xxxxxx xx",
    "x x      x mx",
    "xxxxxxxxxxxxx"
]

for y in range(len(kartta)):
    for x in range(len(kartta[0])):
        if kartta[y][x] == "x":
            seinat.append(pygame.Rect(x*50, y*50, 50, 50))
        if kartta[y][x] == "m":
            maali = pygame.Rect(x*50, y*50, 50, 50)
        if kartta[y][x] == "p":
            pelaaja = pygame.Rect(x*50, y*50, 40, 40)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    if kaynnissa == True:
        nappaimet = pygame.key.get_pressed()
        vanha = pelaaja.copy()

        if nappaimet[pygame.K_UP]:
            pelaaja.y = pelaaja.y - nopeus
        if nappaimet[pygame.K_DOWN]:
            pelaaja.y = pelaaja.y + nopeus
        if nappaimet[pygame.K_RIGHT]:
            pelaaja.x = pelaaja.x + nopeus
        if nappaimet[pygame.K_LEFT]:
            pelaaja.x = pelaaja.x - nopeus

    for s in seinat:
        if pelaaja.colliderect(s):
            pelaaja = vanha
    
    if maali.contains(pelaaja):
        nayta_teksti = True
        kaynnissa = False

    naytto.fill((0, 0, 0))
    for s in seinat:
        pygame.draw.rect(naytto, (100, 100, 100), s)

    if maali:
        pygame.draw.rect(naytto, (0, 255, 0), maali)

    pygame.draw.rect(naytto, (255, 255, 255), pelaaja)

    if nayta_teksti == True:
        teksti_pinta = fontti.render("Pääsit maaliin!", True, (255, 255, 255))
        # Lasketaan tekstin keskikohta
        teksti_rect = teksti_pinta.get_rect(center=(650/2, 400/2))
        naytto.blit(teksti_pinta, teksti_rect)

    pygame.display.flip()
    kello.tick(60)

pygame.quit()

Esimerkkiratkaisu:

import pygame

pygame.init()
naytto = pygame.display.set_mode((650, 400))
kello = pygame.time.Clock()

running = True
nopeus = 1
fontti = pygame.font.SysFont("Arial", 40)
nayta_teksti = False
kaynnissa = True
tappio = False
seinat = []
maali = None
pelaaja = None
vihollinen = pygame.Rect(52.5, 100, 40, 40)
vihollis_nopeus = 1
suunta = 1  # 1 = alas, -1 = ylös
kartta = [
    "xxxxxxxxxxxxx",
    "x  px     x x",
    "x xxxxx x x x",
    "x     x x x x",
    "x xxx   x   x",
    "x   xxxxxx xx",
    "x x      x mx",
    "xxxxxxxxxxxxx"
]

for y in range(len(kartta)):
    for x in range(len(kartta[0])):
        if kartta[y][x] == "x":
            seinat.append(pygame.Rect(x*50, y*50, 50, 50))
        if kartta[y][x] == "m":
            maali = pygame.Rect(x*50, y*50, 50, 50)
        if kartta[y][x] == "p":
            pelaaja = pygame.Rect(x*50, y*50, 40, 40)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    if kaynnissa == True:
        nappaimet = pygame.key.get_pressed()
        vanha = pelaaja.copy()

        if nappaimet[pygame.K_UP]:
            pelaaja.y = pelaaja.y - nopeus
        if nappaimet[pygame.K_DOWN]:
            pelaaja.y = pelaaja.y + nopeus
        if nappaimet[pygame.K_RIGHT]:
            pelaaja.x = pelaaja.x + nopeus
        if nappaimet[pygame.K_LEFT]:
            pelaaja.x = pelaaja.x - nopeus

        vihollinen.y += vihollis_nopeus * suunta

        # vaihda suuntaa kun osuu reunoihin
        if vihollinen.y < 50 or vihollinen.y > 300:
            suunta *= -1

        if pelaaja.colliderect(vihollinen):
            kaynnissa = False
            tappio = True

    for s in seinat:
        if pelaaja.colliderect(s):
            pelaaja = vanha
    
    if maali.contains(pelaaja):
        nayta_teksti = True
        kaynnissa = False

    naytto.fill((0, 0, 0))
    for s in seinat:
        pygame.draw.rect(naytto, (100, 100, 100), s)

    if maali:
        pygame.draw.rect(naytto, (0, 255, 0), maali)

    pygame.draw.rect(naytto, (255, 255, 255), pelaaja)

    pygame.draw.rect(naytto, (255, 0, 0), vihollinen) 

    if tappio == True:
        teksti_pinta = fontti.render("Hävisit!", True, (255, 255, 255))
        # Lasketaan tekstin keskikohta
        teksti_rect = teksti_pinta.get_rect(center=(650/2, 400/2))
        naytto.blit(teksti_pinta, teksti_rect)

    if nayta_teksti == True:
        teksti_pinta = fontti.render("Pääsit maaliin!", True, (255, 255, 255))
        # Lasketaan tekstin keskikohta
        teksti_rect = teksti_pinta.get_rect(center=(650/2, 400/2))
        naytto.blit(teksti_pinta, teksti_rect)

    pygame.display.flip()
    kello.tick(60)

pygame.quit()

Esimerkkiratkaisu:

import pygame

pygame.init()
naytto = pygame.display.set_mode((650, 400))
kello = pygame.time.Clock()

running = True
nopeus = 1
fontti = pygame.font.SysFont("Arial", 40)
nayta_teksti = False
kaynnissa = True
tappio = False
palkinnot = []
pisteet = 0
seinat = []
maali = None
pelaaja = None
palkinto = None

kartta = [
    "xxxxxxxxxxxxx",
    "x  px     x x",
    "x xxxxx x x x",
    "x     x x x x",
    "x xxx   x   x",
    "x   xxxxxx xx",
    "x x      x mx",
    "xxxxxxxxxxxxx"
]

for y in range(len(kartta)):
    for x in range(len(kartta[0])):
        if kartta[y][x] == "x":
            seinat.append(pygame.Rect(x*50, y*50, 50, 50))
        if kartta[y][x] == "m":
            maali = pygame.Rect(x*50, y*50, 50, 50)
        if kartta[y][x] == "p":
            pelaaja = pygame.Rect(x*50, y*50, 40, 40)
        if kartta[y][x] == " ":
            palkinnot.append(pygame.Rect(x*51.5, y*51.5, 30, 30)) #mahdollisimman keskellä "ruutua"


vihollinen = pygame.Rect(52.5, 52.5, 40, 40)
vihollis_nopeus = 1
suunta = 1  # 1 = alas, -1 = ylös

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    if kaynnissa == True:
        nappaimet = pygame.key.get_pressed()
        vanha = pelaaja.copy()

        if nappaimet[pygame.K_UP]:
            pelaaja.y = pelaaja.y - nopeus
        if nappaimet[pygame.K_DOWN]:
            pelaaja.y = pelaaja.y + nopeus
        if nappaimet[pygame.K_RIGHT]:
            pelaaja.x = pelaaja.x + nopeus
        if nappaimet[pygame.K_LEFT]:
            pelaaja.x = pelaaja.x - nopeus

        vihollinen.y += vihollis_nopeus * suunta

        # vaihda suuntaa kun osuu reunoihin
        if vihollinen.y < 50 or vihollinen.y > 300:
            suunta *= -1

        if pelaaja.colliderect(vihollinen):
            kaynnissa = False
            tappio = True

    for s in seinat:
        if pelaaja.colliderect(s):
            pelaaja = vanha
    
    if maali.contains(pelaaja):
        nayta_teksti = True
        kaynnissa = False

    naytto.fill((0, 0, 0))
    for s in seinat:
        pygame.draw.rect(naytto, (100, 100, 100), s)

    if maali:
        pygame.draw.rect(naytto, (0, 255, 0), maali)

    pygame.draw.rect(naytto, (255, 255, 255), pelaaja) 

    for palkinto in palkinnot[:]:
        pygame.draw.rect(naytto, (255, 255, 0), palkinto) 
        if pelaaja.colliderect(palkinto):
            pisteet += 1
            palkinnot.remove(palkinto)
            break

    pygame.draw.rect(naytto, (255, 0, 0), vihollinen) 

    if tappio == True:
        teksti_pinta = fontti.render("Hävisit!", True, (255, 255, 255))
        # Lasketaan tekstin keskikohta
        teksti_rect = teksti_pinta.get_rect(center=(650/2, 400/2))
        naytto.blit(teksti_pinta, teksti_rect)

    if nayta_teksti == True:
        teksti_pinta = fontti.render("Pääsit maaliin!", True, (255, 255, 255))
        # Lasketaan tekstin keskikohta
        teksti_rect = teksti_pinta.get_rect(center=(650/2, 400/2))
        naytto.blit(teksti_pinta, teksti_rect)
    
    score_text = fontti.render(f"Pisteet: {pisteet}", True, (255, 255, 255)) # Valkoinen teksti
    naytto.blit(score_text, (10, 10)) # Piirretään koordinaatteihin (10, 10)

    pygame.display.flip()
    kello.tick(60)

pygame.quit()

2. Lopputehtävä

  1. Rakenna pelisilmukka.
  2. Mieti, miten liikkuvat objektit on toteutettu ja millaisessa muodossa ne ovat koodissa. Mallinna rakenne aluksi paikallaan.
  3. Lisää liike perustehtävissä opitulla tavalla. Onko liikkeessä ehtoja?
  4. Pohdi, mitä törmäys tarkoittaa koodissa ja miten se toteutuu kahden objektin välillä.
  5. Jaa toiminnalliset kokonaisuudet funktioihin.
Projektitehtävä 1. Nappaajapeli

Projektitehtävä 2. Ampumispeli

Projektitehtävä 3. Pong – virtuaalinen ilmakiekko