0. Footrzasta — mini-kurs tworzenia gier w Javie, wstęp

By 21 December 2015Footrzasta

Bard­zo ważnym ele­mentem nau­ki pro­gramowa­nia jest też ele­ment rozry­w­ki i po pros­tu czer­panie z tego przy­jem­noś­ci. Z okazji zbliża­ją­cych się świąt mamy dla Ciebie mini prezent — krót­ki kurs, pod­czas którego stworzymy grę w Javie! Nie martw się, to nie trudne, a może Ci przynieść masę radoś­ci!W ramach tego mini-kur­su stworzymy od pod­staw prostą grę, którą będziesz mogła sprezen­tować najbliższym lub stworzyć razem z młod­szym członkiem rodziny, być może inspiru­jąc go do nau­ki pro­gramowa­nia :) W tej serii wpisy będą pojaw­iać się częś­ciej niż zazwyczaj — nieste­ty z racji innych obow­iązków nie pub­liku­je­my tak częs­to, jak byśmy tego chcieli.

Nie przedłuża­jąc — prze­chodz­imy do dzieła!

Footrzasta — fabuła, zasady i o co chodzi

Na początku może słowo wyjaśnienia w kwestii tytułu — z uwa­gi na trze­ciego auto­ra tego blo­ga, oczy­wistym bohaterem gry będzie kot. Nie byle jaki kot, bo będzie to Tes­la, znana w niek­tórych krę­gach jako “futrza­s­ta”. Tes­la ma też przedzi­wne upodoban­ie do gryzienia w stopy stąd tytuł właś­ci­wie napisało życie ;)

Gra będzie grą plat­for­mową, w której głównym celem jest dotar­cie do koń­ca plan­szy. Po drodze bohater musi unikać przeszkód — myszy, stóp, oraz legowisk, które utrud­ni­a­ją osiąg­nię­cie celu (każde z nich powodu­je utratę jed­nego ze smakołyków, których ilość nie może spaść do zera). Aby móc iść dalej kotek musi oczy­wiś­cie jeść, jed­nak nie jest to takie proste — z uwa­gi na ogrom­ny apetyt prze­jedze­nie się spowodu­je spowol­nie­nie i ‘ociężałe’ ruchy, a na dodatek Tes­li upodoba­nia kuli­narne są … ory­gi­nalne — nie wszys­tko jej przy­pad­nie do gus­tu.

Technologie i nasz cel

Zaczni­jmy może od celu tej serii — nieste­ty nie nauczymy Cię tworzyć gier, na których zaro­bisz mil­iony ;) Celem tego kur­su jest przede wszys­tkim dobra zabawa — bo kto by nie chci­ał stworzyć włas­nej gry ;) — oraz nau­ka pro­gramowa­nia przy okazji :) O ile poz­nasz zasady, jaki­mi rządzi się tworze­nie gier, będziemy wyko­rzysty­wać dość ‘czyste’ narzędzia — współcześnie wiele gier tworzy się korzys­ta­jąc z gotowych sil­ników, które dba­ją o rzeczy takie jak np fizy­ka — my napisze­my taki sil­nik samodziel­nie. Dodatkowo w kilku miejs­cach ‘prze­sadz­imy’ tech­no­log­icznie — przykład­owo wyko­rzys­tamy Spring’a, bardziej po to, aby sobie poćwiczyć korzys­tanie z niego niż z dużej potrze­by :)

Jeśli chodzi o tech­nolo­gie, to sko­rzys­tamy z bib­liote­ki LWJGL (to akro­n­im od Light Weight Java Gam­ing Library), które daje nam dostęp do OpenGL — sil­ni­ka graficznego, który przez dłu­u­u­ugie lata był pod­stawą więk­szoś­ci gier i wszelkiej maś­ci pro­duk­tów związanych z wyświ­et­laniem grafi­ki. O ile bezpośred­nio nie wyko­rzys­tasz tej wiedzy do tworzenia gier np. na Androi­da, o tyle ist­nieją bib­liote­ki bard­zo podob­ne w zachowa­niu, które moż­na z powodze­niem wyko­rzys­tać w sys­temach Android (np. libGDX z tych bardziej pop­u­larnych). Być może zain­spiru­je­my Cię i zosta­niesz sławnym pro­du­cen­tem gier? Nie zapom­nij podesłać wtedy Tes­li jakiegoś smakoły­ka ;)

