Strona główna

piątek, 19 sierpnia 2011

Jeszcze jeden klon "Arukanoido", czyli robimy grę komputerową

Na forach poświęconych programowaniu i/lub grom komputerowym często-gęsto pojawiają się wątki typu "chcę zrobić grę w stylu GTA, tylko lepszą", albo "szukam teamu do zrobienia gry MMORPG". Zwykle autorami takich wpisów są ludzie, którzy nie mają zielonego pojęcia, jak niezwykle złożonym przedsięwzięciem jest produkcja dużej gry komputerowej - zarówno od strony czysto developerskiej (dziesiątki, setki tysięcy linii kodu), poprzez zorganizowanie niezbędnych zasobów (np. modeli, tekstur, dźwięków), na zbalansowaniu mechaniki (testy, testy, testy) kończąc (albo i nawet nie kończąc, bo tak naprawdę zasygnalizowałem tylko najbardziej podstawowe sprawy). W sumie ja też nie mam tego pojęcia nazbyt dużego, ale jednak.

Tymczasem tak się składa, że w ramach poznawania Pythona mam zamiar napisać... klon Arkanoida. Stopniem złożoności ten projekt ustępuje o kilka rzędów wielkości wspomnianym produkcjom typu AAA, a mimo to nadal trzeba wiele rzeczy przemyśleć, podjąć niejedną decyzję, zadbać o odpowiednie zasoby, etc. Nawiasem mówiąc podejrzewam, że większość entuzjastów gier-w-stylu-X-tylko-lepszych odbiłoby się nawet od tak małego projektu, jak od ściany. A żeby pomóc sobie samemu ogarnąć temat, postanowiłem przed rozpoczęciem właściwej pracy "głośno pomyśleć" i wespół w zespół razem z Wami zastanowić się nad kształtem gry.

Grafika

Nie ma co się oszukiwać, jesteśmy wzrokowcami. Słowo "widzisz" bywa często używane jako synonim "rozumiesz", nawet jeśli akurat nie ma czego oglądać. Z tego powodu kwestie związane z grafiką budzą zwykle duże emocje. Niestety tak się składa, że absolutnie nie mam zmysłu artystycznego, więc podchodzę do tematu od strony czysto utylitarnej. Zatem jedno jest pewne: podobnie, jak  oryginał, gra nie będzie emulowała środowiska trójwymiarowego (skąd wziąć modele? jak je obsługiwać?), pozostaniemy przy 2D.
I dalej, chciałbym, żeby działała w trybie pełnego ekranu, co wiąże się z problemem podejścia do skalowania. W przypadku gry w oknie możemy ustalić stałą rozdzielczość, np. 600x400 i wszystko do tego dostosować - obszar gry, rozmiar menu, wielkość klocków, etc. Przy pełnym ekranie sprawa jest znacznie bardziej skomplikowana. Wszak rozdzielczości monitorów bywają bardzo różne. Pół biedy, jakby proporcja krawędzi dłuższej do krótszej była stała - wówczas obraz wystarczyłoby odpowiednio rozciągać lub zwężać. Ale tak nie jest i automatyczne skalowanie często-gęsto prowadzi do deformacji obrazu. Rozwiązaniem może być np. stosowanie czarnych pasów przy krawędziach ekranu, tworzących taki margines, jaki akurat jest potrzebny do utrzymania stałych proporcji ekranu gry. Albo pogodzenie się z ewentualną deformacją. W tym przypadku wymyślna szata graficzna odpada, bo zmiana proporcji na inną od projektowanej, będzie od razu rzucać się w oczy.
Niemniej jednak, jak już wspomniałem, artysta ze mnie żaden, więc możliwe że gra będzie zbudowana wyłącznie z podstawowych figur geometrycznych i to renderowanych przez bibliotekę graficzną, nie zaś reprezentowanych przez sprite'y. W takim przypadku deformacja mogłaby być akceptowalna. Zobaczymy.

Udźwiękowienie

Jakieś plumkanie by się przydało. Dźwięki odbicia piłeczki wydają się absolutnym minimum. Dodatkowo fajnie, jakby były różne w zależności od powierzchni, od której się odbije piłeczka (o ile będą różne powierzchnie). Ponadto dobrze dobrana muzyczka przygrywająca w tle znacząco umila rozgrywkę. Trudno jednak, żeby była wciąż taka sama: wypada zróżnicować przynajmniej na poziomie menu-rozgrywka-highscore. Ideałem byłaby muzyka dobrana do konkretnej planszy, lub jej klimatu, ale to nie wchodzi w grę. Dźwięki spróbuję znaleźć na jednym z kilku portali oferujących darmowe SFXy. Muzykę pewnie na Jamendo. Mam nadzieję, że konwersja z MP3 na jakiś niekomercyjny format nie przysporzy trudności.

Menu, stany gry

Czy chcemy mieć rozbudowane menu? Chodzi mi teraz głównie o opcje konfiguracji: dźwięku czy grafiki. Raczej bym sobie odpuścił takie szczegóły, bo dopisywanie obsługi każdej pierdoły tego typu zajmie trochę czasu, a korzyść z tego dla grywalności żadna. A jak powinna wyglądać pętla główna gry? Czy wystarczy możliwość pauzowania, czy też chcemy móc modyfikować również inne ustawienia w trakcie toczonej rozgrywki (np. zmieniamy rozdzielczość i kontynuujemy grę, jak gdyby nigdy nic)? Konsekwentnie tutaj chyba również nie ma sensu się rozdrabniać. Zdaje się, że pozostaniemy przy minimalnej ilości opcji i brakiem możliwości zmiany ustawień podczas gry (tylko pauza).

