# Python 11 (PyGame)
PyGame Zero to biblioteka do tworzenia gier w języku Python, stworzona z myślą o osobach początkujących, a zwłaszcza o zastosowaniach edukacyjnych. Jej głównym celem jest umożliwienie szybkiego rozpoczęcia pracy nad własnymi grami bez konieczności znajomości skomplikowanych mechanizmów programistycznych.
Dokumentacja: https://pygame-zero.readthedocs.io/en/stable/
Instalacja w terminalu: pip install pgzero
Podstawowa struktura gry:
import pgzrun
from pygame import display
from pgzero import screen as pgzero_screen
from pgzero.builtins import keyboard
# rozmiar okna - pozniej wrzucimy to do osobnego pliku
WIDTH = 800
HEIGHT = 600
screen = pgzero_screen.Screen(display.set_mode((WIDTH, HEIGHT), 0))\
def update():
# tu aktualizujemy stan obiektow
pass
def draw():
# tu je rysujemy
pass
# wywołanie pętli gry
pgzrun.go()Niezbędne funkcje i klasy
- draw() — funkcja rysująca zawartość ekranu
- update() — aktualizuje logikę gry
- Klasa Actor - reprezentuje obiekt graficzny — np. postać, przycisk czy tło. Actor jest powiązany z obrazem (.png) w folderze images/. Pojawia się wszędzie gdzie obiekty wchodzą z sobą w interakcje. Zapewnia obsługę kolizji.
Każdy Actor ma wbudowany prostokąt , który określa jego rozmiar. Metoda colliderect() sprawdza, czy prostokąt jednego aktora nachodzi na prostokąt drugiego
Gra pong:

Main
import pgzrun
import pygame
from pygame import display
from pgzero import screen as pgzero_screen
from pgzero.builtins import keyboard
from stale import *
from paletka import Paletka
from pilka import Pilka
from tablica import TablicaPunktow
# rozmiar okna - pozniej wrzucimy to do osobnego pliku
screen = pgzero_screen.Screen(display.set_mode((WIDTH, HEIGHT), 0))
paletka1 = Paletka("paletka", 10, HEIGHT // 2)
paletka2 = Paletka("paletka", WIDTH - 10, HEIGHT // 2)
pilka = Pilka(WIDTH // 2, HEIGHT // 2)
tablica = TablicaPunktow(380, 10)
# pygame uruchamia pętlę gry automatycznie
# ... ale potrzebuje do tego odpowiednio nazwanych funkcji.
# Korzystamy z funkcji update i draw.
def sterowanie():
if keyboard.w:
paletka1.przesun_gora()
if keyboard.s:
paletka1.przesun_dol()
if keyboard.UP:
paletka2.przesun_gora()
if keyboard.DOWN:
paletka2.przesun_dol()
def update():
sterowanie()
tablica.dodaj_pkt(pilka)
pilka.przesun(paletka1, paletka2)
def draw():
screen.clear()
paletka1.draw()
paletka2.draw()
screen.draw.text(
f"{tablica.licznik_l} : {tablica.licznik_p}",
(tablica.x, tablica.y),
fontsize=32,
)
pilka.draw()
# wywołanie pętli gry
pgzrun.go()Rozkładamy kod na części pierwsze:
- Importy i inicjalizacja naszego kodu pong:
import pgzrun
import pygame
from pygame import display
from pgzero import screen as pgzero_screen
from pgzero.builtins import keyboardpgzrun- moduł do uruchamiania gier Pygame Zeropygameidisplay- podstawowe moduły Pygamepgzero_screen- system ekranu z Pygame Zerokeyboard- obsługa klawiatury
from stale import *
from paletka import Paletka
from pilka import Pilka
from tablica import TablicaPunktow- Import z osobnych plików .py (Ważne - muszą być w tym samym folderze):
stale.py- zawiera WIDTH = 800 HEIGHT = 600 ekranu.paletka.py- klasa reprezentująca paletki graczy (paletka1 i paletka2)pilka.py- klasa piłkitablica.py- klasa tablicy do liczenia punktów
- Konfiguracja gry
#1
screen = pgzero_screen.Screen(display.set_mode((WIDTH, HEIGHT), 0))Tworzy okno gry o rozmiarach WIDTH x HEIGHT; Normalnie w Pygame Zero jest automatyczny obiekt screen dostępny globalnie.
Tutaj tworzymy własny obiekt Screen i przekazujemy mu surface z pygame.
Screen to klasa; Zero to parametr flags w funkcji pygame.display.set_mode(). Określa dodatkowe opcje dla okna gry:
- 0 = standardowe okno (żadnych specjalnych flag). Inne opcje to np.:
pygame.FULLSCREEN- pełny ekranpygame.RESIZABLE- okno o zmiennym rozmiarzepygame.NOFRAME- okno bez ramkipygame.DOUBLEBUF- podwójne buforowanie
#2
paletka1 = Paletka("paletka", 10, HEIGHT // 2)
paletka2 = Paletka("paletka", WIDTH - 10, HEIGHT // 2)
pilka = Pilka(WIDTH // 2, HEIGHT // 2)
tablica = TablicaPunktow(380, 10)
#paletka1 - lewa paletka (x=10, y=środek ekranu), string"paletka" odnosi się do pliku paletka.png, który jest W TYM SAMYM FOLDERZE CO PLIKI .PY GRY
#paletka2 - prawa paletka (x=WIDTH-10, y=środek ekranu)
#pilka - startuje w środku ekranu
#tablica - wynik na pozycji (380, 10)UWAGA! Układ współrzędnych ekranu wygląda tak:

- Funkcje gry
STEROWANIE:
def sterowanie():
if keyboard.w: paletka1.przesun_gora()
if keyboard.s: paletka1.przesun_dol()
if keyboard.UP: paletka2.przesun_gora()
if keyboard.DOWN: paletka2.przesun_dol()
#Gracz 1: W/S (lewa paletka)
#Gracz 2: strzałki góra/dół (prawa paletka)
Update (LOGIKA GRY):
def update():
sterowanie()
tablica.dodaj_pkt(pilka)
pilka.przesun(paletka1, paletka2)
# Obsługuje sterowanie
# Sprawdza czy zdobyto punkt
# Przesuwa piłkę (z kolizjami z paletkami)Draw (rysowanie):
def draw():
screen.clear() #czyści ekran
paletka1.draw() #rysuje paletke1
paletka2.draw() #rysuje paletkę2
screen.draw.text(f"{tablica.licznik_l} : {tablica.licznik_p}", (tablica.x, tablica.y), fontsize=32) #rysuje tablicę wyników
pilka.draw() #rysuje piłkę
pgzrun.go()
#Startuje główną pętlę gry.Plik Paletka
from stale import *
from pgzero.builtins import Actor
class Paletka(Actor):
def __init__(self, nazwa_obrazka: str, wsp_x: int, wsp_y: int):
# przekazujemy to do klasy rodzica
# korzystając z funkcji super nie dodajemy w poniższym __init__ słowa self
super().__init__(nazwa_obrazka, (wsp_x, wsp_y))
# self trzeba by było przekazać jeśli do inicjalizowania
# atrybutów z klasy rodzica użylibyśmy
# Actor.__init__()
self.predkosc_y = 5
def przesun_gora(self):
if self.y > 0:
self.y -= self.predkosc_y
def przesun_dol(self):
if self.y < HEIGHT:
self.y += self.predkosc_yRozkładamy kod na części pierwsze:
from pgzero.builtins import Actor
class Paletka(Actor):
#Paletka dziedziczy z Actor - to klasa Pygame Zero do obsługi
#sprite'ów (obiektów graficznych). Actor automatycznie daje:
#Ładowanie obrazków
#Pozycjonowanie (x, y)
#Metodę draw() do rysowania
#Detekcję kolizji
def __init__(self, nazwa_obrazka: str, wsp_x: int, wsp_y: int):
super().__init__(nazwa_obrazka, (wsp_x, wsp_y))
self.predkosc_y = 5Atrybuty klasy:
nazwa_obrazka- nazwa pliku graficznego (np. "paletka.png")(wsp_x, wsp_y)- pozycja startowa paletkiself.predkosc_y = 5- prędkość ruchu paletki
Metody ruchu:
def przesun_gora(self):
if self.y > 0:
self.y -= self.predkosc_y
def przesun_dol(self):
if self.y < HEIGHT:
self.y += self.predkosc_yprzesun_gora():
- Sprawdza czy paletka nie jest przy górnej krawędzi (
self.y > 0) - Przesuwa w górę o
predkosc_ypikseli
przesun_dol():
- Sprawdza czy paletka nie jest przy dolnej krawędzi (
self.y < HEIGHT) - Przesuwa w dół o
predkosc_ypikseli
Plik pilka
from stale import *
from pgzero.builtins import Actor
class Pilka(Actor):
def __init__(self, x:int, y:int) -> None:
super().__init__("pilka", (x, y))
self.predkosc_x = 3
self.predkosc_y = 3
def przesun(self, paletka1, paletka2):
self.x += self.predkosc_x
self.y += self.predkosc_y
if self.x > WIDTH or self.x < 0:
self.predkosc_x *= -1
if self.y > HEIGHT or self.y < 0:
self.predkosc_y *= -1
if self.colliderect(paletka1) or self.colliderect(paletka2):
self.predkosc_x *= -1Konstruktor:
- Dziedziczy z
Actor(jak paletka) - Ładuje obrazek "pilka"
- Ustawia pozycję startową (x, y)
predkosc_x = 3- ruch w poziomie (prawo: +, lewo: -)predkosc_y = 3- ruch w pionie (dół: +, góra: -)
Metoda przesun() - główna logika piłki:
def przesun(self, paletka1, paletka2): ->Przyjmuje obie paletki jako parametry do sprawdzania kolizji.
self.x += self.predkosc_x
self.y += self.predkosc_y -> Przesuwa piłkę o wartość prędkości w obu osiach.
Odbicia od ścian góra/dół i prawo/lewo:
if self.x > WIDTH or self.x < 0:
self.predkosc_x *= -1
if self.y > HEIGHT or self.y < 0:
self.predkosc_y *= -1
# odbicia od ścian
#Ściany boczne: gdy piłka wyjdzie poza WIDTH lub x<0 → odwraca kierunek #poziomy
#Ściany góra/dół: gdy piłka wyjdzie poza HEIGHT lub y<0 → odwraca kierunek #pionowyKolizje z paletką:
if self.colliderect(paletka1) or self.colliderect(paletka2):
self.predkosc_x *= -1colliderect()- metoda zActorsprawdzająca kolizję prostokątów- Gdy piłka uderzy w którąkolwiek paletkę → odwraca kierunek poziomy
Plik tablica
from stale import *
class TablicaPunktow():
def __init__(self, wsp_x: int, wsp_y: int):
self.x = wsp_x
self.y = wsp_y
self.licznik_p = 0
self.licznik_l = 0
def dodaj_pkt(self, pilka):
if pilka.x <= 0:
self.licznik_p += 1
if pilka.x >= WIDTH:
self.licznik_l += 1Logika punktacji:
- Gdy piłka wyleci za lewą ścianę (
x <= 0) → prawy gracz dostaje punkt - Gdy piłka wyleci za prawą ścianę (
x >= WIDTH) → lewy gracz dostaje punkt
Plik stale
WIDTH = 800 # szerokość okna
HEIGHT = 600 # wysokość okna
#Okno gry ma rozmiar 800x600 pikseli.i pliki graficzne
paletka.png
pilka.png