Pod­sumowu­jąc — w tym kur­sie prze­jdziemy przez pod­stawy pra­cy z grafiką, zasady dzi­ała­nia gier oraz stworzymy pełno­prawną, dzi­ała­jącą grę. Naszym głównym celem jest jed­nak nau­ka i zabawa, więc nie zawsze będziemy się trzy­mali ‘sztu­ki’ wg pro­fesjon­al­nych twór­ców gier. W ramach prak­ty­ki w naszej grze wyko­rzys­tamy także Springa (a także po to, aby przeła­mać stereo­typ, że jest to frame­work do aplikacji webowych).

Grę będziemy także rozwi­jać korzys­ta­jąc z repozy­to­ri­um Git, co ułatwi każde­mu pobranie jej kopii. Przed kole­jną lekcją spodziewa­j­cie się wpisu na ten tem­at :)

OpenGL

W tym miejs­cu warto powiedzieć parę słów o OpenGL — bib­liotece graficznej, z której będziemy korzys­tać. Bib­liote­ka ta pozwala na obsługę grafi­ki zarówno dwu- jak i trój-wymi­arowej i dzi­ała na więk­szoś­ci plat­form sprzę­towych, jakie są dostęp­ne na rynku. Sam stan­dard nie jest nowy (jego począt­ki się­ga­ją przeło­mu lat 80’tych i 90’tych), ale cieszy się niesłab­nącą pop­u­larnoś­cią dzię­ki swo­jej uni­w­er­sal­noś­ci (sama bib­liote­ka jest dość niskopoziomowa, co pozwala na jej wyko­rzys­tanie niemal do wszys­tkiego), pros­to­cie obsłu­gi (choć pier­wsze lin­ij­ki kodu zapewne Cię prz­er­ażą, to API jest czytelne i dobrze zor­ga­ni­zowane) oraz wyda­jnoś­ci (wiele kart graficznych wspiera oper­ac­je, które OpenGL wykonu­je, przyspiesza­jąc je — sama bib­liote­ka wyma­ga kom­pi­lacji pod kątem sys­te­mu, w którym dzi­ała).

Ponieważ bib­liote­ka ta napisana jest w języku C / C++, aby z niej korzys­tać w Javie konieczne jest zaim­por­towanie naty­wnych ele­men­tów — na szczęś­cie LWJGL robi to za nas i nie musimy się tym martwić, nie będziemy też zgłębi­ać się w szczegóły jak taki mech­a­nizm dzi­ała.

Konkuren­cyjną do OpenGL tech­nologią jest Direct3D — ele­ment bib­liote­ki Direc­tX ofer­owanej przez fir­mę Microsoft. Z uwa­gi na lep­sze wspar­cie na sys­temach poza Win­dowsem, OpenGL jest bardziej pop­u­larnym rozwiązaniem.

Obec­nie ist­nieje kil­ka ‘wari­antów’ OpenGL, m.in. OpenGL ES, który jest głównym sil­nikiem graficznym plat­formy Android i iOS . Na jego pod­staw­ie pow­stał też stan­dard WebGL, który ofer­u­je podob­ne możli­woś­ci, ale w ramach przeglą­darek inter­ne­towych (obsługu­ją­cych HTML5, którego to jest częś­cią). Zna­jo­mość zasad pra­cy z OpenGL poz­woli Ci w przyszłoś­ci łatwiej spróbować swoich sił np. z tworze­niem gier mobil­nych czy takich, które dzi­ała­ją w przeglą­darce inter­ne­towej.

