Kontynuacja tematu rysowania w "pygame" 🎨! Tym razem, zajmiemy się rysowaniem obrazów importowanych z pliku zewnętrznego takich formatów, jak JPEG, BMP czy PNG. Czym byłyby gry bez grafiki (z szacunkiem do gier konsolowych 👍) 😉? Przejdziemy przez wszystkie etapy, bo obsługa pliku graficznego w "pygame" wymaga troszkę trudniejszych posunięć. Zapraszam do środeczka 🙂!

OBSŁUGA PLIKU GRAFICZNEGO W "PYGAME" KROK PO KROKU

Procedura prawidłowego wyświetlenia importowanego obrazu składa się z kilku etapów i metod, które nie znajdują się w jednym module. Moje zalecenia co do umiejscowienia instrukcji rysujących pokazałem w artykule dot. rysowania figur geometrycznych, więc zobacz koniecznie w którym miejscu najlepiej wstawiać instrukcje, jakie tu zostaną zaprezentowane.

1. IMPORT OBRAZU

Najpierw odczyt samego pliku. Jeżeli chodzi o załadowanie obrazu znajdującego się na dysku, to korzystamy z metody "load" z modułu "image" ℹ️. Tak wygląda poprawne wywołanie 👇:

image = pygame.image.load("image.png")

Metoda zwraca referencję do naszego obrazka, więc nie zapomnij przypisać wyniku do zmiennej ⚠️. "load" wymaga podania łańcucha znaków jako ścieżka względna do pliku, który ma zostać wgrany do gry 💡.

DZIAŁANIE ŚCIEŻKI WZGLĘDNEJ

Wyjaśnię jak rozumieć parametr. Ścieżka względna oznacza lokalizację danego pliku "licząc" od katalogu, w którym znajduje się skrypt jaki zostanie przez Ciebie uruchomiony ℹ️. Dla przykładu, jeżeli masz obrazek o nazwie "image.png", to lokalizacja 👇:

image = pygame.image.load("image.png")

oznaczać będzie sytuację, w której obrazek znajduje się w tym samym katalogu, co skrypt. Ten katalog staje się "korzeniem" tego pliku (ang. root). Lokalizacja taka:

image = pygame.image.load("images/image.png")

to znak, że obraz znajduje się w katalogu "images", a sam katalog jest w tym samym katalogu, co skrypt. Tak to działa ☑️.

2. RYSOWANIE OBRAZU

Po zaimportowaniu obrazka, możemy przejść do jego rysowania na ekranie 🎨. W "pygame" odpowiada za to metoda o nazwie "blit" i, co może zaskakiwać, wywołasz ją z referencji do okna gry ℹ️. Parametry jakich oczekuje metoda "blit", to:

  • zmienna w postaci referencji do obrazka,
  • lista z dwiema liczbami całkowitymi jako współrzędne,
  • prostokąt ("pygame.Rect") do określenia wycinka obrazka (opcjonalne).

Oto przykład 👇:

window.blit(image, [16, 16])

i taki efekt:

Rysowanie obrazu przy użyciu metody "blit" w "pygame"

Efekt użycia metody "blit" w "pygame" rysującej zaimportowany obraz.

Jeżeli nie widzisz żadnego obrazka, upewnij się, że wywołujesz metodę aktualizującą stan okna ("pygame.display.update" lub "pygame.display.flip") zaraz po wywołaniu "blit", bo "pygame" nie robi tego automatycznie ⚠️!!! Czyli innymi słowy, zobacz czy masz taką sytuację:

window.blit(image, [16, 16])
pygame.display.update()    # lub "pygame.display.flip()"

Dodanie trzeciego parametru jako wycinek obrazka:

window.blit(image, [16, 16], pygame.Rect(16, 16, 48, 128))

sprawi, że otrzymamy następujący efekt:

Rysowanie przyciętego obrazu przy użyciu metody "blit" w "pygame"

Efekt użycia metody "blit" w "pygame" rysującej wycinek zaimportowanego obrazu.

Przycinanie odbywa się następująco: pierwsze dwie liczby określają przesunięcie od lewego górnego rogu, a dwie kolejne, szerokość i wysokość ℹ️. Nic się złego nie stanie jak przekroczysz szerokość lub wysokość podając więcej, niż ma obrazek - po prostu wyrenderuje tyle, ile będzie w stanie 😄.

Możesz bez przeszkód wstawić wielokrotnie ten sam obrazek po prostu wywołując tę samą metodę wiele razy dając tylko inne współrzędne, aby faktycznie było widać wiele obrazków 😊.

3. CZYSZCZENIE EKRANU

Obsługa pliku graficznego w "pygame" to nie tylko import i rysowanie. Trzeba także zadbać o wyczyszczenie ekranu z zawartości zarejestrowanych w poprzedniej klatce gry 🔥! Gdy dany element jest w ruchu (przemieszcza się) i nie zadbamy o odświeżenie zawartości, wtedy grafika zacznie się "rozjeżdżać" ⛔!!! Innymi słowy, "zawartość" następujących po sobie klatek będzie na siebie nachodzić.

Ciężko to sobie wyobrazić? Zerknij na poniższy obrazek i zobacz jak wygląda przykład nakładania się na siebie poszczególnych klatek, gdy obrazek powoli przesuwa się w danym kierunku ⚡!

Efekt uboczny braku odświeżania ekranu w "pygame"

Brak "posprzątania" po poprzedniej klatce powoduje "rozjechanie" wszystkich elementów graficznych, które są w ruchu.

Najprostszym sposobem aby temu zapobiec, jest skorzystanie z metody "fill", która wypełnia ekran danym kolorem 🧱. Ona także jest wywoływana z okna gry ℹ️. Oczekuje jedynego parametru jako listy trzech liczb całkowitych zgodnych z formatem palety barw RGB (od 0 do 255). W ten sposób decydujesz o kolorze, jakim ma zostać zamalowany ekran.

Oto przykład 👇:

window.fill([0, 0, 0])

Wywołanie wstawiaj tuż przed rysowaniem obrazków, bo tylko wtedy to ma sens ℹ️! Tak zabezpieczymy się przed niechcianymi artefaktami ✅.

W ten sposób przeszliśmy przez wszystkie kroki jak prawidłowo zaimportować dowolny plik graficzny, jaki chcemy wprowadzić do gry i zaimplementować jego rysowanie 📜. Także zapamiętaj, drogi Padawanie 😄:

  1. importuj używając metody "pygame.image.load",
  2. czyść ekran wypełniając go kolorem przy użyciu metody "fill" wywoływanej z okna gry,
  3. rysuj stosując metodę "blit" wywoływaną z okna gry,
  4. aktualizuj stan wywołując metodę "update" lub "flip" z modułu "pygame.display".

I będzie dobrze 🏆! Teraz widzisz ile rzeczy trzeba uwzględnić na taką prostą rzecz, jaką jest rysowanie obrazu w oknie "pygame" 😅.


Z mojej strony to wszystko w tym temacie 👍.

PODOBNE ARTYKUŁY