Masz pomysł na grę komputerową i chcesz ją urzeczywistnić? A może zastanawiałeś się kiedyś, jak pisze się gry komputerowe? Ta wikiHow uczy, jak napisać trzy podstawowe gry komputerowe w Pythonie. Aby stworzyć swoją pierwszą grę, będziesz potrzebować podstawowej wiedzy na temat Pythona i ogólnych koncepcji programowania.
Kroki
Część 1 z 3: Tworzenie gry tekstowej
Krok 1. Wybierz język programowania
Wszystkie języki programowania są różne, więc będziesz musiał zdecydować, którego użyjesz do napisania swojej gry. Każdy główny język programowania obsługuje wprowadzanie i wyprowadzanie tekstu oraz konstrukcje jeśli (główne rzeczy, których potrzebujesz do prostej gry tekstowej), więc zbadaj opcje i zdecyduj, z którym czujesz się najbardziej komfortowo i który jest poświęcony nauce. Oto kilka czynników do rozważenia:
-
Do czego najczęściej używany jest język?
Niektóre języki programowania, takie jak JavaScript, są przeznaczone do użytku w Internecie, podczas gdy inne, takie jak Python, C lub C++, są przeznaczone do uruchamiania programów komputerowych. W swojej grze skup się na języku o szerszym zakresie zastosowań, takim jak Python, C, C++ lub JavaScript.
-
Jak trudno jest się nauczyć?
Chociaż pisanie programu powinno być dość łatwe po pewnej praktyce w dowolnym normalnym języku programowania (tj. Nie zaprojektowanym specjalnie tak, aby był mylący jak Malbolge), niektóre są bardziej przyjazne dla początkujących niż inne. Na przykład Java i C będą wymagały zrozumienia głębszych koncepcji programowania niż coś takiego jak Python, który jest znany z bardziej przystępnej i prostej składni.
-
Gdzie mogę z niego skorzystać?
Prawdopodobnie chcesz, aby ludzie na różnych systemach, takich jak Linux, Mac lub Windows, mogli grać w twoją grę. Dlatego nie powinieneś używać języka, który jest obsługiwany tylko w kilku systemach, takich jak Visual Basic, który jest obsługiwany tylko w systemie Windows.
W tym artykule użyjemy Pythona jako przykładów gry tekstowej, ale możesz sprawdzić, jak koncepcje są wykonywane w dowolnym innym języku programowania.
Krok 2. Przygotuj komputer
Dwa główne komponenty, których będziesz potrzebować, to edytor tekstu, w którym napiszesz swój kod, oraz kompilator, za pomocą którego zmienisz go w grę. Jeśli chcesz skorzystać z przykładu z tego artykułu, powinieneś zainstalować Pythona i nauczyć się uruchamiać programy. Jeśli chcesz, możesz skonfigurować IDE (zintegrowane środowisko pulpitu), które łączy edycję, kompilację i debugowanie w jednym programie. IDE Pythona nazywa się IDLE. Ale możesz też po prostu użyć dowolnego edytora tekstu obsługującego zwykły tekst, takiego jak Notatnik dla Windows, TextEdit dla macOS lub Vim dla Linuxa.
Krok 3. Napisz kod, aby przywitać gracza
Gracz będzie chciał wiedzieć, co się dzieje i co musi zrobić, więc powinieneś wydrukować dla niego jakiś tekst.
-
Odbywa się to za pomocą funkcji print() w Pythonie. Aby to wypróbować, otwórz nowy plik z rozszerzeniem.py, wprowadź do niego następujący kod, zapisz i uruchom:
print("Witamy w grze w zgadywanie liczb!") print("Wpisz liczbę całkowitą od 1 do 1000:")
Krok 4. Wygeneruj losową liczbę
Zróbmy grę tekstową, która prosi gracza o odgadnięcie prawidłowej liczby. Pierwszą rzeczą, którą musimy zrobić, to wygenerować losową liczbę na początku gry, aby gracz nie zawsze odgadł tę samą liczbę. Ponieważ liczba pozostanie taka sama w całym programie, będziesz chciał przechowywać liczbę losową w zmiennej.
- Python nie ma wbudowanej funkcji liczb losowych, ale ma standardową bibliotekę (oznacza to, że użytkownik nie będzie musiał instalować niczego dodatkowego), która to robi. Przejdź więc na początek kodu (przed funkcjami print()) i wpisz wiersz import random.
-
Użyj funkcji losowej. Nazywa się randint(), znajduje się w losowej bibliotece, którą właśnie zaimportowałeś, i jako argument przyjmuje minimalną i maksymalną wartość, jaką może mieć liczba. Wróć więc na koniec kodu i wpisz następującą linię:
rightNum = random.randint(0, 1000)
Krok 5. Uzyskaj dane wejściowe od gracza
W grze gracz chce coś zrobić lub wchodzić z czymś w interakcję. W grze tekstowej jest to możliwe poprzez wprowadzenie tekstu. Teraz, gdy mamy już losową liczbę, nasze następne wiersze kodu powinny poprosić gracza o wprowadzenie najlepszego przypuszczenia.
-
Ponieważ wprowadzony kod drukuje polecenie wprowadzenia liczby dla gracza, powinien również odczytać wprowadzoną przez niego liczbę. Odbywa się to za pomocą input() w Pythonie 3 i raw_input() w Pythonie 2. Powinieneś pisać w Pythonie 3, ponieważ Python 2 wkrótce stanie się przestarzały. Dodaj następujący wiersz do swojego kodu, aby zapisać dane gracza w zmiennej o nazwie number:
userNum = input()
Krok 6. Zmień dane wejściowe gracza w użyteczny typ danych
Gracz wpisał numer – co teraz?
-
Wprowadź numer gracza. Może to zabrzmieć mylące, ponieważ właśnie wprowadzili liczbę. Ale jest dobry powód: Python zakłada, że wszystkie dane wejściowe to tekst lub „łańcuch”, jak to się nazywa w programowaniu. Ten tekst zawiera numer, który chcesz uzyskać. Python ma funkcję, która konwertuje ciąg, który zawiera tylko liczbę, na liczbę w środku. Rodzaj:
numer_użytkownika = int(numer_użytkownika)
Krok 7. Porównaj numer gracza z poprawną liczbą
Gdy gracz wprowadzi swój numer, musisz porównać go z tym, który został wygenerowany losowo. Jeśli liczby nie są takie same, gra może sprawić, że gracz spróbuje innej liczby. Jeśli liczby się zgadzają, możesz powiedzieć graczowi, że odgadł poprawnie, i wyjść z programu. Odbywa się to za pomocą następującego kodu:
while userNum != rightNum: userNum = int(input())
Krok 8. Przekaż opinię gracza
Chociaż już przetworzyłeś ich dane wejściowe, gracz tego nie zobaczy. Musisz faktycznie wydrukować wyniki graczowi, aby zrozumiał, co się dzieje.
- Z pewnością możesz po prostu powiedzieć graczowi, czy jego numer jest prawidłowy, czy zły. Ale przy takim podejściu gracz może w najgorszym przypadku zgadywać 1000 razy, co byłoby bardzo nudne.
- Powiedz więc graczowi, czy jego liczba jest za mała lub za duża. To znacznie zmniejszy ich liczbę domysłów. Jeśli, na przykład, gracz najpierw odgadnie 500, a gra odpowie „Za duży. Spróbuj ponownie”, będzie tylko 500 możliwych liczb zamiast 1000. Odbywa się to za pomocą konstrukcji if, więc zastąp print ("Błędnie. Spróbuj ponownie.") za pomocą jednego.
- Należy pamiętać, że sprawdzanie, czy dwie liczby są takie same, odbywa się za pomocą ==, a nie za pomocą =. = przypisuje wartość po prawej stronie zmiennej na lewo od niego!
if userNum < rightNum: print("Za mały. Spróbuj ponownie:") if userNum > rightNum: print("Za duży. Spróbuj ponownie:")
Krok 9. Przetestuj swój kod
Jako programista powinieneś mieć pewność, że Twój kod działa, zanim uznasz, że jest skończony.
-
Podczas programowania w Pythonie upewnij się, że wcięcia są prawidłowe. Twój kod powinien wyglądać tak:
import random print("Witamy w grze w zgadywanie liczb!") print("Wprowadź liczbę całkowitą od 1 do 1000:") rightNum = random.randint(0, 1000) userNum = input() userNum = int(userNum) while userNum != rightNum: if userNum < rightNum: print("Za mały. Spróbuj ponownie:") if userNum > rightNum: print("Zbyt duży. Spróbuj ponownie:") userNum = int(input()) print("Zgadłeś prawidłowo.")
Krok 10. Sprawdź poprawność danych wejściowych
Gracz nie powinien być w stanie zepsuć twojej gry, po prostu wprowadzając niewłaściwą rzecz. „Weryfikacja danych wejściowych” oznacza upewnienie się, że gracz wprowadził poprawną rzecz przed jej przetworzeniem.
- Otwórz grę ponownie i spróbuj wpisać wszystko, co nie jest liczbą. Gra zakończy się z ValueError. Aby tego uniknąć, możesz zaimplementować sposób sprawdzania, czy dane wejściowe były liczbą.
- Zdefiniuj funkcję. Ponieważ sprawdzanie poprawności danych wejściowych jest dość długie i trzeba to robić wiele razy, należy zdefiniować funkcję. Nie przyjmie żadnych argumentów i zwróci liczbę. Najpierw napisz def numInput(): na górze kodu, bezpośrednio pod importem random.
- Uzyskaj dane od gracza raz. Użyj funkcji input() i przypisz wynik do zmiennej inp.
- Jeśli wpis gracza nie jest liczbą, poproś go o wprowadzenie liczby. Aby sprawdzić, czy ciąg jest liczbą, użyj funkcji isdigit(), która dopuszcza tylko liczbę całkowitą, więc nie będziesz musiał tego sprawdzać osobno.
- Jeśli dane wejściowe to liczba, przekonwertuj ją z ciągu na liczbę i zwróć wynik. Użyj funkcji int() do konwersji ciągu na liczbę całkowitą. Spowoduje to, że konwersja w kodzie głównym będzie niepotrzebna i należy ją stamtąd usunąć.
- Zastąp wszystkie wywołania input() w kodzie głównym wywołaniami numInput().
- Kod funkcji numInput() będzie wyglądał tak:
def numInput(): inp = input() while inp.isdigit(): print("Powiedziano Ci wprowadzić liczbę całkowitą! Wprowadź liczbę całkowitą:") inp = input() return int(inp)
Krok 11. Ponownie przetestuj grę
Celowo wprowadzaj niewłaściwe rzeczy, aby zobaczyć, co się stanie, a następnie naprawiaj wszelkie błędy, gdy się pojawią.
Spróbuj wpisać tekst, gdy program poprosi o numer. Teraz, zamiast wychodzić z komunikatem o błędzie, program ponownie poprosi o podanie numeru
Krok 12. Zasugeruj ponowne uruchomienie gry po jej zakończeniu
W ten sposób gracz może dłużej grać w twoją grę bez konieczności ciągłego jej restartowania.
- Umieść cały kod z wyjątkiem importu i definicji funkcji w pętli while. Jako warunek ustaw True: to będzie zawsze prawdziwe, więc pętla będzie trwać w nieskończoność.
- Zapytaj gracza, czy chce zagrać ponownie po prawidłowym odgadnięciu liczby. Użyj funkcji print().
- Jeśli odpowiedzą „Nie”, wyrwij się z tego spojrzenia. Jeśli odpowiedzą na coś innego, kontynuuj. Wyrwanie się z pętli odbywa się za pomocą instrukcji break.
- Przenieś „Witamy w grze w zgadywanie liczb” poza pętlę while. Gracz prawdopodobnie nie chce być mile widziany za każdym razem, gdy gra. Przesuń instrukcję print("Witamy w grze w zgadywanie liczb!" nad while True:, aby była wydrukowana tylko raz, gdy użytkownik rozpocznie pierwszą grę.
Krok 13. Przetestuj grę
Będziesz musiał przetestować swoją grę za każdym razem, gdy zaimplementujesz nową funkcję.
-
Pamiętaj, aby przynajmniej raz odpowiedzieć zarówno „Tak” i „Nie”, aby upewnić się, że obie opcje działają. Oto jak powinien wyglądać Twój kod:
import random def numInput(): inp = input() while not inp.isdigit(): print("Powiedziano Ci wprowadzić liczbę całkowitą! Wprowadź liczbę całkowitą:") inp = input() return int(inp) print ("Witamy w grze w zgadywanie liczb!") while True: print("Wprowadź liczbę całkowitą od 1 do 1000:") rightNum = random.randint(0, 1000) userNum = numInput() while userNum != rightNum: if userNum < rightNum: print("Za mały. Spróbuj ponownie:") if userNum > rightNum: print("Za duży. Spróbuj ponownie:") userNum = numInput() print("Zgadłeś poprawnie.") print("Czy ty chcesz zagrać ponownie? Wpisz Nie, aby zakończyć.") if input() == "Nie": przerwa
Krok 14. Napisz inne gry tekstowe
Co powiesz na napisanie kolejnej przygody tekstowej? Lub quiz? Bądź kreatywny.
Wskazówka: Czasami warto zajrzeć do dokumentacji, jeśli nie masz pewności, jak coś jest zrobione lub jak używana jest funkcja. Dokumentację Pythona 3 można znaleźć pod adresem https://docs.python.org/3/. Czasami wyszukiwanie tego, co chcesz robić w Internecie, również przynosi dobre wyniki.
Część 2 z 3: Tworzenie gry z grafiką 2D
Krok 1. Wybierz bibliotekę graficzną
Tworzenie grafiki jest bardzo skomplikowane, a większość języków programowania (m.in. Python, C++, C, JavaScript) zapewnia jedynie minimalne lub nawet żadne wsparcie dla grafiki w rdzeniu lub standardowych bibliotekach. Więc będziesz musiał użyć zewnętrznej biblioteki, aby móc tworzyć grafikę, na przykład Pygame dla Pythona.
Nawet mając bibliotekę grafik, będziesz musiał się martwić o takie rzeczy, jak wyświetlanie menu, sprawdzanie, co kliknął gracz, jak wyświetlać kafelki i tak dalej. Jeśli wolisz skupić się na tworzeniu rzeczywistej gry, możesz użyć biblioteki silnika gry, takiej jak Unity, która z łatwością implementuje te rzeczy
W tym artykule użyjemy Pythona z Cocos2D, aby pokazać, jak stworzyć prostą platformówkę 2D. Niektóre z wymienionych koncepcji mogą nie istnieć w innych silnikach gier. Więcej informacji można znaleźć w ich dokumentacji.
Krok 2. Zainstaluj wybraną bibliotekę graficzną
Cocos2D dla Pythona jest łatwy w instalacji. Możesz go pobrać z https://python.cocos2d.org/index.html lub uruchamiając sudo pip3 install cocos2d, jeśli używasz Linuksa.
Krok 3. Utwórz nowy katalog dla swojej gry i multimediów
W swojej grze będziesz używać takich rzeczy, jak obrazy i dźwięki. Trzymaj te rzeczy w tym samym katalogu co program. Ten katalog nie powinien zawierać niczego więcej, abyś mógł łatwo zobaczyć, jakie zasoby posiadasz w grze.
Krok 4. Utwórz nowy plik kodu w nowym katalogu
Nazwij to main, z rozszerzeniem pliku dla twojego języka programowania. Jeśli piszesz duży i złożony program, w którym sensowne jest posiadanie wielu plików programu, pokaże ci, który jest głównym plikiem.
W tym przykładzie stworzymy plik o nazwie main.py, który będzie zawierał cały nasz kod
Krok 5. Utwórz okno gry
Jest to podstawowy warunek gry z grafiką.
- Zaimportuj niezbędne moduły podrzędne cocos2d: cocos.director, cocos.scene i cocos.layer. Odbywa się to za pomocą polecenia subModuleName import *, gdzie nazwa submodułu to submoduł, który chcesz zaimportować. Różnica między from … import * i import … polega na tym, że nie musisz umieszczać nazwy modułu przed wszystkim, czego używasz z tego modułu z poprzednim.
- Zdefiniuj podklasę MainMenuBgr ColorLayer. Zasadniczo oznacza to, że każde utworzone tło menu głównego będzie zachowywać się jak warstwa kolorów z pewnymi wprowadzonymi zmianami.
- Zacznij od dyrektora Cocos. To da ci nowe okno. Jeśli nie ustawisz podpisu, okno będzie miało ten sam podpis co nazwa pliku (main.py), co nie będzie wyglądało profesjonalnie. Zezwól na zmianę rozmiaru okna, ustawiając resizable na True.
- Zdefiniuj funkcję showMainMenu. Powinieneś umieścić kod pokazujący menu główne w funkcji, ponieważ pozwoli to na łatwy powrót do menu głównego poprzez ponowne wywołanie funkcji.
- Utwórz scenę. Scena składa się na razie z jednej warstwy, która jest obiektem zdefiniowanej przez Ciebie klasy MainMenuBgr.
- Uruchom tę scenę w oknie.
z cocos.director import * z cocos.scene import * z cocos.layer import * class MainMenuBgr(ColorLayer): def _init_(self): super(MainMenu, self)._init_(0, 200, 255, 255) def showMainMenu(): menuSc = Scene(MainMenuBgr()) director.run(menuSc) director.init(caption="IcyPlat - prosta platformówka", resizable=True) showMainMenu()
Krok 6. Dodaj menu główne do okna
Oprócz samej gry, oprócz innych elementów, które możesz dodać później, musisz dodać menu, za pomocą którego gracz może zamknąć okno.
- Importuj cocos.menu (znowu z instrukcją from) i pyglet.app (tym razem z importem).
- Zdefiniuj MainMenu jako podklasę Menu.
- Ustaw wyrównanie menu głównego. Musisz osobno ustawić wyrównanie w pionie i poziomie.
- Utwórz listę pozycji menu i dodaj je do menu. Powinieneś mieć przynajmniej pozycje menu "Rozpocznij grę" i "Zakończ". Każda pozycja menu powinna być umieszczona w nawiasach. Każdy element musi mieć etykietę i funkcję zwrotną, która określa, co się stanie, gdy gracz go kliknie. W przypadku elementu „Rozpocznij grę” użyj funkcji startGame (zaraz to napiszesz), w przypadku elementu „Wyjdź” użyj „pyglet.app.exit” (już istnieje). Utwórz aktualne menu, wywołując self.create_menu(menuItems).
- Zdefiniuj startGame(). Po prostu wstawiaj pass do definicji na razie, zastąpisz to kiedy piszesz rzeczywistą grę.
- Przejdź do miejsca w kodzie, w którym utworzyłeś scenę menuSc i dodaj do niej obiekt MainMenu.
-
Twój cały kod powinien teraz wyglądać następująco:
z cocos.director import * z cocos.menu import * z cocos.scene import * z cocos.layer import * import pyglet.app class MainMenuBgr(ColorLayer): def _init_(self): super(MainMenuBgr, self)._init_(0, 200, 255, 255) class MainMenu(Menu): def _init_(self): super(MainMenu, self)._init_("") self.menu_valign = CENTRUM self.menu_halign = CENTRUM menuItems = [(MenuItem("Rozpocznij grę) ", startGame)), (MenuItem("Zakończ", pyglet.app.exit))] self.create_menu(menuItems) def startGame(): pass def showMainMenu(): menuSc = Scene(MainMenuBgr()) menuSc.add(MainMenu()) director.run(menuSc) director.init(caption="IcyPlat - prosta platformówka", resizable=True) showMainMenu()
Krok 7. Przetestuj swój kod
Przetestuj kod wcześnie, póki jest krótki i stosunkowo prosty. Następnie możesz zidentyfikować i poprawić wszelkie błędy w podstawowej strukturze, zanim sprawy staną się zbyt skomplikowane.
Kod z instrukcji powinien otworzyć okno z napisem „IcyPlat – prosta platformówka”. Tło jest jasnoniebieskie i możesz zmienić rozmiar okna. Kiedy klikniesz „Rozpocznij grę” w menu, nic nie powinno się (jeszcze) wydarzyć. Po kliknięciu przycisku „Zamknij” okno zostanie zamknięte
Krok 8. Utwórz duszka
Sprite to „obiekt gry” lub dwuwymiarowy obraz. Sprite'y mogą być obiektami w grze, ikonami, dekoracjami tła, postaciami i wszystkim, co możesz przedstawić za pomocą obrazu w grze. Zaczniemy od stworzenia duszka dla postaci, z którą gracz może wchodzić w interakcje.
- Zaimportuj podmoduł cocos.sprite za pomocą wyrażenia from-import-expression.
- Znajdź obraz reprezentujący duszka. Nie możesz wyświetlić duszka, jeśli nie masz do niego obrazu. Możesz go narysować lub zdobyć w Internecie (uważaj jednak na licencje, jeśli planujesz opublikować swoją grę). W tym przykładzie przejdź do https://opengameart.org/content/tux-classic-hero-style i zapisz obraz-p.webp" />
- Utwórz warstwę jako nowy obiekt klasy ScrollableLayer. Następnie utwórz duszka jako obiekt Sprite i ustaw jego pozycję na (8, 250). Dla odniesienia punkt (0, 0) znajduje się w lewym dolnym rogu. Jest to dość wysokie, ale zapewni, że pingwin nie utknie w lodzie.
- Dodaj duszka do warstwy duszka.
- Utwórz nową scenę z warstwy duszka i uruchom ją.
def startGame(): figLayer = ScrollableLayer() fig = Sprite('pingu.png') fig.position = (75, 100) figLayer.add(fig) # gameSc = Scene(figLayer) director.run(gameSc)
Krok 9. Wymyśl swój krajobraz
W większości gier twoje duszki nie powinny po prostu unosić się w próżni. Powinny właściwie stać na jakiejś powierzchni, z czymś wokół siebie. W grach 2D często robi się to za pomocą zestawu kafelków i mapy kafelkowej. Zestaw płytek zasadniczo mówi, jakie rodzaje powierzchni i kwadraty tła istnieją i jak wyglądają.
- Utwórz zestaw płytek. Zestaw płytek do tej gry będzie bardzo prosty: jedna płytka lodu i jedna płytka nieba. Płytka lodowa użyta w tym przykładzie pochodzi stąd, pod CC-BY-SA 3.0.
- Utwórz obraz zestawu kafelków. To obraz wszystkich płytek, które muszą mieć ten sam rozmiar (edytuj je, jeśli nie są) i mieć rozmiar, który chcesz zobaczyć w grze, obok siebie. Zapisz swoje zdjęcie jako icyTiles.png.
-
Utwórz opis zestawu kafelków. To jest plik XML. Plik XML zawiera informacje o tym, jak duże są kafelki na obrazie zestawu kafelków, którego obrazu użyć i gdzie znaleźć kafelek. Utwórz plik XML o nazwie icyTiles.xml z poniższym kodem:
Krok 10. Stwórz mapę kafelkową dla swojego krajobrazu
Mapa kafelków to mapa, która określa, który kafelek znajduje się w którym miejscu na twoim poziomie. W tym przykładzie należy zdefiniować funkcję do generowania map kafelkowych, ponieważ ręczne projektowanie map kafelkowych jest bardzo żmudne. Bardziej zaawansowana gra zwykle miałaby jakiś edytor poziomów, ale aby zapoznać się z tworzeniem gier 2D, algorytm może zapewnić wystarczająco dobre poziomy.
- Dowiedz się, ile wierszy i kolumn jest potrzebnych. W tym celu podziel rozmiar ekranu przez rozmiar kafelków zarówno w poziomie (kolumny), jak iw pionie (wiersze). Zaokrąglij liczbę w górę; potrzebujesz do tego funkcji modułu math, więc dodaj z importu math do importów na górze kodu.
- Otwórz plik do pisania. Spowoduje to usunięcie całej poprzedniej zawartości pliku, więc wybierz nazwę, której nie ma jeszcze żaden plik w katalogu, np. levelMap.xml.
- Zapisz otwierające tagi do pliku.
- Wygeneruj mapę kafelkową zgodnie z algorytmem. Korzystasz z kodu z poniższego kodu lub możesz go wymyślić samodzielnie. Pamiętaj, aby zaimportować funkcję randint z modułu random: jest to wymagane, aby poniższy kod działał, a cokolwiek wymyślisz, prawdopodobnie będzie również wymagało losowych liczb całkowitych. Upewnij się również, że kafelki nieba i kafelki lodu są ułożone w różnych warstwach: lód jest twardy, a niebo nie.
- Zapisz tagi zamykające do pliku i zamknij plik.
def generateTilemap(): colAmount = ceil(800/16)*3 # (szerokość ekranu / rozmiar kafelka) * 3 rowAmount = ceil(600/16) # wysokość ekranu / rozmiar kafelka tileFile = open("levelMap.xml", " w") tileFile.write('\n\n\n') iceHeight = randint(1, 10) for i in range(0, colAmount): tileFile.write('') makeHole = False if randint(0, 50) == 10 i i != 0: # nie zezwalaj na dziury w punkcie odradzania makeHole = True for j in range(0, rowAmount): if makeHole: tileFile.write('\n') else: if j <= iceHeight: tileFile.write('\n') else: tileFile.write('\n') iceHeight = randint(iceHeight-5, iceHeight+5) if iceHeight < 0: # ograniczaj płytki przed zbyt niskimi iceHeight = randint(1, 5) if iceHeight > rowAmount: # ogranicz liczbę płytek przed zbyt wysokimi iceHeight = randint(int(rowAmount/2)-5, int(rowAmount/2)+5) tileFile.write('\n') tileFile.write ('\n\n') for i in range(0, colAmount): tileFile.write('') for j in range(0, rowAmount): tileFile.write('\n') tileFile.write('\ n') tileFile.write('\n\n') tileFile.close()
Krok 11. Wyświetl mapę kafelkową
Zaimportuj wszystko z cocos.tiles, a następnie przejdź do funkcji startGame w tym celu.
- Na początku funkcji startGame wygeneruj mapę kafelków, korzystając ze zdefiniowanej w tym celu funkcji.
- Utwórz nowego menedżera przewijania. Zrób to bezpośrednio pod linią, w której dodajesz duszka do jego warstwy.
- Utwórz nową warstwę zawierającą kafelki, które zostaną załadowane z mapy kafelków levelMap.xml wygenerowanej przez wygenerowaną przez Ciebie funkcję generateTilemap.
- Dodaj warstwę niestałą, warstwę stałą i warstwę sprite do menedżera przewijania, dokładnie w tej kolejności. Jeśli chcesz, możesz dodać pozycję Z.
- Zamiast tworzyć scenę z warstwy sprite, utwórz ją z menedżera przewijania.
-
Twoja funkcja startGame powinna teraz wyglądać tak:
def startGame(): generateTilemap() # fig = Sprite('pingu.png') fig.position = (8, 500) figLayer = ScrollableLayer() figLayer.add(fig) # tileLayer = load('levelMap.xml') solidTiles = tileLayer['solid'] nsoliTiles = tileLayer['not_solid'] # scrMang = ScrollingManager() scrMang.add(nsoliTiles, z=-1) scrMang.add(solidTiles, z=0) scrMang.add(figLayer, z =1) # gameSc = Scena(scrMang) director.run(gameSc)
Krok 12. Przetestuj swój kod
Powinieneś często testować swój kod, aby upewnić się, że nowe funkcje, które zaimplementowałeś, naprawdę działają.
Kod w przykładzie powinien teraz pokazywać lodowaty krajobraz za pingwinem. Jeśli pingwin wygląda, jakby unosił się daleko nad lodem, nie zrobiłeś nic złego i zostanie to naprawione w następnym kroku
Krok 13. Dodaj kontrolki
Gracz ma znacznie więcej sposobów na interakcję z programem w grze 2D niż w grze tekstowej. Typowy polega na przesuwaniu postaci po naciśnięciu odpowiedniego klawisza.
- Importuj wszystko z cocos.mapcolliders i cocos.actions. Zaimportuj również klucz z pyglet.window.
-
„Zadeklaruj” niektóre zmienne globalne. Zmienne globalne są współdzielone przez funkcje. Nie możesz tak naprawdę deklarować zmiennych w Pythonie, ale musisz powiedzieć, że zmienna globalna istnieje w głównym kodzie przed jej użyciem. Możesz przypisać 0 jako wartość, ponieważ funkcja zajmie się później przypisaniem prawidłowej wartości. Dodaj więc pod wyrażeniami importu:
# "deklarowanie" zmiennych globalnych klawiatura = 0 scrMang = 0
-
Dostosuj swoją funkcję startGame:
- Powiedzmy, że używasz klawiatury zmiennych globalnych i scrMang. Zrób to, pisząc globalną klawiaturę scrMang na górze funkcji.
- Spraw, aby okno nasłuchiwało zdarzeń klawiatury.
- Powiedz figurce, aby działała na podstawie kontrolera PlatformerController. Wkrótce zaimplementujesz ten PlatformerController.
- Utwórz zderzacz map do obsługi kolizji między pełnymi płytkami a figurą.
def startGame(): globalna klawiatura, scrMang generateTilemap() # fig = Sprite('pingu.png') fig.position = (8, 250) figLayer = ScrollableLayer() figLayer.add(fig) # tileLayer = load('levelMap.xml') solidTiles = tileLayer['solid'] nsoliTiles = tileLayer['not_solid'] # keyboard = key. KeyStateHandler() director.window.push_handlers(keyboard) # fig.do(PlatformerController()) mapcollider = RectMapCollider(velocity_on_bump) ='slide') fig.collision_handler = make_collision_handler(mapcollider, solidTiles) # scrMang = ScrollingManager() scrMang.add(nsoliTiles, z=-1) scrMang.add(solidTiles, z=0) scrMang.add(figLayer, z= 1) # gameSc = Scene(scrMang) director.run(gameSc)
-
Utwórz kontroler platformówki. To właśnie przesunie figurę zgodnie z twoimi naciśnięciami klawiszy.
- Zdefiniuj kontroler platformówki jako podklasę Action.
- Określ prędkość ruchu, prędkość skoku i grawitację.
- Zdefiniuj funkcję startową. Ta funkcja jest wywoływana raz, gdy kontroler platformówki jest podłączony do figury. Powinien ustawić swoją prędkość na 0 zarówno w kierunku x, jak i y.
- Zdefiniuj funkcję kroku. Będzie powtarzany podczas działania sceny.
- Powiedz funkcji step, aby używała klawiatury zmiennych globalnych i scrMang.
- Pobierz i zmień prędkość. Zapisz prędkość x i y w oddzielnych zmiennych. Ustaw prędkość x na 1 lub -1 (w zależności od tego, czy naciśnięto lewy czy prawy klawisz) pomnożoną przez prędkość ruchu. Dodaj grawitację do prędkości y. Pomnóż to przez czas przestoju, aby działał tak samo na wolniejszych urządzeniach. Jeśli naciśniesz klawisz spacji, a postać stoi na ziemi, skocz zmieniając prędkość y na prędkość skoku.
- Oblicz, dokąd postać powinna się przenieść. Następnie pozwól obsłudze kolizji dostosować tę pozycję, jeśli znajduje się ona wewnątrz litej płytki. Na koniec przenieś figurę do nowej dopasowanej pozycji.
- Ustaw fokus menedżera przewijania na figurze. Powoduje to, że kamera porusza się w rozsądny sposób, gdy postać się porusza.
class PlatformerController(Action): globalna klawiatura, scrMang on_ground = True MOVE_SPEED = 300 JUMP_SPEED = 500 GRAVITY = -1200 def start(self): self.target.velocity = (0, 0) def step(self, dt): globalna klawiatura, scroller jeśli dt > 0.1: # nie rób nic podczas przestoju do dużego powrotu vx, vy = self.target.velocity vx = (keyboard[key. RIGHT] - keyboard[key. LEFT]) * self. MOVE_SPEED vy + = self. GRAVITY * dt jeśli self.on_ground i keyboard[key. SPACE]: vy = self. JUMP_SPEED dx = vx * dt dy = vy * dt last = self.target.get_rect() new = last.copy() new.x += dx nowy.y += dy self.target.velocity = self.target.collision_handler(ostatni, nowy, vx, vy) self.on_ground = (nowy.y == ostatni.y) self.target.position = nowy.centrum scrMang.set_focus(*nowy.centrum)
Krok 14. Przetestuj swój kod
Jeśli podążyłeś za przykładem, powinieneś być w stanie poruszać pingwinem za pomocą klawiszy strzałek i skakać, naciskając spację. Ponadto pingwin powinien teraz spaść, zamiast unosić się nad ziemią.
Krok 15. Stwórz zakończenie gry
Nawet gry, które mogą trwać w nieskończoność, powinny mieć możliwość przegranej. Ponieważ poziom, który stworzyłeś w przykładzie z funkcją, ma swój koniec, musisz także umożliwić wygraną, dochodząc do tego końca. W przeciwnym razie gracz skakałby tam tylko po blokach lodu, co znudziłoby się.
-
Wewnątrz kontrolera platformówki, po ustawieniu ostrości, uzyskaj pozycję x i y postaci. Jeśli pozycja y jest mniejsza niż 0, wywołaj funkcję finishGame() (zapiszesz ją później) z argumentem "Game Over". Jeśli pozycja x jest większa niż rozmiar ekranu pomnożony przez 3 (ustawiłeś to wcześniej jako rozmiar poziomu).
posX, posY = self.target.position if posY < 0: finishGame("Game Over") return jeśli posX > 800*3: # level size finishGame("Level Completed") return
-
Zdefiniuj klasę finishMenu. Powinna być podobna do klasy menu głównego, którą zdefiniowałeś wcześniej, ale zamiast pustego ciągu w tytule, powinna używać zmiennej tekstowej, którą funkcja _init_ przyjmuje jako argument. Pozycje menu powinny być teraz oznaczone etykietami „Spróbuj ponownie” i „Zakończ”, ale wywołane przez nie funkcje pozostaną takie same.
class FinishMenu(Menu): def _init_(self, text): super(FinishMenu, self)._init_(text) self.menu_valign = CENTRUM self.menu_halign = CENTRUM menuItems = [(MenuItem("Spróbuj ponownie", startGame)), (MenuItem("Zakończ", pyglet.app.exit))] self.create_menu(menuItems)
-
Zdefiniuj funkcję finishGame(). Powinien przyjąć tekst jako argument. Powinien utworzyć scenę z tła menu głównego, FinishMenu z argumentem tekstowym przekazywanym do tego menu. Wtedy powinien uruchomić tę scenę.
def finishGame(tekst): menuSc = Scene(MainMenuBgr()) menuSc.add(FinishMenu(text)) director.run(menuSc)
Krok 16. Dodaj kredyty
W tym miejscu otrzymasz uznanie za swój niesamowity kod, a także przyznasz kredyt każdemu, kto pomógł Ci po drodze. Jeśli użyłeś obrazu z innej witryny (za pozwoleniem), pamiętaj, aby przypisać ten obraz jego twórcy.
-
Utwórz plik CREDITS i wprowadź tam wszystkie swoje kredyty, w ten sposób:
Penguin: Kelvin Shadewing, pod CC0 Ice block: Michał Banas digit1024 na opengameart.org pod CC-BY-SA 3.0
- Wróć do kodu Pythona i zaimportuj Label z cocos.text.
-
Zdefiniuj podklasę Kredyty warstwy. W swojej funkcji _init_ odczytaj plik CREDITS i utwórz etykietę tekstową we właściwej pozycji z każdego wiersza w nim.
class Kredyty(Warstwa): def _init_(self): super(Kredyty, self)._init_() credFile = open("KREDYTY", "r") creds = credFile.read() creds = creds.split("\n ") for i in range(0, len(creds)): credLabel = Label(creds, font_size=32, anchor_x="left", anchor_y="top") credLabel.position = 25, 500-(i +1)*40 samodzielne dodawanie (credLabel)
- Przejdź do klasy menu głównego i dodaj element menu o nazwie „Kredyty”, który po kliknięciu wywołuje funkcję showCredits.
-
Zdefiniuj podklasę BackToMainMenuButton z Menu. Zrób to menu z jednym elementem, oznaczonym "Wstecz", który wywołuje funkcję showMainMenu. To „menu”, które bardziej przypomina przycisk, powinno być wyrównane pionowo do dołu i poziomo do góry.
class BackToMainMenuButton(Menu): def _init_(self): super(BackToMainMenuButton, self)._init_("") self.menu_valign = DÓŁ self.menu_halign = LEWO menuItems = [(MenuItem("Wstecz", showMainMenu))] self. create_menu(menuItems)
-
Zdefiniuj funkcję showCredits. Powinien utworzyć scenę z warstwy MainMenuBgr i warstwy Kredytów i uruchomić tę scenę.
def showCredits(): credSc = Scene(MainMenuBgr()) credSc.add(Credits()) credSc.add(BackToMainMenuButton()) director.run(credSc)
Krok 17. Sprawdź swój kod
Kiedy myślisz, że skończyłeś swój kod, powinieneś przejrzeć go ponownie. Pomoże Ci to zauważyć, czy coś można zoptymalizować lub czy są jakieś niepotrzebne wiersze, o których zapomniałeś usunąć. Jeśli podążałeś za przykładem, cały kod powinien teraz wyglądać następująco:
z cocos.director import * z cocos.menu import * z cocos.scene import * z cocos.layer import * z cocos.sprite import * z cocos.tiles import * z cocos.mapcolliders import * z cocos.actions import * z cocos.text import Etykieta import pyglet.app z pyglet.window import klucza z matematyki import ceil z losowego importu randint # "deklarowanie" zmiennych globalnych keyboard = 0 scrMang = 0 class MainMenuBgr(ColorLayer): def _init_(self): super(MainMenuBgr, self)._init_(0, 200, 255, 255) class Menu Główne(Menu): def _init_(self): super(Menu Główne, self)._init_("") self.menu_valign = CENTRUM self.menu_halign = CENTRUM menuItems = [(MenuItem("Rozpocznij grę", startGame)), (MenuItem("Credits", showCredits)), (MenuItem("Quit", pyglet.app.exit))] self.create_menu(menuItems) class Kredyty(Warstwa): def _init_(self): super(Kredyty, self)._init_() credFile = open("KREDYTY", "r") creds = credFile.read() creds = creds.split("\n") for i in range (0, len(creds)): credLabel = Label(creds, font_size=32, anchor_x="left", anchor_y="top") credLabel.position = 25, 500-(i+1)*40 self.add(credLabel) class BackToMainMenuButton(Menu): def _init_(self): super (BackToMainMenuButton, self)._init_("") self.menu_valign = DÓŁ self.menu_halign = LEWO menuItems = [(MenuItem("Back", showMainMenu))] self.create_menu(menuItems) class FinishMenu(Menu): def _init_(self, tekst): super(FinishMenu, self)._init_(tekst) self.menu_valign = CENTRUM self.menu_halign = CENTRUM menuItems = [(MenuItem("Spróbuj ponownie", startGame)), (MenuItem("Zamknij", pyglet. app.exit))] self.create_menu(menuItems) class PlatformerController(Action): globalna klawiatura, scrMang on_ground = True MOVE_SPEED = 300 JUMP_SPEED = 500 GRAVITY = -1200 def start(self): self.target.velocity = (0, 0) def step(self, dt): globalna klawiatura, scroller jeśli dt > 0.1: # nie rób nic przy zbyt dużym przestoju return vx, vy = self.target.velocity vx = (keyboard[key. RIGHT] - klawiatura [key. LEFT]) * self. MOVE_SPEED vy += self. GRAVITY * dt jeśli self.on _ground i keyboard[key. SPACE]: vy = self. JUMP_SPEED dx = vx * dt dy = vy * dt last = self.target.get_rect() new = last.copy() new.x += dx new.y + = dy self.target.velocity = self.target.collision_handler(last, new, vx, vy) self.on_ground = (new.y == last.y) self.target.position = new.center scrMang.set_focus(* new.center) posX, posY = self.target.position if posY < 0: finishGame("Game Over") return if posX > 800*3: # level size finishGame("Level Completed") return def finishGame(text): menuSc = Scene(MainMenuBgr()) menuSc.add(FinishMenu(tekst)) director.run(menuSc) def showCredits(): credSc = Scene(MainMenuBgr()) credSc.add(Credits()) credSc.add(BackToMainMenuButton())) director.run(credSc) def generateTilemap(): colAmount = ceil(800/16)*3 # (szerokość ekranu / rozmiar kafelka) * 3 rowAmount = ceil(600/16) # wysokość ekranu / rozmiar kafelka tileFile = otwarte ("levelMap.xml", "w") tileFile.write('\n\n\n') iceHeight = randint(1, 10) for i in range(0, colAmount): tileFile.write('') makeHole = Fałsz, jeśli rand int(0, 50) == 10 oraz i != 0: # nie zezwalaj na dziury w punkcie odradzania makeHole = True for j in range(0, rowAmount): if makeHole: tileFile.write('\n') else: if j <= iceHeight: tileFile.write('\n') else: tileFile.write('\n') iceHeight = randint(iceHeight-5, iceHeight+5) if iceHeight < 0: # ogranicz ilość kafelków low iceHeight = randint(1, 5) if iceHeight > rowAmount: # ogranicz liczbę płytek przed zbyt wysokimi iceHeight = randint(int(rowAmount/2)-5, int(rowAmount/2)+5) tileFile.write('\n ') tileFile.write('\n\n') dla i in range(0, colAmount): tileFile.write('') dla j in range(0, rowAmount): tileFile.write('\n') tileFile.write('\n') tileFile.write('\n\n') tileFile.close() def startGame(): globalna klawiatura, scrMang generateTilemap() # fig = Sprite('pingu.png') fig.position = (8, 250) figLayer = ScrollableLayer() figLayer.add(fig) # tileLayer = load('levelMap.xml') solidTiles = tileLayer['solid'] nsoliTiles = tileLayer['not_solid'] # keyboard = key. KeyStateHandler () director.window.push_handlers(keybo ard) # fig.do(PlatformerController()) mapcollider = RectMapCollider(velocity_on_bump='slide') fig.collision_handler = make_collision_handler(mapcollider, solidTiles) # scrMang = ScrollingManager() scrMang.add(nsoliTiles, zang=-). add(solidTiles, z=0) scrMang.add(figLayer, z=1) # gameSc = Scene(scrMang) director.run(gameSc) def showMainMenu(): menuSc = Scene(MainMenuBgr()) menuSc.add(MainMenu())) director.run(menuSc) window = director.init(caption="IcyPlat - prosta platformówka", resizable=True) showMainMenu()
Krok 18. Zakończony
Teraz przetestuj grę. Kiedy coś programujesz, musisz sprawdzić, czy działa, gdy zaimplementujesz coś nowego. Możesz też przez jakiś czas pograć w napisaną przez siebie grę.
Część 3 z 3: Publikowanie gry
Krok 1. Zapisz zależności
Każdy, kto korzysta z innego komputera, nie będzie miał zainstalowanego tego samego oprogramowania i bibliotek, co Ty. Musisz więc upewnić się, że wszyscy, którzy instalują Twoją grę, dokładnie wiedzą, czego będą potrzebować do jej uruchomienia. Nie musisz zapisywać wszystkich zależności wszystkich zależności wszystkich zależności i tak dalej, ale powinieneś przynajmniej napisać zależności swoich pakietów i ich zależności.
Krok 2. Upewnij się, że masz uprawnienia do korzystania ze wszystkich mediów
Dotyczy to wszystkich grafik, w tym modeli 3D, muzyki, dialogów, muzyki, bibliotek i struktur, których użyłeś w swojej grze. Wszystko, czego sam nie napisałeś.
- Często istnieją pewne warunki, takie jak konieczność uznania autora lub udostępnienia modyfikacji mediów na tej samej licencji. Czasami będziesz mógł używać grafiki bez przypisywania twórców, o ile nie pobierasz opłat za grę. Jeśli musisz przyznać autorowi, zrób to w dobrze widocznym miejscu, takim jak zakładka „Kredyty” w twojej grze.
- Istnieją również nośniki z roszczeniami dotyczącymi praw autorskich i bez określonej licencji, czasami z tekstem typu „Wszelkie prawa zastrzeżone”. W takim przypadku musisz uzyskać wyraźną zgodę autora przed włączeniem go do gry.
- Biblioteki są zazwyczaj udostępniane na licencjach, które pozwalają na używanie ich jako bibliotek. Godnym uwagi wyjątkiem jest GPL bez wyjątku linkowania: taka licencja pozwala na używanie jej tylko w programie z określonymi licencjami. I zawsze powinieneś przeczytać przynajmniej podstawowe punkty licencji, aby upewnić się, że wszystko, co robisz z mediami lub biblioteką, jest dozwolone.
Ostrzeżenie: Korzystanie z mediów lub bibliotek w grze, którą publikujesz w sposób, na który nie zezwala licencja, może wpędzić Cię w poważne problemy prawne. Zapytaj więc autora lub całkowicie unikaj tego fragmentu multimediów, jeśli nie masz pewności, czy twoje użycie jest dozwolone.
Krok 3. Zdecyduj, na jakich warunkach chcesz opublikować swoją grę
Sprzedasz swoją grę? Czy chcesz, aby inni mogli korzystać z Twoich obrazów i pomysłów? Chociaż musisz uważać na media, których używasz w swoim projekcie, zwykle możesz zdecydować, w jaki sposób chcesz umożliwić innym korzystanie z Twojej gry. Możesz użyć licencji Creative Commons CC0, aby udostępnić swoją grę w domenie publicznej. Aby zezwolić na dystrybucję i modyfikację pod pewnymi warunkami przy zachowaniu pewnych praw, wypróbuj licencję Gnu General Public License (GPL) lub Berkeley Software Distribution (BSD). Możesz też uczynić swoje oprogramowanie zastrzeżonym, co oznacza, że nikomu nie wolno go rozpowszechniać ani modyfikować bez Twojej zgody.
Chociaż można zarabiać na sprzedaży gier, jest mało prawdopodobne, że ludzie kupią Twoją pierwszą grę, która zwykle ma niewiele funkcji i nie ma nic specjalnego. Ponadto, jeśli darmowy program nie działa, osoby, które go pobrały, będą po prostu rozczarowane. Jeśli jednak za to zapłacili, zażądają zwrotu pieniędzy, powodując więcej problemów zarówno dla Ciebie, jak i dla użytkowników. Zastanów się więc nad udostępnieniem kilku pierwszych programów za darmo
Krok 4. Zdecyduj, jak chcesz opublikować swoją grę
Każda metoda ma swoje zalety i wady, więc musisz sam zdecydować.
-
Opublikowanie go na stronie internetowej:
Jeśli masz witrynę internetową, możesz przesłać swoją grę, aby była dostępna do pobrania. Upewnij się, że podałeś jasne instrukcje dotyczące instalacji oprogramowania, a także wszystkie wymagane zależności. Wadą tego jest to, że gracze będą musieli ręcznie instalować zależności, co może być trudne dla niektórych osób.
-
Tworzenie pakietu dla menedżera pakietów:
Istnieją różne menedżery pakietów, takie jak apt, Yum i Homebrew, które ułatwiają ludziom instalowanie aplikacji w środowiskach Linux i Linux. Wszystkie mają różne formaty pakietów. Dobrą rzeczą w pakietach jest to, że automatycznie instalują wszystkie zależności (jeśli skonfigurujesz je poprawnie). Więc gracz musi tylko zainstalować twój pakiet i może grać w grę. Problem polega na tym, że istnieje wiele różnych menedżerów pakietów na różnych platformach, więc będziesz musiał włożyć trochę pracy w dostarczenie pakietów dla wszystkich najpopularniejszych.
Krok 5. Skieruj uwagę na swój program
Rozważ przesłanie swojego programu do głównego repozytorium pakietów, takiego jak te, które utrzymują Ubuntu i Debian, aby umożliwić łatwą instalację. Publikuj także posty na odpowiednich forach, takich jak dział projektów GameDev lub część tigSource. Ale nie bądź rozczarowany, jeśli Twoje pierwsze gry nie staną się sławne. Jeśli masz pomysł, który podoba się wielu osobom, Twoja gra może stać się dobrze znana.
Porady
- Bądź cierpliwy i chętny do nauki. Programowanie może być czasami frustrujące!
- Jeśli zastanawiasz się, jak coś jest zrobione w innej grze, a gra jest open-source, możesz spojrzeć na jej kod źródłowy.
- Szukając mediów, spróbuj znaleźć treści, które są w domenie publicznej. Wyszukaj obrazy i muzykę „Creative Commons” lub „Domena publiczna” i korzystaj z witryn takich jak https://opengameart.org lub
- Nie kopiuj większych fragmentów kodu bez sprawdzenia licencji. Często jest to zabronione, a jeśli nie, zwykle wymaga przypisania.
- Nie wysyłaj spamu ani nie umieszczaj postów w nieodpowiednich miejscach podczas promowania swojej gry. Może to spowodować zablokowanie Cię na stronie, jest po prostu denerwujące i zaszkodzi Twojej reputacji.