Zastrzeżenie

Nasza gra, którą będziemy pokazy­wać na screenach w trak­cie tej serii, będzie się różniła od tego, co zobaczysz uruchami­a­jąc przykład czy pisząc samodziel­nie podąża­jąc za kursem. Powód tego jest proza­iczny — nie jesteśmy grafika­mi i ‘ładne’ grafi­ki po pros­tu kupil­iśmy, licenc­ja jed­nak nie pozwala nam dzielić się tymi grafika­mi z Tobą. Dlat­ego w mate­ri­ałach do pobra­nia i na repozy­to­ri­um zna­jdziesz mniej este­ty­czne grafi­ki, które pochodzą z dar­mowych zestawów. Nie martw się jed­nak — na końcu tej lekcji zna­jdziesz przykład­owe lin­ki, pod który­mi możesz kupić ład­ny zestaw grafik. Za nasze zapła­cil­iśmy w sum­ie ok. 60zł — także nie jest to majątek, a może­my dopa­sować grę do ulu­bionej postaci naszego dziecka/rodzeństwa/partnera/rodziny itp. Oczy­wiś­cie nie jest to konieczne i moż­na także uży­wać bezpłat­nych ele­men­tów lub też stworzyć własne — ogranicze­niem jest tutaj tylko Two­ja wyobraź­nia :)

Jak zapewne zauważysz w kole­jnych częś­ci­ach, kod będzie pisany ‘po ang­iel­sku’ — nazwy klas i metod będziemy bazowali na języku ang­iel­skim. Powód jest proza­iczny — jak już wspom­i­nal­iśmy planu­je­my uru­chomić anglo­języ­czną wer­sję blo­ga. I choć ostat­nio nie mamy na to zbyt wiele cza­su, posi­adanie kodów źródłowych w tym języku znacznie ułatwi nam tłu­macze­nie treś­ci w przyszłoś­ci :)

Jak pisze się gry

Zaczni­jmy od wstępu teo­re­ty­cznego — czyli jak ‘dzi­ała’ gra. Różnic w sto­sunku do ‘stan­dar­d­owych’ aplikacji jest wiele, ale nie jest to też magia ;)

Rysowanie — wyświetlamy grafikę

Przede wszys­tkim wyświ­et­lanie — gry bard­zo częs­to inten­sy­wnie korzys­ta­ją z pro­ce­so­ra czy pamię­ci, cza­sem spowal­ni­a­jąc cały kom­put­er — objaw­ia się to ‘pok­latkową’ grafiką — przykład­owo ekran odświeża się co najwyżej kilka­naś­cie razy na min­utę. Jak zapewne nier­az widzi­ałaś, kiedy ‘nor­mal­na’ aplikac­ja się ‘zat­nie’, widać kole­jność, w jakiej pojaw­ia­ją się czy są mody­fikowane ele­men­ty. Podob­nie wyglą­da to na stronach inter­ne­towych, które wczy­tu­ją się powoli. Dlaczego w grach wyglą­da to inaczej? Dlat­ego, że stosowany jest tutaj pewien trick.

Przede wszys­tkim w prze­ci­wieńst­wie do stan­dar­d­owych aplikacji za każdym razem sce­na prz­erysowywana jest od nowa — dzieje się to kilka­dziesiąt razy na sekundę (co najm­niej 30 razy, aby ani­mac­ja była płyn­na), i liczbę tą częs­to opisu­je się jako FPS — frames per sec­ond. Im wyda­jniejszy kom­put­er, tym wskaźnik ten będzie więk­szy. Co więcej — licz­ba ta się zmienia, w zależnoś­ci od dostęp­nych mocy obliczeniowych w danym momen­cie. Jak więc gra ‘wie’ co wyświ­etlić w danej klatce, aby np. chodze­nie odby­wało się zawsze z tą samą pręd­koś­cią? Otóż wszelkie akc­je w grze (takie jak ruch, wro­gowie itp) są prze­chowywani w odniesie­niu do cza­su rzeczy­wis­tego — czyli np. iloś­ci milisekund od uru­chomienia gry. Dzię­ki temu gra wie, że skok czy poje­dynczy ruch zaj­mu­je określoną ilość cza­su i powodu­je prze­sunię­cie o określoną ilość jed­nos­tek w grze — wiedząc jaki jest ‘czas’ w przyjętej skali odniesienia w momen­cie rysowa­nia sce­ny, gra może pre­cyzyjnie określić w jakiej pozy­cji powinien być gracz, wro­gowie itp.

