Darmowy fragment publikacji:
Tytuł oryginału: Python Programming for the Absolute Beginner, 3rd Edition
Tłumaczenie: Grzegorz Pawłowski
Projekt okładki: Studio Gravite / Olsztyn; Obarek, Pokoński, Pazdrijowski, Zaprucki
Materiały graficzne na okładce zostały wykorzystane za zgodą Shutterstock Images LLC.
ISBN: 978-83-246-9358-0
© 2010 Course Technology, a part of Cengage Learning.
ALL RIGHTS RESERVED. No part of this work covered by the copyright herein may be reproduced,
transmitted, stored, or used in any form or by any means graphic, electronic, or mechanical, including but
not limited to photocopying, recording, scanning, digitizing, taping, Web distribution, information
networks, or information storage and retrieval systems, without the prior written permission of the
publisher.
Python is a registered trademark of the Python Software Foundation.
All other trademarks are the property of their respective owners.
All images © Cengage Learning unless otherwise noted.
Polish edition copyright © 2014 by Helion S.A. All rights reserved.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były
kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane
z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie
ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji
zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/pytdk3
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/pytdk3.zip
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis treści
O autorze ...........................................................................11
Wst(cid:246)p ...............................................................................13
Rozdzia(cid:228) 1. Wprowadzenie. Program Koniec gry ....................................15
Analiza programu Koniec gry ..........................................................15
Co warto wiedzie(cid:232) o Pythonie? .......................................................16
Konfiguracja Pythona w systemie Windows ......................................19
Konfiguracja Pythona w innych systemach operacyjnych ...................20
Wprowadzenie do IDLE ..................................................................20
Powrót do programu Koniec gry ......................................................26
Podsumowanie .............................................................................29
Rozdzia(cid:228) 2. Typy, zmienne i proste operacje wej(cid:264)cia-wyj(cid:264)cia.
Program Nieistotne fakty ...................................................31
Wprowadzenie do programu Nieistotne fakty ...................................31
U(cid:276)ycie cudzys(cid:228)owów przy tworzeniu (cid:228)a(cid:254)cuchów znaków .....................32
U(cid:276)ywanie sekwencji specjalnych w (cid:228)a(cid:254)cuchach znaków .....................36
Konkatenacja i powielanie (cid:228)a(cid:254)cuchów .............................................40
Operacje na liczbach .....................................................................42
Poj(cid:246)cie zmiennych .........................................................................45
Pobieranie danych wprowadzanych przez u(cid:276)ytkownika ......................48
U(cid:276)ywanie metod (cid:228)a(cid:254)cucha ..............................................................50
Stosowanie w(cid:228)a(cid:264)ciwych typów ........................................................54
Konwersja warto(cid:264)ci .......................................................................56
Powrót do programu Nieistotne fakty ..............................................59
Podsumowanie .............................................................................61
Rozdzia(cid:228) 3. Rozga(cid:228)(cid:246)zianie kodu, p(cid:246)tle while, projektowanie programu.
Gra Odgadnij moj(cid:241) liczb(cid:246) ....................................................63
Wprowadzenie do gry Jaka to liczba? ..............................................63
Generowanie liczb losowych ...........................................................64
U(cid:276)ywanie instrukcji if .....................................................................67
Kup książkęPoleć książkę
6
Python dla ka(cid:276)dego. Podstawy programowania
U(cid:276)ywanie klauzuli else ...................................................................71
U(cid:276)ywanie klauzuli elif .....................................................................73
Tworzenie p(cid:246)tli while .....................................................................76
Unikanie p(cid:246)tli niesko(cid:254)czonych ........................................................80
Traktowanie warto(cid:264)ci jako warunków ..............................................83
Tworzenie umy(cid:264)lnych p(cid:246)tli niesko(cid:254)czonych ......................................86
Korzystanie z warunków z(cid:228)o(cid:276)onych ..................................................88
Projektowanie programów ..............................................................93
Powrót do gry Jaka to liczba? .........................................................95
Podsumowanie .............................................................................97
Rozdzia(cid:228) 4. P(cid:246)tle for, (cid:228)a(cid:254)cuchy znaków i krotki.
Gra Wymieszane litery ........................................................99
Wprowadzenie do programu Wymieszane litery ................................99
Liczenie za pomoc(cid:241) p(cid:246)tli for .........................................................102
Stosowanie funkcji i operatorów sekwencji do (cid:228)a(cid:254)cuchów znaków ...105
Indeksowanie (cid:228)a(cid:254)cuchów .............................................................107
Niemutowalno(cid:264)(cid:232) (cid:228)a(cid:254)cuchów .........................................................111
Tworzenie nowego (cid:228)a(cid:254)cucha .........................................................113
Wycinanie (cid:228)a(cid:254)cuchów ..................................................................116
Powrót do gry Wymieszane litery ...................................................128
Podsumowanie ...........................................................................131
Rozdzia(cid:228) 5. Listy i s(cid:228)owniki. Gra Szubienica ........................................133
Wprowadzenie do gry Szubienica ..................................................133
Korzystanie z list .........................................................................135
Korzystanie z metod listy .............................................................140
Kiedy nale(cid:276)y u(cid:276)ywa(cid:232) krotek zamiast list? .......................................144
U(cid:276)ywanie sekwencji zagnie(cid:276)d(cid:276)onych ..............................................145
Referencje wspó(cid:228)dzielone ............................................................149
U(cid:276)ywanie s(cid:228)owników ....................................................................152
Powrót do gry Szubienica .............................................................159
Podsumowanie ...........................................................................165
Rozdzia(cid:228) 6. Funkcje. Gra Kó(cid:228)ko i krzy(cid:276)yk .............................................167
Wprowadzenie do gry Kó(cid:228)ko i krzy(cid:276)yk .............................................167
Tworzenie funkcji .........................................................................169
U(cid:276)ywanie parametrów i warto(cid:264)ci zwrotnych ....................................172
Wykorzystanie argumentów nazwanych i domy(cid:264)lnych warto(cid:264)ci
parametrów ..............................................................................176
Wykorzystanie zmiennych globalnych i sta(cid:228)ych ...............................181
Powrót do gry Kó(cid:228)ko i krzy(cid:276)yk ........................................................185
Podsumowanie ...........................................................................196
Kup książkęPoleć książkę
Spis tre(cid:264)ci
7
Rozdzia(cid:228) 7. Pliki i wyj(cid:241)tki. Gra Turniej wiedzy .....................................199
Wprowadzenie do programu Turniej wiedzy ....................................199
Odczytywanie danych z plików tekstowych .....................................200
Zapisywanie danych do pliku tekstowego ......................................206
Przechowywanie z(cid:228)o(cid:276)onych struktur danych w plikach .....................209
Obs(cid:228)uga wyj(cid:241)tków ........................................................................214
Powrót do gry Turniej wiedzy .........................................................218
Podsumowanie ...........................................................................223
Rozdzia(cid:228) 8. Obiekty programowe. Program Opiekun zwierzaka .............225
Wprowadzenie do programu Opiekun zwierzaka .............................225
Podstawy programowania obiektowego .........................................227
Tworzenie klas, metod i obiektów .................................................228
U(cid:276)ywanie konstruktorów ..............................................................230
Wykorzystywanie atrybutów ..........................................................232
Wykorzystanie atrybutów klasy i metod statycznych ........................236
Hermetyzacja obiektów ................................................................240
U(cid:276)ywanie atrybutów i metod prywatnych ........................................241
Kontrolowanie dost(cid:246)pu do atrybutów ............................................245
Powrót do programu Opiekun zwierzaka ........................................249
Podsumowanie ...........................................................................252
Rozdzia(cid:228) 9. Programowanie obiektowe. Gra Blackjack ........................255
Wprowadzenie do gry Blackjack ....................................................255
Wysy(cid:228)anie i odbieranie komunikatów .............................................256
Tworzenie kombinacji obiektów ....................................................259
Wykorzystanie dziedziczenia do tworzenia nowych klas ...................263
Rozszerzanie klasy poprzez dziedziczenie ......................................263
Modyfikowanie zachowania odziedziczonych metod ........................269
Polimorfizm ................................................................................273
Tworzenie modu(cid:228)ów .....................................................................273
Powrót do gry Blackjack ...............................................................277
Podsumowanie ...........................................................................287
Rozdzia(cid:228) 10. Tworzenie interfejsów GUI. Gra Mad Lib ............................289
Wprowadzenie do programu Mad Lib .............................................289
Przyjrzenie si(cid:246) interfejsowi GUI .....................................................291
Programowanie sterowane zdarzeniami .........................................292
Zastosowanie okna g(cid:228)ównego .......................................................293
U(cid:276)ywanie przycisków ...................................................................298
Tworzenie interfejsu GUI przy u(cid:276)yciu klasy .....................................300
Wi(cid:241)zanie wid(cid:276)etów z procedurami obs(cid:228)ugi zdarze(cid:254) .........................303
U(cid:276)ywanie wid(cid:276)etów Text i Entry oraz mened(cid:276)era uk(cid:228)adu Grid ...........305
Kup książkęPoleć książkę
8
Python dla ka(cid:276)dego. Podstawy programowania
Wykorzystanie pól wyboru ............................................................310
Wykorzystanie przycisków opcji .....................................................314
Powrót do programu Mad Lib ........................................................318
Podsumowanie ...........................................................................322
Rozdzia(cid:228) 11. Grafika. Gra Pizza Panic ...................................................323
Wprowadzenie do gry Pizza Panic ..................................................323
Wprowadzenie do pakietów pygame i livewires ..............................325
Tworzenie okna graficznego .........................................................325
Ustawienie obrazu t(cid:228)a ..................................................................328
Uk(cid:228)ad wspó(cid:228)rz(cid:246)dnych ekranu graficznego .......................................331
Wy(cid:264)wietlanie duszka ...................................................................332
Wy(cid:264)wietlanie tekstu ....................................................................336
Wy(cid:264)wietlanie komunikatu .............................................................339
Przemieszczanie duszków ............................................................342
Radzenie sobie z granicami ekranu ...............................................344
Obs(cid:228)uga danych wej(cid:264)ciowych z myszy ...........................................347
Wykrywanie kolizji ........................................................................350
Powrót do gry Pizza Panic .............................................................353
Podsumowanie ...........................................................................360
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu.
Gra Astrocrash .................................................................361
Wprowadzenie do gry Astrocrash ..................................................361
Odczyt klawiatury ........................................................................363
Obracanie duszka .......................................................................365
Tworzenie animacji ......................................................................368
Przegl(cid:241)d obrazów eksplozji ...........................................................369
Wykorzystywanie d(cid:274)wi(cid:246)ku i muzyki ................................................371
Planowanie gry Astrocrash ...........................................................376
Utworzenie asteroidów .................................................................377
Obracanie statku ........................................................................380
Poruszanie statku .......................................................................382
Wystrzeliwanie pocisków ..............................................................385
Regulowanie tempa wystrzeliwania pocisków .................................388
Obs(cid:228)uga kolizji ............................................................................390
Dodanie efektów eksplozji ...........................................................393
Dodanie poziomów gry, rejestracji wyników
oraz tematu muzycznego ...........................................................397
Podsumowanie ...........................................................................405
Kup książkęPoleć książkę
Spis tre(cid:264)ci
9
Dodatek A. Opis pakietu livewires ......................................................407
Pliki archiwów .............................................................................407
Dodatek B. Opis pakietu livewires ......................................................409
Pakiet livewires ...........................................................................409
Klasy modu(cid:228)u games ...................................................................409
Funkcje modu(cid:228)u games ................................................................417
Sta(cid:228)e modu(cid:228)u games ...................................................................418
Sta(cid:228)e modu(cid:228)u color ......................................................................422
Skorowidz ........................................................................423
Kup książkęPoleć książkę 10
Python dla ka(cid:276)dego. Podstawy programowania
Kup książkęPoleć książkę12
Dźwięk, animacja
i rozwijanie programu.
Gra Astrocrash
tym rozdziale poszerzysz swoje umiejętności tworzenia programów multimedialnych
o obsługę dźwięku i ruchomych obrazów. Zobaczysz również, jak można pisać
W
duży program etapami. W szczególności nauczysz się:
(cid:132) odczytywać dane z klawiatury,
(cid:132) odtwarzać pliki dźwiękowe,
(cid:132) odtwarzać pliki muzyczne,
(cid:132) tworzyć animacje,
(cid:132) rozwijać program poprzez pisanie coraz bardziej kompletnych jego wersji.
Wprowadzenie do gry Astrocrash
Projekt przedstawiony w tym rozdziale, gra Astrocrash, to moja wersja klasycznej gry
arkadowej Asteroids. W grze Astrocrash gracz steruje statkiem kosmicznym w ruchomym
polu śmiertelnie groźnych asteroidów. Statek może się obracać i wykonywać ruch do
przodu oraz, co najważniejsze, może wystrzeliwać pociski w kierunku asteroidów, aby je
zniszczyć. Gracz ma jednak trochę roboty do wykonania, ponieważ asteroidy dużego
i średniego rozmiaru rozpadają się na dwie mniejsze asteroidy, gdy zostaną zniszczone.
I w tej samej chwili, gdy graczowi uda się unicestwić wszystkie asteroidy, pojawia się ich
nowa, większa fala. Liczba punktów uzyskanych przez gracza zwiększa się wraz z każdą
zniszczoną asteroidą, lecz jeśli tylko statek gracza zderzy się z unoszącą się w przestrzeni
kosmiczną skałą, gra się kończy. Rysunki 12.1 i 12.2 pokazują tę grę w toku.
Kup książkęPoleć książkę362
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Rysunek 12.1. Gracz steruje statkiem kosmicznym i niszczy asteroidy w celu zwi(cid:246)kszenia
swojego wyniku punktowego. (Obraz mg(cid:228)awicy nale(cid:276)y do domeny publicznej.
Dzi(cid:246)ki uprzejmo(cid:264)ci: NASA, The Hubble Heritage Team–AURA/STScl)
Rysunek 12.2. Je(cid:264)li asteroida uderzy w statek gracza, gra si(cid:246) ko(cid:254)czy
Kup książkęPoleć książkęOdczyt klawiatury
363
Odczyt klawiatury
Już wiesz, jak pobierać łańcuchy znaków od użytkownika przy użyciu funkcji input(),
ale odczyt klawiatury w celu identyfikacji pojedynczych naciśnięć klawiszy to inna
kwestia. Na szczęście istnieje nowy obiekt z modułu games, który to właśnie umożliwia.
Prezentacja programu Odczytaj klawisz
Program Odczytaj klawisz wyświetla statek kosmiczny na tle mgławicy. Użytkownik
może przemieszczać statek po całym ekranie za pomocą naciśnięć różnych klawiszy.
Kiedy użytkownik naciska klawisz W, statek porusza się do góry. Gdy użytkownik
naciska klawisz S, statek porusza się w dół. Kiedy użytkownik naciska klawisz A, statek
porusza się w lewo. Kiedy użytkownik naciska klawisz D, statek porusza się w prawo.
Użytkownik może również nacisnąć wiele klawiszy jednocześnie dla uzyskania łącznego
efektu. Na przykład, gdy użytkownik naciska jednocześnie klawisze W i D, statek porusza
się po przekątnej — w prawo, do góry. Program został zilustrowany na rysunku 12.3.
Rysunek 12.3. Statek porusza si(cid:246) po ekranie dzi(cid:246)ki naci(cid:264)ni(cid:246)ciom klawiszy
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to odczytaj_klawisz.py.
Kup książkęPoleć książkę364
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Rozpocz(cid:246)cie programu
Tak jak w przypadku wszystkich programów wykorzystujących pakiet livewires
rozpoczynam od importu potrzebnych modułów i wywołania funkcji inicjalizującej
ekran graficzny:
# Odczytaj klawisz
# Demonstruje odczytywanie klawiatury
from livewires import games
games.init(screen_width = 640, screen_height = 480, fps = 50)
Testowanie stanu klawiszy
Następnie piszę kod klasy reprezentującej statek kosmiczny. W metodzie update()
sprawdzam, czy zostały naciśnięte określone klawisze, i zgodnie z wynikiem tych testów
zmieniam pozycję statku.
class Ship(games.Sprite):
Poruszaj(cid:200)cy si(cid:218) statek kosmiczny.
def update(self):
Kieruj ruchem statku na podstawie wci(cid:258)ni(cid:218)tych klawiszy.
if games.keyboard.is_pressed(games.K_w):
self.y -= 1
if games.keyboard.is_pressed(games.K_s):
self.y += 1
if games.keyboard.is_pressed(games.K_a):
self.x -= 1
if games.keyboard.is_pressed(games.K_d):
self.x += 1
Wykorzystuję nowy obiekt z modułu games o nazwie keyboard. Możesz użyć tego
obiektu do sprawdzenia, czy określone klawisze zostały naciśnięte. Wywołuję metodę
is_pressed() obiektu, która zwraca wartość True, jeśli testowany klawisz jest naciśnięty,
i wartość False w przeciwnym wypadku.
Używam metody is_pressed w ciągu instrukcji if, aby sprawdzić, czy którykolwiek
z czterech klawiszy — W, S, A lub D — nie jest naciśnięty. Jeśli jest naciśnięty klawisz W,
zmniejszam o 1 wartość właściwości y obiektu klasy Ship, przesuwając duszka w górę
ekranu o jeden piksel. Jeśli jest naciśnięty klawisz S, zwiększam wartość właściwości y
obiektu o 1, przesuwając duszka w dół ekranu. Jeśli jest naciśnięty klawisz A, zmniejszam
o 1 wartość właściwości x obiektu, przesuwając duszka w lewo. Jeśli jest naciśnięty
klawisz S, zwiększam wartość właściwości x obiektu o 1, przesuwając duszka w prawo.
Ponieważ wielokrotne wywołania metody is_pressed() mogą odczytywać
jednoczesne naciśnięcia klawiszy, użytkownik może przyciskać wiele klawiszy naraz dla
uzyskania łącznego efektu. Jeśli na przykład użytkownik przytrzymuje w tym samym czasie
wciśnięte klawisze D i S, statek porusza się w dół i w prawo, ponieważ za każdym razem,
gdy wykonywana jest metoda update(), wartość 1 zostaje dodana zarówno do
współrzędnej x, jak i współrzędnej y obiektu klasy Ship.
Kup książkęPoleć książkęObracanie duszka
365
Moduł games zawiera zbiór stałych reprezentujących klawisze, których możesz
używać w roli argumentu w wywołaniu metody is_pressed(). W tym programie
wykorzystuję stałą games.K_w reprezentującą klawisz W, stałą games.K_s odpowiadającą
klawiszowi S, stałą games.K_a oznaczającą klawisz A oraz stałą games.K_d identyfikującą
klawisz D. Schemat nadawania nazw tym stałym jest dość intuicyjny. Oto szybki sposób
na wydedukowanie nazwy większości stałych reprezentujących klawisze:
(cid:132) wszystkie stałe klawiatury zaczynają się od games.K_;
(cid:132) w przypadku klawiszy alfabetycznych dodaj literę z klawisza, po zamianie
na małą, na końcu nazwy stałej; na przykład stała reprezentująca klawisz A
to games.K_a;
(cid:132) w przypadku klawiszy numerycznych dodaj cyfrę z klawisza na końcu nazwy
stałej; na przykład stała reprezentująca klawisz 1 to games.K_1;
(cid:132) w przypadku pozostałych klawiszy często możesz na końcu nazwy stałej dodać
ich nazwę pisaną samymi dużymi literami; na przykład stała reprezentująca
klawisz spacji to games.K_SPACE.
Kompletną listę stałych klawiatury znajdziesz w dokumentacji pakietu livewires,
w dodatku B.
Doko(cid:254)czenie programu
Na koniec piszę znajomą funkcję main(). Ładuję obraz tła przedstawiający mgławicę,
tworzę statek, umieszczając go w środku ekranu, oraz wszystko uruchamiam poprzez
wywołanie metody mainloop().
def main():
nebula_image = games.load_image( mglawica.jpg , transparent = False)
games.screen.background = nebula_image
ship_image = games.load_image( statek.bmp )
the_ship = Ship(image = ship_image,
x = games.screen.width/2,
y = games.screen.height/2)
games.screen.add(the_ship)
games.screen.mainloop()
main()
Obracanie duszka
W rozdziale 11. dowiedziałeś się, jak przemieszczać duszki po ekranie, ale pakiet
livewires umożliwia również ich obracanie. Duszka można obracać, wykorzystując
jedną z jego właściwości.
Kup książkęPoleć książkę366
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Prezentacja programu Obró(cid:232) duszka
W programie Obróć duszka, użytkownik może obracać statek kosmiczny przy użyciu
klawiatury. Kiedy użytkownik naciska klawisz strzałki w górę, statek obraca się w kierunku
zgodnym z ruchem wskazówki zegara. Jeśli użytkownik naciśnie klawisz strzałki w lewo,
statek obróci się w kierunku przeciwnym do ruchu wskazówki zegara. Jeśli naciśnie
klawisz 1, kąt położenia statku zmieni się skokowo na 0 stopni. Jeśli użytkownik naciśnie
klawisz 2, statek zmieni swoją orientację na 90 stopni. Jeśli naciśnie klawisz 3, statek
przyjmie położenie kątowe 180 stopni. Jeśli użytkownik naciśnie klawisz 4, kąt położenia
zmieni się skokowo na 270 stopni. Program został przedstawiony na rysunku 12.4.
Rysunek 12.4. Statek kosmiczny mo(cid:276)e si(cid:246) obraca(cid:232) zgodnie z ruchem wskazówki zegara
lub w kierunku przeciwnym do ruchu wskazówki zegara.
Mo(cid:276)e te(cid:276) przeskoczy(cid:232) do po(cid:228)o(cid:276)enia pod z góry ustalonym k(cid:241)tem
Pu(cid:228)apka
Program Obró(cid:232) duszka sprawdza, czy s(cid:241) wci(cid:264)ni(cid:246)te klawisze cyfr znajduj(cid:241)ce si(cid:246)
u góry klawiatury, powy(cid:276)ej klawiszy z literami, lecz nie sprawdza stanu klawiszy
klawiatury numerycznej.
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to obroc_duszka.py.
Kup książkęPoleć książkęObracanie duszka
367
# Obró(cid:202) duszka
# Demonstruje obracanie duszka
from livewires import games
games.init(screen_width = 640, screen_height = 480, fps = 50)
class Ship(games.Sprite):
Obracaj(cid:200)cy si(cid:218) statek kosmiczny.
def update(self):
Obró(cid:202) w zale(cid:285)no(cid:258)ci od naci(cid:258)ni(cid:218)tych klawiszy.
if games.keyboard.is_pressed(games.K_RIGHT):
self.angle += 1
if games.keyboard.is_pressed(games.K_LEFT):
self.angle -= 1
if games.keyboard.is_pressed(games.K_1):
self.angle = 0
if games.keyboard.is_pressed(games.K_2):
self.angle = 90
if games.keyboard.is_pressed(games.K_3):
self.angle = 180
if games.keyboard.is_pressed(games.K_4):
self.angle = 270
def main():
nebula_image = games.load_image( mglawica.jpg , transparent = False)
games.screen.background = nebula_image
ship_image = games.load_image( statek.bmp )
the_ship = Ship(image = ship_image,
x = games.screen.width/2,
y = games.screen.height/2)
games.screen.add(the_ship)
games.screen.mainloop()
main()
Wykorzystanie w(cid:228)a(cid:264)ciwo(cid:264)ci angle obiektu klasy Sprite
Nowym elementem w programie jest właściwość angle, która reprezentuje orientację
kątową duszka wyrażoną w stopniach. Możesz zwiększać lub zmniejszać wartość tej
właściwości przez dodawanie lub odejmowanie przyrostów, lecz możesz też po prostu
przypisać jej nową wartość w celu zmiany kąta położenia duszka.
W metodzie update() najpierw sprawdzam, czy wciśnięty jest klawisz strzałki w prawo.
Jeśli tak jest, dodaję jedynkę do wartości właściwości angle obiektu, co powoduje obrócenie
duszka o jeden stopień w kierunku ruchu wskazówki zegara. Następnie sprawdzam, czy
wciśnięty jest klawisz strzałki w lewo. Jeśli jest tak w istocie, odejmuję jedynkę od wartości
tej właściwości, powodując obrót duszka o jeden stopień w kierunku przeciwnym do
ruchu wskazówki zegara.
Kup książkęPoleć książkę368
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Kolejny zestaw wierszy kodu obraca statek bezpośrednio do określonego kąta
położenia poprzez przypisanie nowej wartości do właściwości angle. Kiedy użytkownik
naciska klawisz 1, kod przypisuje 0 do właściwości angle i duszek przeskakuje do
położenia pod kątem 0 stopni (jest to jego początkowa orientacja). Kiedy użytkownik
naciska klawisz 2, kod przypisuje do właściwości angle wartość 90 i duszek przeskakuje
do położenia pod kątem 90 stopni. Gdy użytkownik naciska klawisz 3, kod przypisuje do
właściwości angle wartość 180 i duszek przeskakuje do położenia pod kątem 180 stopni.
Wreszcie, gdy użytkownik naciska klawisz 4, kod przypisuje do właściwości angle
wartość 270 i duszek przeskakuje do położenia pod kątem 270 stopni.
Tworzenie animacji
Przemieszczanie duszków i ich obracanie sprawia, że gra staje się bardziej ekscytująca,
lecz dopiero animacja wnosi w nią prawdziwe życie. Na szczęście moduł games zawiera
klasę do obsługi animacji, stosownie nazwaną Animation.
Prezentacja programu Eksplozja
Program Eksplozja tworzy animację wybuchu w środku ekranu graficznego. Animacja
jest odtwarzana w sposób ciągły, żebyś mógł się jej dobrze przyjrzeć. Kiedy skończysz już
podziwiać ten bombowy efekt, możesz zakończyć program przez zamknięcie okna
graficznego. Na rysunku 12.5 prezentuję migawkę programu w akcji.
Rysunek 12.5. Chocia(cid:276) trudno to stwierdzi(cid:232) na podstawie nieruchomego obrazu,
w centrum okna graficznego wykonywana jest animacja wybuchu
Kup książkęPoleć książkęPrzegl(cid:241)d obrazów eksplozji
369
Przegl(cid:241)d obrazów eksplozji
Animacja to sekwencja obrazów (zwanych także ramkami — ang. frames) wyświetlanych
jeden po drugim. Utworzyłem sekwencję dziewięciu obrazów, które, kiedy są wyświetlane
jeden po drugim, tworzą wrażenie ognistej eksplozji. Wszystkie dziewięć obrazków
pokazałem na rysunku 12.6.
Rysunek 12.6. Gdy te dziewi(cid:246)(cid:232) ramek zostanie wy(cid:264)wietlonych w szybkim tempie
jedna po drugiej, otrzymamy wra(cid:276)enie eksplozji
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to eksplozja.py.
Rozpocz(cid:246)cie programu
Jak zawsze, na początku programu importuję potrzebne moduły i wywołuję funkcję
inicjalizującą ekran graficzny:
# Eksplozja
# Demonstruje tworzenie animacji
from livewires import games
games.init(screen_width = 640, screen_height = 480, fps = 50)
Kup książkęPoleć książkę370
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Potem ustawiam tło ekranu graficznego:
nebula_image = games.load_image( mglawica.jpg , transparent = 0)
games.screen.background = nebula_image
Utworzenie listy plików z obrazami
Konstruktor klasy Animation pobiera listę nazw plików zawierających obrazy lub listę
obiektów obrazu reprezentującą sekwencję obrazów do wyświetlenia. Więc w następnej
kolejności tworzę listę nazw plików z obrazami, które zostały pokazane na rysunku 12.6:
explosion_files = [ eksplozja1.bmp ,
eksplozja2.bmp ,
eksplozja3.bmp ,
eksplozja4.bmp ,
eksplozja5.bmp ,
eksplozja6.bmp ,
eksplozja7.bmp ,
eksplozja8.bmp ,
eksplozja9.bmp ]
Utworzenie obiektu klasy Animation
W końcu tworzę obiekt klasy Animation i dodaję go do ekranu:
explosion = games.Animation(images = explosion_files,
x = games.screen.width/2,
y = games.screen.height/2,
n_repeats = 0,
repeat_interval = 5)
games.screen.add(explosion)
Animation jest klasą pochodną klasy Sprite, więc dziedziczy wszystkie jej atrybuty,
właściwości i metody. Podobnie jak w przypadku wszystkich duszków, możesz podać
współrzędne x i y, aby zdefiniować umiejscowienie animacji. W powyższym kodzie
przekazuję współrzędne do konstruktora klasy, tak aby animacja była utworzona
w środku ekranu.
Animacja tym się różni od duszka, że występuje w niej lista obrazów, która jest
przetwarzana cyklicznie. Więc musisz dostarczyć listę nazw plików graficznych w postaci
łańcuchów znaków albo listę obiektów obrazu reprezentujących obrazy, które mają być
wyświetlane. Ja dostarczam listę explosion_files z łańcuchami reprezentującymi nazwy
plików graficznych poprzez parametr images.
Atrybut n_repeats obiektu określa, ile razy animacja (jako sekwencja jej wszystkich
obrazów) zostanie wyświetlona. Wartość domyślna atrybutu n_repeats wynosi 0.
Ponieważ przekazuję 0 do n_repeats, cykl animacji eksplozji będzie powtarzany
bez końca (lub przynajmniej do momentu zamknięcia okna graficznego).
Atrybut repeat_interval obiektu reprezentuje opóźnienie między następującymi po
sobie obrazami. Większa liczba oznacza większe opóźnienie między ramkami, skutkujące
Kup książkęPoleć książkęWykorzystywanie d(cid:274)wi(cid:246)ku i muzyki
371
wolniejszą animacją. Mniejsza liczba reprezentuje mniejszą zwłokę, generując szybszą
animację. Ja przekazuję do atrybutu repeat_interval wartość 5, aby uzyskać prędkość,
jaką uważam za właściwą do wygenerowania przekonującej eksplozji.
Ostatnią, lecz równie ważną czynnością jest uruchomienie programu poprzez
wywołanie metody mainloop() obiektu screen:
games.screen.mainloop()
Wykorzystywanie d(cid:274)wi(cid:246)ku i muzyki
Dźwięk i muzyka dodają nowy, oddziałujący na zmysły wymiar do programów. Ładowanie,
odtwarzanie, powtarzanie w pętli i zatrzymywanie dźwięku i muzyki są łatwe do wykonania
za pomocą modułu games. Chociaż ludzie mogliby się spierać na temat różnicy między
dźwiękiem a muzyką, na gruncie pakietu livewires nie ma żadnej takiej dyskusji —
istnieje w nim wyraźne rozróżnienie między tymi dwoma elementami.
Prezentacja programu D(cid:274)wi(cid:246)k i muzyka
Program Dźwięk i muzyka umożliwia użytkownikowi odtwarzanie, powtarzanie w pętli
i zatrzymywanie efektu dźwiękowego wystrzelonego pocisku oraz tematu muzycznego
z gry Astrocrash. Użytkownik może nawet odtwarzać obydwa te elementy jednocześnie.
Rysunek 12.7 pokazuje uruchomiony program (lecz niestety nie jest w stanie
wygenerować dźwięku).
Rysunek 12.7. Program umo(cid:276)liwia u(cid:276)ytkownikowi odtworzenie d(cid:274)wi(cid:246)ku i fragmentu muzyki
Kup książkęPoleć książkę372
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Wskazówka
Kiedy uruchomisz ten program, b(cid:246)dzie Ci potrzebna interakcja z oknem konsoli.
Powiniene(cid:264) umie(cid:264)ci(cid:232) okno konsoli w takiej pozycji, aby nie by(cid:228)o ono zakryte
przez okno graficzne. Mo(cid:276)esz zignorowa(cid:232) lub nawet zminimalizowa(cid:232) utworzone
przez program okno graficzne.
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to dzwiek_i_muzyka.py.
Praca z d(cid:274)wi(cid:246)kami
Możesz utworzyć obiekt dźwiękowy do użytku programu poprzez załadowanie pliku
typu WAV. Format WAV znakomicie się nadaje do zapisu efektów dźwiękowych,
ponieważ może zostać użyty do zakodowania wszystkiego, co zarejestrujesz za pomocą
mikrofonu.
Za(cid:228)adowanie d(cid:274)wi(cid:246)ku
Program rozpoczynam jak zawsze:
# D(cid:283)wi(cid:218)k i muzyka
# Demonstruje odtwarzanie plików d(cid:283)wi(cid:218)kowych i muzycznych
from livewires import games
games.init(screen_width = 640, screen_height = 480, fps = 50)
Potem ładuję plik WAV, wykorzystując funkcję load_sound() modułu games.
# za(cid:239)aduj plik d(cid:283)wi(cid:218)kowy
missile_sound = games.load_sound( pocisk.wav )
Funkcja przyjmuje łańcuch znaków reprezentujący nazwę pliku dźwiękowego, który
ma zostać załadowany. Ładuję plik pocisk.wav i przypisuję nowo utworzony obiekt
dźwiękowy do zmiennej missile_sound.
Pu(cid:228)apka
Za pomoc(cid:241) funkcji load_sound() mo(cid:276)na (cid:228)adowa(cid:232) tylko pliki WAV.
Następnie ładuję plik muzyczny:
# za(cid:239)aduj plik muzyczny
games.music.load( temat.mid )
Omówienie sposobu obsługi muzyki odłożę do momentu, gdy skończę
demonstrowanie dźwięków.
Kup książkęPoleć książkęWykorzystywanie d(cid:274)wi(cid:246)ku i muzyki
373
Odtworzenie d(cid:274)wi(cid:246)ku
Następnie tworzę menu, z czym po raz pierwszy spotkałeś się w rozdziale 5.:
choice = None
while choice != 0 :
print(
D(cid:283)wi(cid:218)k i muzyka
0 - zako(cid:241)cz
1 - odtwórz d(cid:283)wi(cid:218)k pocisku
2 - odtwarzaj cyklicznie d(cid:283)wi(cid:218)k pocisku
3 - zatrzymaj odtwarzanie d(cid:283)wi(cid:218)ku pocisku
4 - odtwórz temat muzyczny
5 - odtwarzaj cyklicznie temat muzyczny
6 - zatrzymaj odtwarzanie tematu muzycznego
)
choice = input( Wybieram: )
print()
# wyjd(cid:283)
if choice == 0 :
print( (cid:191)egnaj! )
Jeśli użytkownik wprowadzi 0, program pożegna użytkownika i zakończy działanie.
Poniższy kod obsługuje przypadek, w którym użytkownik wprowadza 1:
# odtwórz d(cid:283)wi(cid:218)k pocisku
elif choice == 1 :
missile_sound.play()
print( Odtworzenie d(cid:283)wi(cid:218)ku pocisku. )
Aby odtworzyć dźwięk jeden raz, wywołuję metodę play() obiektu dźwiękowego.
Kiedy dźwięk jest odtwarzany, zajmuje jeden z ośmiu dostępnych kanałów dźwiękowych.
Aby odtworzyć dźwięk, potrzeba przynajmniej jednego otwartego kanału dźwiękowego.
Kiedy zajętych jest wszystkich osiem kanałów, wywołanie metody play() obiektu
dźwiękowego nie przyniesie żadnego efektu.
Jeśli wywołasz metodę play() obiektu dźwiękowego, który jest już odtwarzany,
rozpocznie się odtwarzanie tego dźwięku na innym kanale, jeśli taki jest dostępny.
Cykliczne odtwarzanie d(cid:274)wi(cid:246)ku
Możesz odtwarzać dźwięk cyklicznie poprzez przekazanie liczby dodatkowych
odtworzeń, jakie mają mieć miejsce, do metody play() obiektu. Jeśli na przykład
przekażesz do play() liczbę 3, odpowiedni dźwięk zostanie odtworzony cztery razy
(początkowe odtworzenie plus trzy powtórzenia). Możesz cyklicznie odtwarzać dźwięk
bez końca po przekazaniu wartości -1 do metody play().
Poniższy kod obsługuje przypadek, gdy użytkownik wprowadza 2:
Kup książkęPoleć książkę374
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
# odtwarzaj cyklicznie d(cid:283)wi(cid:218)k pocisku
elif choice == 2 :
loop = int(input( Ile razy powtórzy(cid:202) odtwarzanie? (-1 = bez ko(cid:241)ca): ))
missile_sound.play(loop)
print( Cykliczne odtwarzanie d(cid:283)wi(cid:218)ku pocisku. )
W tym fragmencie kodu pobieram liczbę wskazującą, ile dodatkowo razy użytkownik
chce usłyszeć odgłos pocisku, a następnie przekazuję tę wartość do metody play()
obiektu dźwiękowego.
Zatrzymanie odtwarzania d(cid:274)wi(cid:246)ku
Odtwarzanie dźwięku przez obiekt dźwiękowy zatrzymuje się poprzez wywołanie metody
stop(). Zatrzymuje ona ten konkretny dźwięk na wszystkich kanałach, na których jest
odtwarzany. Jeśli wywołasz metodę stop() obiektu dźwiękowego, który w danej chwili
nic nie odtwarza, przekonasz się, że pakiet livewires jest tolerancyjny i nie poskarży się
poprzez zgłoszenie błędu.
Jeśli użytkownik wprowadzi 3, poniższy kod zatrzyma odtwarzanie odgłosu pocisku
(jeśli takowy jest właśnie odtwarzany):
# zatrzymaj odtwarzanie d(cid:283)wi(cid:218)ku pocisku
elif choice == 3 :
missile_sound.stop()
print( Zatrzymanie odtwarzania d(cid:283)wi(cid:218)ku pocisku. )
Praca z muzyk(cid:241)
W pakiecie livewires muzyka jest obsługiwana nieco inaczej niż dźwięk. Istnieje tylko
jeden kanał muzyczny, więc w danym momencie jako bieżący plik muzyczny może
zostać wyznaczony tylko jeden plik. Kanał muzyczny jest jednak bardziej elastyczny
niż kanały dźwiękowe. Akceptuje on wiele różnych typów plików dźwiękowych, takich
jak WAV, MP3, OGG i MIDI. Wreszcie, ponieważ istnieje tylko jeden kanał muzyczny,
nie tworzy się nowego obiektu dla każdego pliku muzycznego. Zamiast tego masz dostęp
do zestawu funkcji służących do ładowania, odtwarzania i zatrzymywania muzyki.
Za(cid:228)adowanie muzyki
Widziałeś kod odpowiedzialny za załadowanie pliku muzycznego w podpunkcie
„Załadowanie dźwięku” punktu „Praca z dźwiękami”. Kod skorzystał z dostępu do
obiektu music modułu games. To dzięki obiektowi music możesz załadować, odtworzyć
i zatrzymać pojedynczą ścieżkę muzyczną.
Kod, którego użyłem do załadowania ścieżki muzycznej, games.music.load( temat.mid ),
ustawia bieżącą muzykę na plik temat.mid typu MIDI. Muzykę ładuje się poprzez wywołanie
metody games.music.load() i przekazanie do niej nazwy pliku muzycznego w postaci
łańcucha znaków.
Masz dostępną tylko jedną ścieżkę muzyczną. Więc jeśli załadujesz nowy plik
muzyczny, zastąpi on muzykę bieżącą.
Kup książkęPoleć książkęWykorzystywanie d(cid:274)wi(cid:246)ku i muzyki
375
Odtworzenie muzyki
Poniższy kod obsługuje przypadek, gdy użytkownik wprowadzi 4:
# odtwórz temat muzyczny
elif choice == 4 :
games.music.play()
print( Odtworzenie tematu muzycznego. )
W rezultacie komputer odtwarza plik muzyczny, który załadowałem, temat.mid.
Jeśli nie przekażesz żadnych wartości do metody games.music.play(), muzyka jest
odtwarzana tylko raz.
Cykliczne odtwarzanie muzyki
Możesz odtwarzać muzykę cyklicznie, tyle razy, ile chcesz, po przekazaniu do metody
play() liczby dodatkowych odtworzeń. Jeśli na przykład przekażesz wartość 3 do metody
games.music.play(), muzyka zostanie odtworzona cztery razy (odtworzenie początkowe
plus trzy powtórzenia). Możesz cyklicznie odtwarzać muzykę bez końca po przekazaniu
wartości -1 do metody.
Poniższy kod obsługuje przypadek, w którym użytkownik wprowadza 5:
# odtwarzaj cyklicznie temat muzyczny
elif choice == 5 :
loop = int(input( Ile razy powtórzy(cid:202) odtwarzanie? (-1 = bez ko(cid:241)ca): ))
games.music.play(loop)
print( Cykliczne odtwarzanie tematu muzycznego. )
W tym fragmencie kodu wczytuję liczbę dodatkowych odtworzeń tematu muzycznego,
jakiej użytkownik chce posłuchać, a następnie przekazuję tę wartość do metody play().
Zatrzymanie odtwarzania muzyki
Jeśli użytkownik wprowadzi opcję 6, poniższy kod zatrzyma odtwarzanie muzyki (jeśli
faktycznie jest wykonywane):
# zatrzymaj odtwarzanie tematu muzycznego
elif choice == 6 :
games.music.stop()
print( Zatrzymanie odtwarzania tematu muzycznego. )
Możesz spowodować zatrzymanie odtwarzania bieżącej muzyki poprzez wywołanie
metody games.music.stop(), co właśnie w tym miejscu kodu robię. Jeśli wywołasz tę
metodę, kiedy nie jest odtwarzana żadna muzyka, moduł livewires okazuje się
wyrozumiały i nie generuje błędu.
Doko(cid:254)czenie programu
Wreszcie kończę program obsługą nieprawidłowego wyboru i oczekiwaniem na decyzję
użytkownika:
Kup książkęPoleć książkę376
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
# nieprzewidziany wybór
else:
print( \nNiestety, , choice, nie jest prawid(cid:239)owym wyborem. )
input( \n\nAby zako(cid:241)czy(cid:202) program, naci(cid:258)nij klawisz Enter. )
Planowanie gry Astrocrash
Pora na powrót do projektu rozdziału — gry Astrocrash. Zamierzam pisać stopniowo
coraz kompletniejsze wersję gry, aż osiągnę postać końcową, lecz nadal odczuwam
potrzebę wymienienia kilku szczegółów programu, w tym głównych elementów gry,
kilku niezbędnych klas i wymaganych zasobów multimedialnych.
Elementy gry
Chociaż moja gra jest oparta na klasycznej grze wideo, którą dobrze znam (a poznawałem ją
etapami, drogą prób i błędów), wypisanie listy jej elementów jest nadal dobrym pomysłem:
(cid:132) statek kosmiczny powinien obracać się i inicjować (lub przyśpieszać) ruch
do przodu w reakcji na klawisze naciśnięte przez gracza;
(cid:132) statek powinien wystrzeliwać pociski po naciśnięciu przez gracza
odpowiedniego klawisza;
(cid:132) asteroidy powinny przelatywać przez ekran z różnymi prędkościami; mniejsze
asteroidy powinny mieć generalnie wyższe prędkości niż większe;
(cid:132) statek, wszystkie pociski i asteroidy powinny „przewijać się” przez brzegi ekranu —
jeśli wyjdą poza granicę ekranu, powinny ukazać się po przeciwnej stronie;
(cid:132) jeśli pocisk uderzy w dowolny inny obiekt na ekranie, powinien zniszczyć ten
obiekt i sam siebie w efektownej, ognistej eksplozji;
(cid:132) jeśli statek uderzy w dowolny inny obiekt na ekranie, powinien zniszczyć ten
obiekt i sam siebie w efektownej, ognistej eksplozji;
(cid:132) jeśli statek zostaje zniszczony, gra się kończy;
(cid:132) jeśli zostaje zniszczona duża asteroida, powinny utworzyć się dwie asteroidy
średniej wielkości; jeśli zostaje zniszczona asteroida średniego rozmiaru,
powinny powstać dwie małe asteroidy; jeśli zostaje zniszczona mała asteroida,
nie powstają już żadne nowe;
(cid:132) za każdym razem, gdy gracz zniszczy asteroidę, jego dorobek punktowy powinien
się zwiększyć; mniejsze asteroidy powinny być warte więcej punktów niż większe;
(cid:132) liczba punktów uzyskanych przez gracza powinna być wyświetlana w prawym
górnym rogu ekranu;
(cid:132) kiedy tylko wszystkie asteroidy zostaną zniszczone, powinna zostać utworzona
nowa, większa fala asteroidów.
Pomijam kilka elementów oryginału, aby zachować prostotę gry.
Kup książkęPoleć książkęUtworzenie asteroidów
377
Klasy potrzebne w grze
Następnie sporządzam listę klas, które, jak sądzę, będą mi potrzebne:
(cid:132) Ship,
(cid:132) Missile,
(cid:132) Asteroid,
(cid:132) Explosion.
Już trochę wiem o tych klasach. Ship, Missile i Asteroid powinny być klasami
pochodnymi klasy games.Sprite, podczas gdy Explosion powinna być klasą pochodną
klasy games.Animation. Wiem też, że ta lista może ulec zmianie, kiedy teorię będę
zamieniał w praktykę i gdy będę pisał kod gry.
Zasoby gry
Ponieważ gra zawiera dźwięk, muzykę, duszki i animację, wiem, że muszę utworzyć
pewną liczbę plików multimedialnych. Oto lista, jaką udało mi się stworzyć:
(cid:132) plik graficzny reprezentujący statek kosmiczny,
(cid:132) plik graficzny reprezentujący pociski,
(cid:132) trzy pliki graficzne, po jednym dla każdego rozmiaru asteroidy,
(cid:132) seria plików graficznych do animacji eksplozji,
(cid:132) plik dźwiękowy imitujący rozpędzanie statku,
(cid:132) plik dźwiękowy z odgłosem wystrzeliwania pocisku,
(cid:132) plik dźwiękowy imitujący eksplozję obiektu,
(cid:132) plik z tematem muzycznym.
Utworzenie asteroidów
Ponieważ w grze mają występować śmiercionośne asteroidy, pomyślałem, że zacznę od nich.
Choć wydaje się, że jest to dla mnie najlepszy wybór pierwszego kroku, w przypadku
innego programisty może być inaczej — i jest to w porządku. Mógłbyś oczywiście wybrać
inny pierwszy krok, taki jak umieszczenie na ekranie statku kosmicznego gracza. Nie
istnieje jeden właściwy pierwszy krok. Najważniejszą rzeczą jest zdefiniowanie i wykonanie
programów „na jeden kęs”, które, bazując jeden na drugim, wypracowują ścieżkę do
kompletnego projektu.
Program Astrocrash01
Program Astrocrash01 tworzy okno graficzne, ustawia tło w postaci mgławicy i tworzy
osiem asteroid w losowo wybranych miejscach. Prędkość każdej asteroidy jest również
Kup książkęPoleć książkę378
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
obliczana z uwzględnieniem losowości, lecz mniejsze asteroidy mogą się poruszać
szybciej niż większe. Na rysunku 12.8 pokazuję program w akcji.
Rysunek 12.8. Pole poruszaj(cid:241)cych si(cid:246) asteroid stanowi podstaw(cid:246) gry
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to astrocrash01.py.
Rozpocz(cid:246)cie programu
Program rozpoczyna się jak większość pozostałych:
# Astrocrash01
# Tworzy poruszaj(cid:200)ce si(cid:218) po ekranie asteroidy
import random
from livewires import games
games.init(screen_width = 640, screen_height = 480, fps = 50)
Importuję moduł random, aby wygenerować współrzędne x i y dla asteroid.
Kup książkęPoleć książkęUtworzenie asteroidów
379
Klasa Asteroid
Klasa Asteroid jest wykorzystywana do tworzenia poruszających się asteroid:
class Asteroid(games.Sprite):
Asteroida przelatuj(cid:200)ca przez ekran.
SMALL = 1
MEDIUM = 2
LARGE = 3
images = {SMALL : games.load_image( asteroida_mala.bmp ),
MEDIUM : games.load_image( asteroida_sred.bmp ),
LARGE : games.load_image( asteroida_duza.bmp ) }
SPEED = 2
Pierwszą moją czynnością jest zdefiniowanie stałych klasowych reprezentujących
trzy różne wielkości asteroid: SMALL (mała), MEDIUM (średniego rozmiaru) i LARGE (duża).
Następnie tworzę słownik z rozmiarami i odpowiadającymi im obiektami obrazów
asteroid. W ten sposób mogę wykorzystać stałą reprezentującą rozmiar do znalezienia
odpowiedniego obiektu obrazu. Na koniec tworzę stałą klasową o nazwie SPEED, której
użyję jako podstawy do obliczenia ulosowionej prędkości każdej asteroidy.
Metoda __init__()
W następnej kolejności zajmuję się zdefiniowaniem konstruktora:
def __init__(self, x, y, size):
Inicjalizuj duszka asteroidy.
super(Asteroid, self).__init__(
image = Asteroid.images[size],
x = x, y = y,
dx = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size,
dy = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size)
self.size = size
Wartość przekazana poprzez parametr size reprezentuje wielkość asteroidy
i powinna być równa jednej ze stałych rozmiaru: Asteroid.SMALL, Asteroid.MEDIUM
lub Asteroid.LARGE. Na podstawie wartości size pobierany jest odpowiedni obraz nowej
asteroidy, który następnie zostaje przekazany do konstruktora klasy Sprite (ponieważ
Sprite jest klasą nadrzędną klasy Asteroid). Do konstruktora klasy Sprite zostają również
przekazane wartości x i y reprezentujące położenie kosmicznej skały, przekazane
wcześniej do konstruktora klasy Asteroid.
Konstruktor klasy Asteroid generuje losowe wartości składowych prędkości nowego
obiektu i przekazuje je do konstruktora klasy Sprite. Składowe prędkości mają wartości
losowe, ale mniejsze asteroidy mogą się potencjalnie poruszać szybciej niż większe.
W końcu konstruktor klasy Asteroid tworzy i inicjalizuje atrybut size obiektu.
Kup książkęPoleć książkę380
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Metoda update()
Metoda update() utrzymuje asteroidę w grze poprzez przeniesienie jej na przeciwległy
brzeg ekranu:
def update(self):
Przenie(cid:258) asteroid(cid:218) na przeciwleg(cid:239)y brzeg ekranu.
if self.top games.screen.height:
self.bottom = 0
if self.bottom 0:
self.top = games.screen.height
if self.left games.screen.width:
self.right = 0
if self.right 0:
self.left = games.screen.width
Funkcja main()
Na koniec funkcja main() ustawia tło w postaci mgławicy oraz tworzy osiem asteroid
w przypadkowych miejscach ekranu:
def main():
# ustaw t(cid:239)o
nebula_image = games.load_image( mglawica.jpg )
games.screen.background = nebula_image
# utwórz 8 asteroid
for i in range(8):
x = random.randrange(games.screen.width)
y = random.randrange(games.screen.height)
size = random.choice([Asteroid.SMALL, Asteroid.MEDIUM, Asteroid.LARGE])
new_asteroid = Asteroid(x = x, y = y, size = size)
games.screen.add(new_asteroid)
games.screen.mainloop()
# wystartuj!
main()
Obracanie statku
Aby wykonać swoje następne zadanie, wprowadzam statek kosmiczny gracza. Moim
skromnym celem jest umożliwienie użytkownikowi obracania statku za pomocą klawiszy
strzałek. Do pozostałych funkcji statku zamierzam zabrać się później.
Kup książkęPoleć książkęObracanie statku
381
Program Astrocrash02
Program Astrocrash02 stanowi rozszerzenie programu Astrocrash01. W nowej wersji
tworzę w środku ekranu statek, który gracz może obracać. Jeśli gracz naciska klawisz
strzałki w prawo, statek obraca się zgodnie z ruchem wskazówek zegara. Jeśli zaś gracz
naciska klawisz strzałki w lewo, statek obraca się w kierunku przeciwnym do ruchu
wskazówek zegara. Na rysunku 12.9 pokazuję ten program w działaniu.
Rysunek 11.9. Statek kosmiczny gracz stanowi teraz cz(cid:246)(cid:264)(cid:232) akcji
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to astrocrash02.py.
Klasa Ship
Moim głównym zadaniem jest napisanie kodu klasy Ship reprezentującej statek
kosmiczny gracza:
class Ship(games.Sprite):
Statek kosmiczny gracza.
image = games.load_image( statek.bmp )
ROTATION_STEP = 3
Kup książkęPoleć książkę382
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
def update(self):
Obró(cid:202) statek zgodnie z naci(cid:258)ni(cid:218)tym klawiszem.
if games.keyboard.is_pressed(games.K_LEFT):
self.angle -= Ship.ROTATION_STEP
if games.keyboard.is_pressed(games.K_RIGHT):
self.angle += Ship.ROTATION_STEP
Ta klasa jest podobna do klasy występującej w programie Obróć duszka z wcześniejszej
części tego rozdziału, lecz istnieje kilka różnic. Po pierwsze, ładuję obraz statku i przypisuję
uzyskany w ten sposób obiekt obrazu do zmiennej klasowej o nazwie image. Po drugie,
wykorzystuję stałą klasową, ROTATION_STEP, do reprezentowania liczby stopni, o jaką
statek się obraca.
Konkretyzacja obiektu klasy Ship
Moją ostatnią czynnością w tej nowej wersji gry jest konkretyzacja obiektu klasy Ship
oraz dodanie go do ekranu. Tworzę nowy statek w funkcji main():
# utwórz statek
the_ship = Ship(image = Ship.image,
x = games.screen.width/2,
y = games.screen.height/2)
games.screen.add(the_ship)
Poruszanie statku
W następnej wersji programu wprawiam statek w ruch. Gracz może nacisnąć strzałkę
w górę, aby włączyć silnik statku. Dzięki temu na statek oddziałuje siła ciągu, pchając go
w kierunku, jaki wskazuje przód statku. Ponieważ brak jest tarcia, statek kontynuuje
poruszanie się, nie tracąc prędkości nadanej mu na początku przez gracza.
Program Astrocrash03
Kiedy gracz włącza silnik statku, program Astrocrash03 zmienia prędkość statku
w sposób zależny od położenia kątowego statku (czemu towarzyszy odpowiedni
efekt dźwiękowy). Program został zilustrowany na rysunku 12.10.
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to astrocrash03.py.
Import modu(cid:228)u math
Moją pierwszą czynnością jest umieszczenie na początku programu instrukcji
importującej nowy moduł:
import math, random
Kup książkęPoleć książkęPoruszanie statku
383
Rysunek 12.10. Teraz statek mo(cid:276)e si(cid:246) porusza(cid:232) po ekranie
Moduł math zawiera znaczną liczbę funkcji i stałych matematycznych, ale niech Cię to
nie przeraża. W tym programie użyję tylko kilku z nich.
Dodanie do klasy Ship zmiennej i sta(cid:228)ej klasowej
Tworzę stałą klasową, VELOCITY_STEP, którą wykorzystam do zmiany prędkości statku:
VELOCITY_STEP = .03
Użycie większej liczby spowodowałoby szybsze przyśpieszanie statku,
podczas gdy mniejsza liczba sprawiłaby, że statek przyśpieszałby wolniej.
Dodaję również nową zmienną klasową, sound, mającą reprezentować dźwięk
towarzyszący przyśpieszaniu statku:
sound = games.load_sound( przyspieszenie.wav )
Modyfikacja metody update() klasy Ship
Następnie dodaję nowy kod na końcu metody update() klasy Ship, aby sprawić, by statek
się poruszał. Sprawdzam, czy gracz naciska klawisz strzałki w górę. Jeśli ma to miejsce,
odtwarzam dźwięk przyśpieszającego statku:
Kup książkęPoleć książkę384
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
# zastosuj si(cid:239)(cid:218) ci(cid:200)gu przy naci(cid:258)ni(cid:218)tym klawiszu strza(cid:239)ki w gór(cid:218)
if games.keyboard.is_pressed(games.K_UP):
Ship.sound.play()
Poza tym, gdy gracz naciska klawisz strzałki w górę, muszę zmieniać składowe
prędkości statku (właściwości dx i dy obiektu klasy Ship). Więc jak, mając dany kąt
położenia statku, mogę obliczyć wartość, o jaką powinienem zmienić każdą ze składowych
prędkości? Odpowiedź daje trygonometria. Poczekaj, nie zamykaj z trzaskiem tej książki
i nie uciekaj, gdzie Cię nogi poniosą, wykrzykując coś bez ładu i składu. Jak obiecałem,
do tych obliczeń wykorzystam tylko dwie funkcję matematyczne w paru wierszach kodu.
Aby rozpocząć ten proces, obliczam kąt położenia statku po zamianie stopni
na radiany:
# zmie(cid:241) sk(cid:239)adowe pr(cid:218)dko(cid:258)ci w zale(cid:285)no(cid:258)ci od k(cid:200)ta po(cid:239)o(cid:285)enia statku
angle = self.angle * math.pi / 180 # zamie(cid:241) na radiany
Radian to tylko miara obrotu, podobnie jak stopień. Moduł math w języku Python
wymaga, aby miary kątów były wyrażone w radianach (podczas gdy pakiet livewires
używa stopni), więc z tego powodu muszę dokonać konwersji. W obliczeniu
wykorzystuję stałą pi modułu math, która reprezentuje liczbę π.
Kiedy już mam kąt położenia statku wyrażony w radianach, mogę obliczyć, o jaką
wartość powinienem zmienić każdą ze składowych prędkości, wykorzystując funkcje
sin() i cos() obliczające sinus i cosinus kąta. W poniższych wierszach zostają obliczone
nowe wartości właściwości dx i dy obiektu:
self.dx += Ship.VELOCITY_STEP * math.sin(angle)
self.dy += Ship.VELOCITY_STEP * -math.cos(angle)
Zasadniczo math.sin(angle) reprezentuje procent siły ciągu powodujący zmianę
prędkości statku w kierunku osi x, podczas gdy -math.cos(angle) reprezentuje procent
siły ciągu zmieniający prędkość statku w kierunku osi y.
Pozostaje tylko zająć się granicami ekranu. Korzystam z tej samej strategii, której
używałem w przypadku asteroid: statek wychodzący poza krawędź ekranu powinien
wrócić po przeciwnej stronie. Prawdę mówiąc, kopiuję kod z metody update() klasy
Asteroid i wklejam go na końcu metody update() w klasie Ship:
# przenie(cid:258) statek na przeciwleg(cid:239)y brzeg ekranu
if self.top games.screen.height:
self.bottom = 0
if self.bottom 0:
self.top = games.screen.height
if self.left games.screen.width:
self.right = 0
if self.right 0:
self.left = games.screen.width
Kup książkęPoleć książkęWystrzeliwanie pocisków
385
Chociaż jest to skuteczne, kopiowanie i wklejanie dużych fragmentów kodu to zwykle
oznaka słabości projektu. Wrócę do tego kodu później, aby znaleźć bardziej eleganckie
rozwiązanie.
Pu(cid:228)apka
Powtarzaj(cid:241)ce si(cid:246), du(cid:276)e porcje kodu powoduj(cid:241) rozd(cid:246)cie programów i sprawiaj(cid:241),
(cid:276)e staj(cid:241) si(cid:246) one trudniejsze do konserwacji. Kiedy widzisz powtarzaj(cid:241)cy si(cid:246) kod,
to cz(cid:246)sto pora na wprowadzenie nowej funkcji lub klasy. Pomy(cid:264)l, jak móg(cid:228)by(cid:264)
skonsolidowa(cid:232) kod w jednym miejscu i wywo(cid:228)ywa(cid:232) go z innych cz(cid:246)(cid:264)ci programu,
w których powtarzaj(cid:241)cy si(cid:246) kod aktualnie wyst(cid:246)puje.
Wystrzeliwanie pocisków
Następnie umożliwię statkowi wystrzeliwanie pocisków. Kiedy gracz naciska klawisz
spacji, wystrzeliwany jest pocisk z działa statku, który leci w kierunku wskazywanym
przez przód statku. Pocisk powinien niszczyć wszystko, w co uderza, ale aby nie
komplikować spraw, odkładam frajdę niszczenia do jednej z późniejszych wersji
programu.
Program Astrocrash04
Program Astrocrash04 pozwala graczowi na wystrzeliwanie pocisków poprzez naciśnięcie
klawisza spacji, lecz jest z tym pewien problem. Jeśli gracz przytrzymuje naciśnięty
klawisz spacji, ze statku wylatuje strumień pocisków w tempie około 50 na sekundę.
Muszę ograniczyć tempo wystrzeliwania pocisków, lecz zostawiam ten problem do
następnej wersji gry. Na rysunku 12.11 przedstawiłem program Astrocrash04 z pełnym
realizmem.
Kod tego programu możesz znaleźć na stronie internetowej tej książki
(http://www.helion.pl/ksiazki/pytdk3.htm), w folderze rozdziału 12.; nazwa pliku
to astrocrash04.py.
Modyfikacja metody update() klasy Ship
Modyfikuję metodę update() klasy Ship poprzez dodanie kodu, dzięki któremu statek
może wystrzeliwać pociski. Jeśli gracz naciśnie klawisz spacji, tworzony jest nowy pocisk:
# wystrzel pocisk, je(cid:258)li jest naci(cid:258)ni(cid:218)ty klawisz spacji
if games.keyboard.is_pressed(games.K_SPACE) or True:
new_missile = Missile(self.x, self.y, self.angle)
games.screen.add(new_missile)
Oczywiście, aby skonkretyzować nowy obiekt przy użyciu wyrażenia Missile(self.x,
self.y, self.angle), muszę napisać taką drobną rzecz… jak klasa Missile.
Kup książkęPoleć książkę386
Rozdzia(cid:228) 12. D(cid:274)wi(cid:246)k, animacja i rozwijanie programu. Gra Astrocrash
Rysunek 12.11. Tempo wystrzeliwania pocisków jest zbyt du(cid:276)e
Klasa Missile
Piszę kod klasy Missile mającej reprezentować pociski wystrzeliwane przez statek.
Zaczynam od utworzenia zmiennych i stałych klasowych:
class Missile(games.Sprite):
Pocisk wystrzelony przez statek gracza.
image = games.load_image( pocisk.bmp )
sound = games.load_sound( pocisk.wav )
BUFFER = 40
VELOCITY_FACTOR = 7
LIFETIME = 40
Zmienna image ma reprezentować pocisk — pełne, czerwone kółko. Zmienna sound
reprezentuje efekt dźwiękowy wystrzeliwania pocisku. Stała BUFFER definiuje odległość
miejsca utworzenia nowego pocisku od statku (żeby pocisk nie został utworzony
na wierzchu statku). Stała VELOCITY_FACTOR wpływa na szybkość lotu pocisku.
Wreszcie stała LIFETIME określa długość czasu istnienia pocisku przed jego zniknięciem
(żeby pocisk nie latał bez końca po ekranie).
Metoda __init__()
Rozpoczynam kod konstruktora klasy od następujących wierszy:
def __init__(self, ship_x, ship_y, ship_angle):
Inicjalizuj duszka pocisku.
Kup książkęP
Pobierz darmowy fragment (pdf)