blog.furas.pl
# prywatne notatki - Python, Linux, Machine Learning, etc.

Najprostszy program w PyGame

# import potrzebnego modulu (i podmodulow)
import pygame

# inicjalizacja modulu (i podmodulow)
pygame.init()

# stworzenie okna o powierzchni do rysowania 800x600
screen = pygame.display.set_mode((800, 600))

# uruchomienie glownej petli (mainloop) do obslugi zdarzen
running = True

while running:

    # pobieranie kolejnych zdarzen
    for event in pygame.event.get():

        # jesli kliknieto w przycisk zamykajacy okno
        # to konczymy program
        if event.type == pygame.QUIT:
            running = False

# zamkniecie modulu (i podmodulow)
pygame.quit()

Nie importuję do jednej przestrzeni nazw (namespace) za pomocą from pygame import * oraz from pygame.locals import * aby zawsze było widać, które elementy pochodzą z pygame a które są własnej produkcji.

pygame.init() inicjuje wszystkie podmoduły. Wywołanie set_mode() też może automatycznie zainicjować moduł ale lepiej to zrobić jawnie. Poza tym czasami trzeba użyć pygame.init() wcześniej aby jeszcze przed set_mode() można było skorzystać z jakiś dodatkowych funkcji.

Główna pętla - zwana "mainloop" lub "event loop" (pętla obsługi zdarzeń) - ma się zajmować obsługą zdarzeń oraz obsługą wszystkich elementów w trakcie działania programu (np. przesuwaniem obiektów, rysowaniem obiektów na ekranie, itd.)

Jeśli nie będzie obsługi pygame.QUIT to okno nie biędzie się chciało zamknąć poprzez kliknięcie w standardowy przycisk zamykania okien/programów.

pygame.quit() zamyka wszystkie podmoduły.

Właściwie powinno zamknąć moduły automatycznie nawet bez użycia tej komendy ale w niektórych sytuacjach może to być potrzebne (np. podczas uruchamiania kodu w IDLE lub DreamPie). Dla porządku warto więc go użyć.

Czasami po pygame.init() dodawane jest sys.exit() (co wymaga jeszcze dodania na początku import sys) ale nie jest to tutaj potrzebne. Mogło by być potrzebne gdyby zakończenie programu następowałoby gdzieś wewnątrz pętli - choć i to nie zawsze jest skuteczne.

Dla wygody i z powodu własnego przyzwyczajenia zwykle dodaje jeszcze zamykanie programu klawiszem ESC. Wtedy całość wygląda tak

# import potrzebnego modulu (i podmodulow)
import pygame

# inicjalizacja modulu (i podmodulow)
pygame.init()

# stworzenie okna o powierzchni do rysowania 800x600
screen = pygame.display.set_mode((800, 600))

# uruchomienie glownej petli (mainloop) do obslugi zdarzen
running = True

while running:

    # pobieranie kolejnych zdarzen
    for event in pygame.event.get():

        # jesli kliknieto w przycisk zamykajacy okno
        # to konczymy program
        if event.type == pygame.QUIT:
            running = False

        # zakonczenie programu klawiszem ESC
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

# zamkniecie modulu (i podmodulow)
pygame.quit()

Nie każde zdarzenie (event) posiada te same pola więc zanim użyje się event.key trzeba najpierw sprawdzić czy event.type jest pygame.KEYDOWN lub pygame.KEYUP.

Pełna lista pól dla poszególnych typów zdarzene jest w dokumentacji: https://www.pygame.org/docs/ref/event.html

pygame.KEYDOWN występuje tylko w momencie przejścia klawisza od niewciśniętego do wciśniętego. Przez cały ten czas gdy klawisz jest trzymany wciśnięty już nie jest generowany pygame.KEYDOWN. Podobnie pygame.KEYUP jest generowany tylko gdy klawisz przechodzi od wciśniętego do niewciśniętego. Przez cały czas gdy klawisze nie są wciśnięte nie występuje pygame.KEYUP.

Aby rozpoznać czy klawisz "X" jest cały czas wciśnięty należy podczas pygame.KEYDOWN ustawiać zmienną key_X_pressed = True a podczas pygame.KEYUP zmieniać na key_X_pressed = False. I tak dla wszystkich klawiszy, które nas interesują.

# poczatkowa wartosc zmienneje
key_X_pressed = False

# wewnatrz `mainloop`
if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_X:
        key_X_pressed = True

elif event.type == pygame.KEYDOWN:
    if event.key == pygame.K_X:
        key_X_pressed = False

PyGame sam też przechowuje indormację jakie klawisze są w danej chwili wciśnięte i można się tego dowiedzieć za pomocą pygame.key.get_pressed

Funkcja ta jednak wymaga aby co chwila było wywoływane pygame.event.get() aby mogła ona pobrać aktualne dane o KEYDOWN i KEYUP

Nazwy wszystkich klawiszy w dokumentacji https://www.pygame.org/docs/ref/key.html

Przełączanie jednym klawiszem między włączone/wyłączone

Przykładowe pauzowanie i wznawianie gry przy pomocy spacji.

# poczatkowa wartosc zmiennej

game_paused = False

# --- mainloop ---

    # --- zdarzenia ---

    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE:
            # przelaczanie miedzy True i False
            game_paused = not game_paused

    # --- aktualizacja ---

    if not game_paused:
       # aktualizacja stanu obiektow

    # --- rysowanie ---

    if game_paused:
       # wyswietlanie napisu "PAUSE"
Książki: python-dla-kazdego-podstawy-programowania python-wprowadzenie python-leksykon-kieszonkowy python-receptury python-programuj-szybko-i-wydajnie python-projekty-do-wykorzystania black-hat-python-jezyk-python-dla-hackerow-i-pentesterow efektywny-python-59-sposobow-na-lepszy-kod tdd-w-praktyce-niezawodny-kod-w-jezyku-python aplikacje-internetowe-z-django-najlepsze-receptury