Zas­tanaw­iasz się ter­az pewnie dlaczego, nawet jeśli kom­put­er spowal­nia, nie ‘widać’ tego prz­erysowywa­nia. Otóż zas­tosowanie tutaj ma kole­jny spry­t­ny trick. Zami­ast najprost­szego cyk­lu -> wyczyść ekran -> nary­suj od nowa -> powtórz, kom­put­er trzy­ma w pamię­ci dwa ‘ekrany’ (nazy­wa się to for­mal­nie ram­ki — w języku ang­iel­skim frames; real­nie jest ich więcej niż dwie, ale zasa­da pozosta­je ta sama). Jed­na jest wyświ­et­lana, nato­mi­ast drugiej uży­wamy do rysowa­nia. Kiedy ta ram­ka jest gotowa i w pełni narysowana, instru­u­je­my kartę graficzną ‘zamień je ze sobą’ i pow­tarza­my oper­ac­je. Oper­ac­ja ‘zamień’ wyma­ga jedynie przepisa­nia obszaru pamię­ci i wykonu­je się bard­zo szy­bko — w maksy­mal­nie kilka­dziesiąt cyk­li pro­ce­so­ra (czyli ok. jed­nej mil­iar­dowej częś­ci sekundy na współczes­nym sprzę­cie), dzię­ki czemu nie widać efek­tu ‘rysowa­nia’.

Obsługa klawiatury, myszki itp

Klaw­iaturę moż­na obsługi­wać na dwa sposo­by — albo w osob­nym wątku, czeka­jąc na naciśnię­cie klaw­isza, albo odczy­ty­wać bufor klaw­iatu­ry w momen­cie prz­erysowywa­nia ekranu. Będziemy korzys­tać z tego drugiego pode­jś­cia — nie jest nam potrzeb­ny wątek tylko do obsłu­gi wejś­cia, co poz­woli nam nieco uproś­cić nasz kod. Tryb ten jest też wspier­any przez LWJGL, co także nieco ułatwi.

W grze założymy proste sterowanie — strza­ł­ki do porusza­nia się, spac­ja do wykony­wa­nia akcji i enter oraz escape do porusza­nia się w menu.

Zasoby gry

W ramach wyjaśnienia dlaczego pewne rzeczy będziemy imple­men­towali w ten a nie inny sposób — a konkret­nie dlaczego będziemy starali się wczy­tać wszys­tkie pli­ki graficzne i dźwiękowe zan­im grę w ogóle wyświ­etlimy. Otóż oper­ac­je na plikach są naj­droższe, jakie moż­na wykon­ać. Aby to zobra­zować — wczy­tanie jed­nego pliku graficznego to załóżmy 100 oper­acji pro­ce­so­ra (trochę nieefek­ty­wnie, ale niech będzie). Przy współczes­nych pro­ce­so­rach zajmie to teo­re­ty­cznie jed­ną stu­mil­ionową część sekundy, czyli jakieś 10 nanosekund. W przy­pad­ku dysków trady­cyjnych, samo ułoże­nie głow­icy w miejs­cu do odczy­tu zaj­mu­je śred­nio 10–15 ms, czyli pon­ad 10 000 nanosekund. Jeśli przyjmiemy, że dla płyn­nej ani­macji potrze­bu­je­my wygen­erować co najm­niej 30 klatek na sekundę, oznacza to że mamy ok. 30ms na wygen­erowanie jed­nej — w takiej sytu­acji wczy­tanie więcej niż jed­nego pliku stanie się zauważalne dla płyn­noś­ci ani­macji. I to przy założe­niu, że żad­na inna aplikac­ja nie korzys­ta z dysku w danym momen­cie.

