Gra w Pythonie – PyGame – Animacje – #2
W dzisiejszym odcinku tutorialu zaczniemy kodować proste animacje i pierwszy raz pojawi się obiecany dinozaur z Chrome’a :)
FPS-y
Aby animacja działała poprawnie, musimy określić, ile obrazków program będzie rysować na sekundę. Od tego zależy zarówno szybkość wykonywania się animacji, jak i jej płynność. Zaraz pod importami i inicjalizacją PyGame zdefiniujmy FPS-y i stwórzmy zegar:
1 2 |
FPS = 60 fpsClock = pygame.time.Clock() |
Druga linijka, wg dokumentacji:
Creates a new Clock object that can be used to track an amount of time. The clock also provides several functions to help control a game’s framerate.
W połączeniu z fpsClock.tick(FPS), które wywołamy po każdym odświeżeniu programu, będzie pilnować, czy gra działa z odpowiednią szybkością.
Wstawianie obrazków
Kolejnym krokiem będzie umieszczenie na planszy obrazka, którego chcemy zanimować. W tym wypadku będzie to nasz dinozaur:
Jeszcze przed główną pętlą gry, umieśćmy definicję zmiennych powiązanych ze zwierzaczkiem:
1 2 3 |
dino_Img = pygame.image.load('dino3.png') dino_x = 10 dino_y = 10 |
Współrzędne określają położenie lewego górnego piksela ilustracji. Użyjemy ich w wywołaniu, które znajdzie się już w głównej pętli programu.
1 |
DISPLAY_SURFACE.blit(dino_Img, (dino_x, dino_y)) |
Korzystamy tutaj z DISPLAY_SURFACE.blit(), które możecie pamiętać z poprzedniego odcinka – tam wywoływaliśmy nim tekst. Blit służy właśnie do rysowania jednych obiektów Surface na drugich. Użyty wcześniej kod pygame.image.load() tworzy nowy obiekt tego typu, oddzielony od właściwej planszy, dlatego konieczne jest jeszcze ich połączenie.
Ruch niezależny
Właściwy kod, który sprawi, że nasz dinozaur będzie poruszać się sam z siebie, również wstawimy do głównej pętli programu. Będzie on wyglądać tak:
1 2 3 4 5 6 7 8 9 10 |
if direction == 'right': dino_x += 4 if dino_x == 282: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'left' elif direction == 'left': dino_x -= 4 if dino_x == 22: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'right' |
Jak łatwo się domyślić – dinozaur zwrócony w prawo, porusza się w tym kierunku, dopóki jego współrzędna X-owa nie osiągnie wartości 282. Wtedy obrazek zostaje obrócony (horyzontalnie), a kierunek zmienia się na lewy.
Cały kod programu powinien prezentować się teraz tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import pygame, sys from pygame.locals import * pygame.init() FPS = 60 fpsClock = pygame.time.Clock() DISPLAY_SURFACE = pygame.display.set_mode((400, 300)) pygame.display.set_caption('Dinozaur') GRAY = (247, 247, 247) dino_Img = pygame.image.load('dino3.png') dino_x = 10 dino_y = 10 direction = 'right' while True: DISPLAY_SURFACE.fill(GRAY) if direction == 'right': dino_x += 4 if dino_x == 282: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'left' elif direction == 'left': dino_x -= 4 if dino_x == 22: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'right' DISPLAY_SURFACE.blit(dino_Img, (dino_x, dino_y)) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() pygame.display.update() fpsClock.tick(FPS) |
Po uruchomieniu, gra powinna prezentować się mniej więcej tak:
Reakcja na akcję gracza
Dobrze by było, aby móc mieć jakiś wpływ na ruch naszego dinozaura. W oryginalnej grze skacze się spacją, przy tym więc pozostańmy. Na razie nie weźmiemy pod uwagę innych zmiennych i pominiemy liczenie sił – ma po prostu podskoczyć i podążać dalej.
Do definicji cech obrazka, dodajmy jeszcze dwie:
1 2 |
dino_jump = False dino_fall = False |
Rozdzielimy skok dinozaura na dwa etapy – podskok i opadanie. Skrypt dotyczący ruchu zwierzęcia podmieńmy na:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
if dino_jump == True: if dino_y > 2: dino_y = dino_y - 2 else: dino_fall = True dino_jump = False elif dino_fall == True: if dino_y < 10: dino_y = dino_y + 2 else: dino_fall = False else: if direction == 'right': dino_x += 4 if dino_x == 282: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'left' elif direction == 'left': dino_x -= 4 if dino_x == 22: dino_Img = pygame.transform.flip(dino_Img, True, False) direction = 'right' |
Jeżeli dinozaur podskakuje, robi to aż do osiągnięcia dwóch pikseli od górnej krawędzi ekranu – gdy dotrze w to miejsce, ruch zmienia się na opadanie. Automatyczny ruch dinozaura wykonuje się dopiero wtedy, gdy dino_jump i dino_fall są False.
Pozostało nam jeszcze dodanie samej reakcji na spację:
1 2 3 4 5 6 |
for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if (event.type == KEYUP and event.key == K_SPACE): dino_jump = True |
I cieszenie się efektem :)
W kolejnej części, która pojawi się po weekendzie, uporządkujemy kod (dzieląc go na funkcje), opiszemy trochę praw fizyki, aby dinozaur poruszał się bardziej realistycznie, i skonstruujemy ruchome tło, takie jak w oryginalnej grze. Stay tuned! :)