Gameplay

Standardem arukanoidów są plansze o ustalonym porządku cegiełek. Może od tego odejść? Może wymyślić algorytm losujący sensowną, grywalną planszę? Z jednej strony odpadłby problem projektowania poziomów, z drugiej wymyślenie wspomnianego algorytmu nie jest trywialnym zadaniem. Ponadto przy losowych planszach lista najlepszych wyników byłaby trochę bez sensu. Może zastosować oba rozwiązania i zrobić dwa tryby rozgrywki: fixed i random?
Jakie powinno być ustawienie planszy względem paletki? Naturalne, ze względu na skojarzenia z grawitacją i opadaniem piłki, któremu zapobiegamy, wydaje się ustawienie paletki wzdłuż dolnej krawędzi ekranu. Jednak w Krakout 2 na C64, moim ulubionym klonie, paletka chodziła po prawej krawędzi.
Czy trzymać się schematu, że trzy strony są zamknięte, a paletka chodzi po czwartej? A gdyby tak paletki były dwie - na górze i dole lub z prawej i lewej strony? Innymi słowy plansza byłaby "na przestrzał". Czy w takim przypadku lepiej będzie, żeby poruszały się równocześnie w tym samym kierunku, czy zrobić oddzielne sterowanie dla każdej?
Przeszkadzajki. Zwykle po pewnym czasie na planszy zaczynają pojawiać się przeszkadzajki - stworki poruszające się w mniej lub bardziej losowych kierunkach i utrudniające de facto zbijanie cegiełek. Raczej na pewno z tego zrezygnuję - stworki musiałyby mieć swoją grafikę, logikę pojawiania się i poruszania, przy trafieniu kulką przeszkadzajki powinien dobywać się inny dźwięk niż przy trafieniu cegiełki. Jednym słowem kupa dodatkowej roboty.
Podobne ze spadającymi witaminami (chociaż mogłyby być też ukryte pod cegiełkami, co by niwelowało problem poruszania). Znowu problemy grafiki, dźwięków. Również trzeba by przemyśleć częstotliwość pojawiania się: losowa, stała? Oprogramować efekty: powiększanie statku, multiplikacja piłek, działko, etc. Raczej się w to nie będę pakował.
Czy piłka powinna mieć stałą prędkość, czy też w miarę upływu czasu powinna przyspieszać? Czy cegiełki powinny być zawsze zrobione z takiego samego materiału, czy różnych (np. wymagających dwukrotnego trafienia do zniszczenia, znowu problem dźwięku)? Czy powinny być tradycyjnie prostokątne, czy może zastosować jakieś inne struktury, np. koła, trójkąty? Wówczas niestety fizyka odbić by się mocno skomplikowała. Czy cegły powinny być zawsze jednej i tej samej wielkości? Można by tu odejść od schematu, ale czy to byłoby grywalne?

Konfiguracja

Co powinno być konfigurowalne? Życia (początkowe, częstotliwość zdobywania życia podczas gry?), prędkość piłki (startowa, przyrost), trudność (w jaki sposób to oddać? przez dwa poprzednie parametry?), sterowanie, grafika (np. rozdzielczość, schemat kolorów), dźwięk (np. głośność)? Jak modyfikacje parametrów wpływających na trudność rozgrywki przełożyć na highscore?

Zapamiętywanie stanu

Niby zawsze fajnie jest móc zapisać stan gry i nawet nie byłoby to jakoś ekstremalnie trudne do zaimplementowania. Pytanie tylko, czy warto. W końcu ile może trwać jedna gra? Dziesięć minut? W takiej sytuacji można się chyba obejść bez mechanizmów odczytu i zapisu. Poza tym, jeśli wprowadzimy jakieś "highscore", to taka opcja fałszowałaby wyniki (chyba że jej użycie automatycznie wykluczałoby możliwość wpisu na tablicę wyników po zakończeniu danej rozgrywki). Z drugiej strony zrzucanie stanu programu do plików i odtwarzanie go jest samo w sobie mechanizmem, który często przydaje się podczas programowania i w związku z tym warto go opanować. Nie podjąłem jeszcze ostatecznej decyzji.

Multiplayer

Raczej będziemy rozważać wyłącznie rozwiązania na jednym komputerze. Jaki model - rywalizacja, kooperacja? Gra jednoczesna, na zmianę? Jeśli jednoczesna, to na podzielonym ekranie, czy jednocześnie na tej samej planszy? A jeśli tak, to jakie umiejscowienie paletek: w jednej linii przenikalne lub nie, jak w deblu tenisowym czy naprzeciwlegle?

Na tym kończę zarys problemów i dylematów. Zapraszam do wyrażania własnych preferencji, co do poszczególnych wyborów oraz zgłaszania nowych pomysłów (najlepiej niezbyt kosztownych w implementacji). Cenne będą też fachowe sugestie osób bardziej doświadczonych w produkcji gier - może czegoś ważnego nie wziąłem pod uwagę, albo upatruję jakiś problem tam, gdzie go nie ma (bo np. biblioteka graficzna zrobi to za mnie).