Oczy­wiś­cie są szyb­sze dys­ki, są także dys­ki SSD, które jeszcze bardziej skra­ca­ją ten czas, ale w dal­szym ciągu dostęp do pamię­ci RAM jest o rząd wieloś­ci szyb­szy od dostępu do jakiegokol­wiek dysku.

Z tego powodu będziemy wczy­ty­wać maksy­mal­nie wiele ele­men­tów do pamię­ci RAM, aby wyko­rzysty­wać je później bez zbęd­nej zwło­ki.

Podsumowanie

Wiesz już mniej więcej jak będzie wyglą­dało tworze­nie gier, i z jakich tech­nologii będziemy korzys­tać. Wprawdzie jeszcze nie napisal­iśmy ani jed­nej lin­ij­ki kodu, zabierze­my się za to już w kole­jnej lekcji. Póki co warto zapoz­nać się z tech­nolo­gia­mi, których będziemy uży­wać, wybrać grafi­ki do Two­jej gry lub wymyślić włas­ną fabułę, którą zre­al­izu­jesz razem z naszym kursem!

Konkurs

Żeby było troszkę ciekaw­iej, mamy dla Was konkurs! Do koń­ca tygod­nia (do półno­cy z niedzieli 27.12.2015 na poniedzi­ałek 28.12.2015) może­cie zgłaszać swo­je propozy­c­je rozsz­erzenia do gry — np. możli­wość strze­la­nia, dodatkowe przeszkody, akc­je, które moż­na wykony­wać, ele­men­ty plan­szy — tak naprawdę cokol­wiek, co przyjdzie Ci na myśl. Pomysły będziemy oce­ni­ać pod kątem tego jak bard­zo są intere­su­jące, ale także czy są kom­pletne (np. pro­ponu­jąc strze­lanie opisz także czym są pocis­ki, jak dzi­ała­ją na otocze­nie czy przeszkody, czy jest skońc­zona czy nieskońc­zona ilość itp). Naj­ciekawsze odpowiedzi zaim­ple­men­tu­je­my w grze w trak­cie tego mini-kur­su, a dwie odpowiedzi nagrodz­imy: jed­ną książką o pisa­niu aplikacji mobil­nych na sys­tem Win­dows 10, a drugą książką o Scru­mie.

Pisz­cie Wasze propozy­c­je w komen­tarzach!

Zwycięz­ca­mi konkur­su są Marcin­ho oraz anthime — grat­u­lu­je­my! Będziemy się kon­tak­tować mailowo, a Wasze pomysły zaim­ple­men­tu­je­my w grze ;)

Zasoby

  • http://opengameart.org — grafi­ki, ścież­ki dźwiękowe itp
  • http://www.newgrounds.com — bard­zo duże zaso­by, w szczegól­noś­ci muzy­ki (na licencji CC — do użytku niekomer­cyjnego)
  • http://www.gameart2d.com — głównie grafi­ki, całkiem dobrej jakoś­ci (także w sekcji free­bies)
  • http://graphicriver.net — ilus­trac­je, grafi­ki, obraz­ki itp — strona jest płat­na, ale moż­na tam trafić naprawdę na pereł­ki (pod kątem gier, szukaj ‘sprites’ albo po pros­tu ‘game’)
  • https://craftpix.net/freebies/ — bezpłatne i płatne ele­men­ty do gier
  • https://creativemarket.com — podob­na do powyższej, konkuren­cyj­na strona, także wiele bard­zo ład­nych ele­men­tów w korzyst­nej cenie
  •  
  •  
  •  
  •  
  •