implementacja gry komputerowej z interfejsem głosowym

43
str. 1 AKADEMIA GÓRNICZO-HUTNICZA IM. STANISŁAWA STASZICA W KRAKOWIE WYDZIAŁ INFORMATYKI, ELEKTRONIKI I TELEKOMUNIKACJI INŻYNIERSKA PRACA DYPLOMOWA IMPLEMENTACJA GRY KOMPUTEROWEJ Z INTERFEJSEM GŁOSOWYM Autorzy: Konrad Jagielski, Bartosz Orliński Kierunek studiów: Elektronika i Telekomunikacja Opiekun pracy: dr inż. Bartosz Ziółko Kraków, rok akademicki 2015/2016

Upload: phamtu

Post on 11-Jan-2017

225 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Implementacja gry komputerowej z interfejsem głosowym

str. 1

AKADEMIA GÓRNICZO-HUTNICZA IM. STANISŁAWA

STASZICA W KRAKOWIE

WYDZIAŁ INFORMATYKI, ELEKTRONIKI I TELEKOMUNIKACJI

INŻYNIERSKA PRACA DYPLOMOWA

IMPLEMENTACJA GRY KOMPUTEROWEJ Z INTERFEJSEM GŁOSOWYM

Autorzy: Konrad Jagielski, Bartosz Orliński

Kierunek studiów: Elektronika i Telekomunikacja

Opiekun pracy: dr inż. Bartosz Ziółko

Kraków, rok akademicki 2015/2016

Page 2: Implementacja gry komputerowej z interfejsem głosowym

str. 2

Oświadczamy, świadomi odpowiedzialności karnej za poświadczenie nieprawdy, że

niniejszą pracę dyplomową wykonaliśmy osobiście i samodzielnie (w zakresie

wyszczególnionym we wstępie) i że nie korzystaliśmy ze źródeł innych niż wymienione w

pracy.

Page 3: Implementacja gry komputerowej z interfejsem głosowym

str. 3

Serdeczne podziękowania dla dr inż. Bartosza Ziółko opiekuna pracy,

mgr inż. Szymona Pałki oraz mgr inż. Dawida Skurzoka,

za pomoc merytoryczną, wsparcie i motywację do pracy.

Page 4: Implementacja gry komputerowej z interfejsem głosowym

str. 4

Spis treści 1. Wstęp .................................................................................................................................. 5

1.1. Cel pracy.......................................................................................................................... 5

1.2. Streszczenie ..................................................................................................................... 5

2. Wprowadzenie .................................................................................................................... 6

2.1. Gry Komputerowe ........................................................................................................... 6

2.2. Hero Defense ................................................................................................................... 7

2.3. Rozpoznawanie mowy – ogólnie .................................................................................... 8

2.4. Rozpoznawanie mowy w grach ....................................................................................... 9

3. Opis narzędzi .................................................................................................................... 10

3.1. Unity3D ......................................................................................................................... 10

3.3 System kontroli wersji. ................................................................................................... 12

4. Opis projektu ........................................................................................................................ 12

4.1 Opis gry .......................................................................................................................... 12

4.2. Opis grafiki .................................................................................................................... 14

4.3. Implementacja SARMATY ........................................................................................... 17

4.4 Opis elementów .............................................................................................................. 19

4.4.1. Gracz ....................................................................................................................... 19

4.4.2. GameMaster ............................................................................................................ 22

4.4.3. Capzone .................................................................................................................. 22

4.4.4. Magia ...................................................................................................................... 24

4.4.5. Minotaur ................................................................................................................. 26

4.4.6 Przeciwnicy .............................................................................................................. 27

4.4.7. Interfejs użytkownika. ............................................................................................ 31

4.4.8 Kamera ..................................................................................................................... 36

4.5 Sposób podziału pracy – Metodyka Agile ..................................................................... 37

4.6 Fazy projektowania ........................................................................................................ 39

5. Zakończenie ...................................................................................................................... 40

5.1 Podsumowanie................................................................................................................ 40

5.2. Problemy ....................................................................................................................... 40

5.3. Przyszłość projektu........................................................................................................ 41

Page 5: Implementacja gry komputerowej z interfejsem głosowym

str. 5

1. Wstęp

Niniejsza praca inżynierska jest wynikiem wspólnej pasji jej autorów. Zamiłowanie do gier

komputerowych nie było oczywiście jedyny czynnikiem wpływającym na wybór tematu.

Istotna rolę odegrała także chęć rozwoju umiejętności programistycznych w języku

programowania C#, którego poznanie stało się kolejnym krokiem rozwoju zawodowego

autorów jak również poznanie sposobu działania silnika Unity3D, a także pracy w nim.

Ciekawą wydawała się również perspektywa projektowania własnego oprogramowania

oraz wypróbowania w praktyce poznanej metodyki Agile jako sposobu zarządzania.

1.1. Cel pracy

Celem pracy było stworzenie gry komputerowej sterowanej nie tylko za pomocą

klasycznego sterowania klawiaturą i myszą, ale także z wykorzystaniem interfejsu

głosowego. Gracz miał kontaktować się z grą korzystając z mikrofonu dzięki

wykorzystaniu systemu rozpoznawania mowy. Pobocznym celem pracy było sprawdzenie

czy podobne rozwiązanie ma sens funkcjonowania na rynku komercyjnym, a także

pokazanie procesu twórczego towarzyszącego kreacji gry komputerowej.

1.2. Streszczenie

Poniższa praca inżynierska jest opisem implementacji gry komputerowej, mającej na celu

zademonstrowanie wykorzystania interfejsu głosowego opartego o rozpoznawanie mowy

polskiej przy użyciu systemu SARMATA stworzonego przez Zespół Przetwarzania

Sygnałów Akademii Górniczo-Hutniczej[1]

. Przedstawiono krótki opis wybranego gatunku

gier, a także historię wykorzystania rozpoznawania mowy w grach komputerowych.

Dalsza część pracy przedstawia również złożony opis silnika Unity3D w którym została

stworzona opisywana gra. W pracy opisano także główne klasy wykorzystywane w grze.

W związku z faktem tworzenie projektu w dwuosobowym zespole przedstawiono również

sposób dzielenia pracy oraz opisano poszczególne etapy jej powstawania. W części

kończącej pracę poza podsumowaniem opisano pojawiające się w trakcie implementacji

problemy, a także zaproponowano dalsze możliwości rozwoju projektu.

Page 6: Implementacja gry komputerowej z interfejsem głosowym

str. 6

2. Wprowadzenie

2.1. Gry Komputerowe

Gry komputerowe podobnie jak inne formy zabawy opiera się o podstawowy cel,

wybierany przez gracza bądź narzucany przez twórców. Graczowi dostarczana jest

rozrywka poprzez pokonywanie stawianych przez niego wyzwań. Kluczowym elementem

gry komputerowej jest całość oprawy audiowizualnej. Celem twórcy jest więc zapewnienie

graczowi długich godzin jak najciekawszej formy rozrywki poprzez stawianie na jego

drodze grafiki i dźwięku opartych o pewną narracje.

Gry komputerowe powstały w połowie XX wieku jako produkcje akademickie. Następnie

głównie za sprawą amerykańskiego (Atari) i japońskiego (Nintendo) przemysłu gry

komputerowe stały się elementem rozrywki masowej. Mimo, że początkowo gry

wydawane były głównie na dedykowane konsole to ich rozwój jest nierozerwalnie

złączony z rozwojem komputerów osobistych. W latach 90. XX wieku zaczęły powstawać

pierwsze produkcje o grafice imitującej trójwymiarową, z których niektóre stały się

później kanonem klasyki gier komputerowych. XXI wiek przyniósł branży ogromne

możliwości. Szerokopasmowy Internet pozwolił na wprowadzenie w grach trybów

wieloosobowych, a co za tym idzie elementów socjalizacji. Przyciągnęło to nie tylko

miliony graczy, ale również gigantyczne pieniądze. Zgodnie z raportem ESA-Essential-

Facts[2]

w samych Stanach Zjednoczonych w szeroko pojęte gry wideo w 2014 roku grało

około 155mln mieszkańców. Należy również wspomnieć, że najlepiej sprzedające się

produkcje przynoszą twórcą i wydawcą ogromne dochody. Przykładowo seria Call Of

Duty sprzedaje się rokrocznie w około 20 milionach egzemplarzy, przynosząc wydawcy

zyski rzędu kilkuset milionów dolarów już w ciągu pierwszych godzin od premiery[3]

.

Gracze stają się jednak bardziej świadomi, podobnie jak w innych dziedzinach rozrywki w

wyniku przesycenia rynku wielkimi produkcjami, coraz częściej sięgają po produkcje

niszowe, dostępne za mniejsze pieniądze, a dostarczające zabawy na długie godziny.

Mamy, więc dzięki temu (jak również dzięki firmie Valve Corporation i jej platformie

Steam) do czynienia z intensywnym rozwojem produkcji niezależnych (Indie Games). Nie

wszystkie oczywiście można zaliczyć do udanych. Jednak obserwacja powstających

produkcji pozwala na wyznaczanie trendu panującego na rynku.

Twórcy coraz częściej sięgają po rozwiązania alternatywne np. w dziedzinie sterowania.

Największe firmy w branży sięgają po sterowanie gestem czy różnego rodzaju sensorami.

Nieco zaniedbywany jest koncept sterowania przy pomocy głosu co stało się niejako

powodem powstania tej pracy.

Page 7: Implementacja gry komputerowej z interfejsem głosowym

str. 7

2.2. Hero Defense

Aby rozgrywka nie była monotonna każda gra powinna posiadać cel oraz element

współzawodnictwa. Jeden typ takich gier nazwany jest w języku angielskim „Hero

Defense” co można luźno przetłumaczyć na język polski jako „bohaterska obrona”. Jego

celem jest obrona obszaru lub budynku przed napierającymi kolejnymi falami wrogów.

Prekursorem tego gatunku jest stworzona jako mapa społeczności – czyli wymyślona oraz

zbudowana w całości przez graczy za pomocą udostępnionych wewnętrznych narzędzi - w

grze wydanej na komputery osobiste, Warcraft 3.

Pierwszą decyzją gracza był wybór bohatera – każdy z nich różnił się posiadanymi

zdolnościami specjalnymi, czarami oraz specyfikacją swoich atrybutów odpowiadających

między innymi za ilość życia, siłę i szybkość ataku czy maksymalną liczbę rzuconych

czarów. Następnie był on rzucany w ferwor walki, gdzie miał do pokonania trzy

przeszkody – uciekający czas, innych graczy oraz nieskończone morze przeciwników. Co

określoną chwilę pojawia się kolejna fala przeciwników, za każdym razem rosnąca w siłę.

Gracze muszą nie dopuścić przeciwników do dotarcia w określone miejsce na mapie,

jednocześnie współzawodnicząc ze sobą w ilości pokonanych wrogów.

Rysunek 1 Screen z gry Warcraft 3 obrazujący mapę typu Hero Defense[4]

Jak wiele map tego typu Hero Defense doczekało się swojego wydania w wersji

niezależnej od Warcraft 3. Jedna z nowszych produkcji tego typu o nazwie Bloodsports.TV

Page 8: Implementacja gry komputerowej z interfejsem głosowym

str. 8

została wydana w marcu 2015 roku, jednak nie zebrała dobrych recenzji i ciągle nie cieszy

się popularnością[5]

.

Gry typu Hero Defense wydają się być przytłoczone przez podobny typ gier, również

powstałych jako modyfikacja do Warcraft 3 o nazwie DOTA – MOBA[6]

(z ang.

Multiplayer Online Battle Arena). Różnica między nimi polega na tym, iż gracze stoją po

obu stronach konfliktu, wspomagając kolejne fale jednostek dążą do zniszczenia głównego

budynku przeciwnika. Powodem tej nierównowagi może być fakt, iż walka ze sztuczną

inteligencją nie przynosi graczom takiej rozrywki i dozy przyjemności jak

współzawodniczenie z żywym przeciwnikiem.

Powstało również wiele aplikacji na platformę android, które realizują rozgrywkę tego

typu. Wiele z nich przenosi gracza w świat dwuwymiarowy, co ułatwia kontrole nad

postacią na ekranie dotykowym. Według danych z play.google.com najpopularniejsze gry

tego typu pobierane są między sto a pięćset tysięcy razy[7]

.

2.3. Rozpoznawanie mowy – ogólnie

Rozpoznawanie mowy to technologia polegająca na interpretacji mowy przez urządzenie.

Ze względu na niską absorbcje uwagi pozwala na przykład na sterowanie urządzeniami bez

konieczności użycia kończyn, może być też szczególnie przydatna dla osób

niepełnosprawnych jak i jako narzędzie transkrypcji. Obecnie istnieje wiele systemów

rozpoznających mowę w różnych językach, systemy te wciąż posiadają jednak wiele wad

wynikających z różnego rodzaju problemów implementacyjnych. Sygnały wejściowe

charakteryzują się dużą zmiennością, mówcy mówią w różny sposób, mają różne dialekty

czy różne tempo wypowiedzi. Jednak problemy hamujące rozwój technologii

rozpoznawania mowy wynikają nie tylko z aspektów technicznych, ale także z pewnych

limitacji wdrożeniowych. Używanie sterowania głosowego jest ograniczone ze chociażby

ze względu na fakt, że różni użytkownicy mogą przeszkadzać sobie nawzajem.

Rozwiązywanie tych problemów trwa od dziesięcioleci, a wciąż jest jeszcze wiele do

zrobienia.

W rozważaniach o rozpoznawaniu mowy należy zwrócić uwagę na historię powstawania

kolejnych elementów koniecznych nie tylko do samej cyfrowej analizy, ale również do

samego pozyskania próbek głosu czyli po prostu jego nagrania. Niewątpliwie ważną rolę w

tej dziedzinie odegrał Aleksander Graham Bell który w latach osiemdziesiątych XIX

wieku zbudował telefon tworząc podwaliny dzisiejszej techniki przesyła głosu za pomocą

słuchawki i mikrofonu. W 1920 roku zbudowano prymitywny system reagujący na imię

psa: "Rex", a dokładniej głoskę "e" zintegrowany z psią budą i zabawkowym psem –

system nazywał się tak jak pies i reagował na charakterystyczną zmianę częstotliwości

towarzyszącą głosce[8]

. W latach pięćdziesiątych XX wieku Bell Labs zademonstrował

AUDREY maszynę rozpoznającą cyfry. Rozwojowi maszyn rozpoznających głos

towarzyszył rozwój słowników. Obecnie kiedy dysponujemy ogromnymi możliwościami

jeśli chodzi o pozyskiwanie i przechowywanie danych wielkie korporacje z łatwością

Page 9: Implementacja gry komputerowej z interfejsem głosowym

str. 9

mogą pracować nad takimi systemami. Jednym z najbardziej rozpowszechnionych (bo

dostępnym między innymi w niemal każdym nowym smartfonie z systemem Android)

systemem rozpoznawania mowy jest Google Speech Api[9]

. W 2011 roku kalifornijski

gigant dysponował słownikiem języka angielskiego z około milionem różnych słów.

Obecnie dzięki tym systemom możemy dyktować treść wiadomości prowadząc samochód

czy korzystać z wyszukiwarki internetowej bez konieczności korzystania z rąk. Mimo, iż

najlepiej rozpoznawany jest język angielski firma wprowadza również słowniki innych

języków. System ma jednak wiele wad jest dość wolny, ponieważ stosuje moduły uczenia

maszynowego oraz niedokładny co ma jednak dzięki rozwojowi sprzętu i metod ma stać

się bardziej użyteczny. W pracy korzystano z systemu rozpoznawania mowy

SARMATA[1]

stworzonego przez zespół DSP.

2.4. Rozpoznawanie mowy w grach

Przemysł gier komputerowych ciągle poszukuje nowych pomysłów jak wzbogacić

rozgrywkę oraz jak sprawić, by gracz czuł się w wirtualnym świecie jak w prawdziwym

życiu. Powstało wiele interfejsów, pozwalających na interakcje człowieka z grą.

Najbardziej popularnymi są klawiatura komputera w połączeniu z myszką, pady

stosowanie głównie na konsolach oraz zestawy osprzętu samochodowego, lub mapy

taneczne. W ostatnich latach na rynku, w raz z rozwojem techniki pojawiają się coraz

bardziej złożone interfejsy, jak na przykład sensory ruchu bazujące na kamerach video –

Kinect od Microsoftu, czy PlayStation Move od Sony. Naturalnym sposobem wymiany

informacji między ludźmi jest rozmowa. Ludzki umysł przystosowany jest do takiego

tempa i sposobu przyswajania wiedzy, co wynika z wielu lat ewolucji.

Coraz więcej producentów gier zdaje się zauważać fakt, iż możliwe jest połączenie gracza

z ich wirtualnymi awatarami za pomocą interfejsu głosowego. Wydając polecenia głosowe

można tworzyć scenariusze gier, w których całość świata sterowana jest za pomocą

komend lub są one dodatkiem do istniejących już kontrolerów.

Jednym z przykładów gier, gdzie całkowita kontrola sprawowana jest za pomocą komend

głosowych jest There Came An Echo[10]

. Gra została stworzona od podstaw z zamysłem

wykorzystania takiego interfejsu. Gracz wciela się w niej w dowódcę niewielkiego

oddziału, któremu wydając polecenia próbuje przejść kolejne poziomy i ukończyć wątek

fabularny. Do dyspozycji została oddana cała gama poleceń, odnoszących się zarówno do

poszczególnych członków drużyny, jak i do niej całej.

Na planszy umieszczono specjalne znaczniki, z których każdy posiada indywidualną

nazwę. Używając ich w rozkazach gracz może przemieścić swoich podwładnych lub

przeprowadzić ostrzał danej pozycji. Każda z postaci posiada własny zestaw broni, do

których użycia zachęca się poprzez użycie ich nazw w poleceniu. Gra jest sprzedawana na

platformie Steam, gdzie niestety nie cieszy się dużą popularnością. Z 244 recenzji

pozytywnych jest 75%[11]

, co pozwoliło Steam’owi ocenić je na „W większości

pozytywne” (stan na dzień 25.12.2015). Gra nie obsługuje mowy polskiej.

Page 10: Implementacja gry komputerowej z interfejsem głosowym

str. 10

Kolejna grą, w której wymiennie można stosować polecenia głosowe, jak i klasyczne

sterowanie za pomocą klawiatury i myszki to Tom Clancy’s EndWar. Tutaj również,

podobnie jak w There Came An Echo gracz wciela się w dowódcę, tym razem całej armii.

Każda z jednostek posiada indywidualne oznaczenie, odnosząc się do którego można

wydać jej odpowiednie rozkazy – zaatakowanie wrogiej jednostki, zajęcie punktu

kontrolnego czy rekrutacja nowych żołnierzy. Gra została oceniona w bardzo podobny

sposób jak opisywana wcześniej – na portalu Steam ze 171 recenzji pozytywnych było

74%[12]

. Ocena to również „W większości pozytywne”. Mowa polska nie jest obsługiwana.

Dlaczego gry tego typu nie zdobyły popularności? Możliwe, że odpowiedź na to pytanie

kryje się w sposobie, w jaki człowiek odbiera i przekazuje informacje mówione. Znaczenie

ma tutaj nie tylko sama treść informacji, lecz także sposób w jakim zdanie zostało

wypowiedziane. Mimika twarzy i gestykulacja również odgrywają znaczącą rolę w

komunikacji interpersonalnej. Komputer pozbawiony osobowości jest w stanie tylko

reagować na wykryte czynniki lub przeprowadzać z góry zaplanowane akcje, co jest

natychmiast wychwytywane przez człowieka i sprawia wrażenie nienaturalnego.

Jednak samo nasycenie emocjonalne głosu może również zostać wykorzystane w grach

wideo, jako kolejny czynnik odpowiadający na przykład za szybkość pojazdu, moc czaru

lub chęć z jaką wirtualna postać wykona zlecone przez gracza zadanie.

3. Opis narzędzi

3.1. Unity3D

Unity3D[24]

to jeden z największych dostępnych za darmo edytorów gier komputerowych.

Edytor jest wyposażony w własny silnik graficzny, dźwiękowy oraz symulator fizyki.

Unity pozwala na tworzenie gotowych gier na różne platformy zarówno w 3D jak i w 2D.

Dostarcza także gotowe funkcje do tworzenia i łączenia animacji czy też obróbki i

planowania rozgrywki. Środowisko jest bardzo rozbudowane jednak aby stworzyć grę w

Unity3D nie potrzeba kilkuletniego doświadczenia w programowaniu czy w korzystaniu z

samego edytora. Wystarczy zrozumieć podstawowe pojęcia i nauczyć się poruszać w

interfejsie i na podstawie poradników w Internecie oraz gotowych paczek z dodatkami

można stworzyć grę. Środowisko nie jest jednak używane tylko przez twórców

niezależnych, ale także przez duże studia, są w nim tworzone setki gier dzięki czemu

bardzo szybko się rozwija. Uaktualnienie do wersji obecnej piątej już generacji było

dużym skokiem w rozwoju silnika. Wprowadzono wersje 64-bitową, a także wiele zmian

w obsłudze animacji i dźwięku. Dzięki temu w nowej wersji Unity3D tworzone są między

innymi takie produkcje jak Hearthstone, Wasteland 2, Cities: Skylines czy DeusEx:The

Fall.

Page 11: Implementacja gry komputerowej z interfejsem głosowym

str. 11

Rysunek 2 Screen edytora Unity

Interfejs Unity składa się z wielu dostępnych widoków. Najistotniejsze to "Hierarchia",

"Scena", "Inspektor" oraz "Gra". Po odpowiednim rozmieszczeniu widoków w głównym

oknie edytor jest gotowy do tworzenia gry. Proces twórczy odbywa się poprzez

przeciągnie elementów na scenę i edytowanie ich komponentów w oknie inspektora. Na

scenie deweloper operuje w trójwymiarowym układzie współrzędnych. Każdy obiekt

posiada swoje współrzędne zawarte w wbudowanym w Unity komponencie typu

Transform. Z punktu widzenia dewelopera programisty najważniejszym komponentem jest

skrypt. Do każdego elementu na scenie możemy dołączyć komponent skryptu zawierający

dowolne określone w kodzie zachowania mające być realizowane przez dany obiekt.

Twórcy silnika dostarczyli jednak bardzo wiele gotowych komponentów pozwalających

między innymi na symulacje fizyki czy renderowanie grafiki.

Każdemu typowi w kodzie odpowiada klasa, każdemu komponentowi instancja tej klasy. Z

poziomu programisty poruszanie się po obiektach na scenie jest bardzo łatwe. Każda klasa

odpowiadająca za zachowanie danego obiektu automatycznie dziedziczy z klasy

MonoBehaviour której metody pozwalają na wyszukania referencji każdego komponentu

w danym obiekcie oraz jego hierarchicznych dzieciach. MonoBehaviour posiada też

funkcje wywoływane automatycznie w odpowiednich momentach pozwalające na

wykonywanie się określonych przez twórcę czynności. W projekcie użyte zostały funkcje

Start() – wywoływana w pierwszej klatce w której obiekt staje się aktywny, Update() -

zawsze na początku każdej klatki, LateUpdate() - na końcu każdej klatki oraz

OnTriggerEnter() – wywoływana jednorazowo w momencie przejścia obiektu

transparentnego przez inny obiekt czy OnColiderEnter() – w momencie kolizji obiektów

fizycznych. Dzięki czemu programowanie w edytorze jest bardzo proste.

Page 12: Implementacja gry komputerowej z interfejsem głosowym

str. 12

Unity3D w ramach współpracy z firmą Microsoft dostarcza dodatek dla Visual Studio

pozwalając na debugowanie kodu w trakcie gry, a także połączenie z serwerem kontroli

wersji.

3.3 System kontroli wersji.

Niezależnie od wielkości czy typu projektu korzystanie z systemu kontroli wersji pozwala

osobom w niego zaangażowanym na łatwe zarządzanie kolejno wprowadzanymi

zmianami. Korzysta on z tak zwanych repozytoriów, czyli nadrzędnych zbiorów kodu i

historii jego zmian. Każde repozytorium składa się z co najmniej jednej gałęzi (ang.

branch), która pozwala zrównoleglić proces wprowadzania zmian. Takie udogodnienie

sprawia, iż gdy zajdzie taka potrzeba można zachować aktualnie wprowadzane zmiany i

powrócić do nich później.

System kontroli wersji sprawdza się doskonale do scalania kodu pisanego przez wiele

osób. Po wykonaniu przydzielonego zadania oraz przejściu przez system recenzji

programista może wprowadzić swoją zmianę do wspólnego repozytorium. Tego typu

system pozwala odnieść się do dowolnego momentu istnienia kodu, poprzez przywołanie

konkretnej zmiany, a także daje możliwość wycofania dowolnego ich podzbioru. Jest to

naturalny wybór, gdy zachodzi potrzeba pracy w metodykach zwinnych. W pracy

korzystano z systemu dostarczanego przez firmę Microsoft[25]

.

4. Opis projektu

4.1 Opis gry

Stworzona w ramach pracy inżynierskiej gra zawiera elementy Hero Defense. Osadzona w

realiach fantasy bitwa pomiędzy samotnym magiem – wirtualną reprezentacją gracza -

oraz hordą przeciwników mających tylko jeden cel – dotrzeć za wszelką cenę do

bronionego przez gracza obiektu.

W grze rozróżnione są trzy typy przeciwników, każdy z nich posiada odmienne

właściwości i gracz powinien użyć innej taktyki, w zależności od bliskości danego typu

wrogów oraz ich ilości w danym obszarze. Celem gry jest jak najdłuższe przetrwanie

gracza, który ograniczony jest jedynie ilością zdrowia, traconą po każdorazowym dotarciu

wroga do strefy zamkniętej, bronionej przez bohatera. Z każdym zabitym wrogiem gracz

otrzymuje punkty mnożone dodatkowo przez poziom wzrastający co określoną ilość czasu.

Page 13: Implementacja gry komputerowej z interfejsem głosowym

str. 13

Rysunek 3 Screen z gry z widocznym interfejsem

Gracz ma możliwość poruszania się w trójwymiarowym świecie. Aby nie dopuścić

wrogów do celu musi ich niszczyć za pomocą szerokiego wachlarza czarów oraz swojego

pomocnika – chowańca minotaura.

Sterowanie w grze zrealizowane jest za pomocą hybrydy sterowania klasycznego – myszki

i klawiatury – oraz interfejsu głosowego. Każdy z czarów realizowany jest za pomocą

wypowiedzenia dwóch słów – kształtu czaru oraz jego żywiołu. Minotaur reaguje na

polecenie ataku po uprzednim umieszczeniu przez gracza znacznika na odpowiednim

wrogu.

Jeśli zbyt wiele przeciwników dostanie się do bronionego miejsca, gracz umiera i gra się

kończy.

Wszystkie postacie zostały wygenerowane za pomocą silnika Mixamo[26]

należącego do

Adobe. Aktualnie modele nie są już dostępne, akcja mająca na celu promocję silnika

zakończyła się w trakcie trwania wakacji 2015. Podczas jej trwania, każde konto było

uprawnione do użycia dowolnej liczby modeli z szerokiej puli dostępnych jako demo.

Ograniczenie polegało na fakcie, iż całkowita liczba animacji połączonych z modelami nie

mogła przekraczać dwudziestu.

Do stworzenia gry użyto silnika Unity3D, ze względu na jego elastyczność, powszechność

materiałów szkoleniowych oraz przejrzystość dokumentacji.

Jako system rozpoznawania mowy polskiej wykorzystano Sarmatę rozwijanego przez

Zespół Przetwarzania Sygnałów z krakowskiej Akademii Górniczo-Hutniczej[1]

.

Page 14: Implementacja gry komputerowej z interfejsem głosowym

str. 14

4.2. Opis grafiki

Jednym z głównych elementów gry jako rozrywki multimedialnej jest jej grafika. W

trakcie tworzenia komercyjnych gier komputerowych nad ich wyglądem pracują

najczęściej wielkie grupy artystów projektantów grafiki jak i animatorów. W projektach

wielkich serii takich jak Assasins Creed, Call of Duty których kolejne edycje wydawane są

co roku zespoły grafików liczą po kilkadziesiąt osób. W projekcie z racji bycia pracą

inżynierska, a nie komercyjną czy artystyczną skupiono się na aspektach technicznych

czyli głównie programistycznym podejściu do gier komputerowych. Początkowo świat gry

miałby płaski i klinicznie pusty co zwiększało jego czytelność, jednak w miarę dodawania

kolejnych elementów zwłaszcza po uzyskaniu kompletnych modeli odznaczających się

dokładnym detalem uznano, że należy go wypełnić. W tym celu skorzystano w tworzonego

przez społeczność Unity i wspieranego przez twórców sklepu AssetStore na którym można

znaleźć wiele zarówno darmowych jak i płatnych elementów graficznych. Można znaleźć

tam bardzo wiele elementów jednak mimo dużej swobody w dodawaniu poszczególnych

dodatków twórcy zawsze stawiają na spójność świata. Podjęto więć decyzje o stworzeniu

spójnego świata jednak koncepcja musiał być na tyle abstrakcyjna aby móc pozwolić sobie

na dużą dowolność w produkcji.

Świat gry to świat magiczny, co daje możliwość rezygnacji z realizmu i

wiarygodności poszczególnych elementów. W standardowej pozycji kamery gracz widzi

teren aż po sam horyzont w związku z tym początkowo w oczy rzucała mu się płaskość

świata i pustka na używanym wówczas niebie. Postanowiono więc umieścić na mapie niski

ale szeroki las. Drzew skutecznie wypełniły pusty obszar jednak otoczenie nimi całej strefy

wydało się przesadnie nudne, dlatego wypełnił on tylko jeden narożnik. Sam jednak

zielony las w połączeniu z zieloną trawą i niebieskim niebem nie miały w sobie nic

magicznego, więc atmosfera magii w którą chciano wprowadzić gracza nie dala się

poczuć. Ze względu na fakt, iż przy tworzeniu pierwszych pocisków używano gotowych

efektów cząsteczkowych, które dobrze odwzorowywały żywioły, a także dawały poczucie

nie realizmu charakterystycznego dla magicznego świata uznano, że wypełnienie nimi

świata gry będzie dobrym pomysłem. W lesie umieszczono więc emitery kolorowych

promieni, a cały świat pokryto mgłą składającą się z ogromnej ilości cząsteczek, która

wraz ze zredukowanym oświetleniem wprowadziła mroczną atmosferę. Aby domknąć

nierealność lasu umieszczono w nim nienaturalnej wielkości grzyby oraz ogromne

wyschnięte drzewa. Fragment lasu została przedstawiona na ilustracji poniżej.

Page 15: Implementacja gry komputerowej z interfejsem głosowym

str. 15

Na ilustracji poza lasem możemy zauważyć zmieniony teren oraz imitacje czarnego

nieba z fioletowymi gwiazdami. Postanowiono, że naturalne słoneczne oświetlenie nie

pasuje do abstrakcyjnego świata dlatego światło białe zastąpiono fioletowym, a niebieskie

dotychczas niebo czarnym. Pustkę nieba uzupełniono uzyskanymi z AssetStore

elementami uzyskanymi z paczki Vast Outer Space[13]

. Paczka ta zawierała gotowe

przygotowane obiekty będące odwzorowaniem ciał niebieskich. Powiększono je do

ogromnych rozmiarów u umieszczono w odpowiedniej odległości, aby widoczne były na

horyzoncie w trakcie gry. Pozwoliło to wypełnić kolejny pusty narożnik mapy.

Rysunek 4 Screen z gry - Las

Rysunek 5 Screen z gry - Ciała niebieskie

Page 16: Implementacja gry komputerowej z interfejsem głosowym

str. 16

Unity dostarcza bardzo zaawansowane narzędzie do modyfikacji terenu. Działa ono

z wykorzystaniem pędzli. Twórca ma do dyspozycji pędzle służące podnoszeniu i

obniżaniu terenu, wygładzaniu i kolorowaniu, a także dwóm pędzlom służącym stawianiu

drzew oraz traw i kwiatów. Każdy z pędzli może wykorzystywać zaimportowane bądź

narysowane własnoręcznie paczki z elementami. Szczególnie interesujące są jednak dwa

ostatnie pędzle w ich ustawieniach możemy dobrać zakresy losowania parametrów drzew,

pozwala to uzyskać las w którym wszystkie drzewa różnią się od siebie, możemy podać

skale barwienia roślin, sterować ich wyschnięcie, a wreszcie podać zakresy zmienności ich

wysokości i szerokości. Za pomocą dwóch paczek Fantasy Forest[14]

oraz Painterly

Nature[15]

udało się uzyskać gotowy las, a także trawy i krzaki znajdujące się na terenie

mapy. Tekstura terenu jest stylizowana na popularne w grach motywy pustkowia. Dzięki

pędzlowi służącemu do zmiany wysokości terenu stworzono wzgórze, w którym w celu

urozmaicenia osadzono drzewo.

Fioletowe oświetlenie, mgła oraz czarnofioletowy skybox stworzyły atmosferę

magicznego surrealistycznego świata zostały dopełnione nienaturalnymi drzewami oraz

różnobarwnymi trawami i drzewami, a także ogromnymi planetami. Całość wygląda jest

dosyć spójną magiczną kompozycją, a wraz z dynamicznym oświetleniem dostarczanym

przez Unity oraz efektami cząsteczkowymi tworzy dynamiczny świat z dosyć płynną

akcją.

Rysunek 6 Screen z gry - wzgórze

Page 17: Implementacja gry komputerowej z interfejsem głosowym

str. 17

4.3. Implementacja SARMATY

Kluczowym elementem pracy, było skorzystanie z funkcjonalności Sarmaty – systemu

rozpoznawania mowy polskiej. W zamyśle, za pomocą interfejsu głosowego gracz mógł

wywoływać kolejne zaklęcia, które składały się z dwóch członów: żywiołu oraz kształtu.

W wyniku rozpoznania komendy, bohater gracza zaczyna dysponować odpowiednią

magią. Dodatkowo wprowadzono komendę ataku, pozwalającą wydawać polecenie szarży

pomocnikowi minotaurowi.

Implementacja interfejsu Sarmaty miała zostać napisana przy wykorzystaniu otrzymanej

od zespołu DSP biblioteki klienta skompilowanej w zgodności z platformą .NET. Unity od

wersji 5.0 pozwala na wykorzystanie bibliotek zewnętrznych jako zarządzalnych w wersji

darmowej silnika, dzięki temu implementacja miała być bardzo łatwa, a kod miał być

kompilowany w Unity razem z grą. Podczas importowania biblioteki pojawił się jednak

problem związany z wersją platformy .Net. Silnik ogranicza użycie bibliotek .Net do

wersji 2.0, niestety otrzymana biblioteka mimo iż jest skompilowana w zgodności z

odpowiednią wersją wykorzystuje podczas działania nowszą wersje przez co Unity

rozpoznaje ją jako natywną i nie pozwala na jej swobodne wykorzystanie. Możliwym jest

zawołanie metod natomiast nie jest możliwe korzystanie z klas, tworzenie instancji i

wykorzystanie typów zawartych w bibliotece.

Z tego powodu zdecydowano się na rozwiązanie mniej eleganckie, ale dające możliwość

spełnienia założeń projektu. Stworzono samodzielny program obsługujący sesję Sarmaty,

który gdy zachodzi potrzeba jest uruchamiany. Jest w pełni konfigurowalny w

podstawowym zakresie przez plik zawierający ścieżki do nagranego głosu oraz gramatyki.

Podając ścieżki należy pamiętać, iż nie są one bezwzględne – domyślnie przeszukiwany

jest katalog zawierający plik wykonywalny Sarmaty.

Gramatyka zawiera nagłówek ANBF[17]

(Augmented Backus–Naur Form) w wersji 1.0,

który zawiera informację o jej języku, używanym trybie oraz wskazanie na korzeń

tworzonego drzewa.

#ABNF 1.0;

language pl;

mode voice;

root $czar;

Następnie zgodnie ze standardem ANBF następuje wskazanie kolejnych oczekiwanych

słów wraz z ich logicznym połączeniem. Znak dolara oznacza zdeklarowanie zmiennej

nazwanych w tym formacie zasadami (ang. rule), których definicja odbywa się przez

dwuargumentowy znak równości. Znak alternatywy pozwala na stworzenie listy słów, z

których wybrane zostanie tylko jedno. Znaki nawiasów kwadratowych zostały użyte aby

Page 18: Implementacja gry komputerowej z interfejsem głosowym

str. 18

wskazać, które części tworzonego poprzez kolejne referencje do zasad drzewa są uznane

jako alternatywne. Każda z linii zakończona jest przez średnik.

$czar = $prefix [$postfix] | $atak;

Oznacza iż wypowiedziana przez gracza fraza, która została przesłana do rozpoznania

będzie zawierać czar składający się z obowiązkowego z prefixu oraz opcjonalnego

postfixu albo pojedynczą komendę ataku. Opcjonalność prefixu została jednak pominięta i

moduł decyzyjny gry wymaga obu słów podczas wyboru zaklęcia.

Właściwy program interfejsu Sarmaty po uruchomieniu przechodzi do wspomnianego już

pliku konfiguracyjnego, pobierając z niego nazwy i ścieżki plików zawierających nagrany

dźwięk oraz gramatykę. Następnie korzystając z konstruktora klasy RemoteSession

odpowiedzialnej za nawiązanie i utrzymanie sesji z serwerem, przyjmującego jako

argument string w formacie adres_IP:port tworzone jest połączenie. Jeśli z jakiś powodów

proces ten zakończył się niepowodzeniem zostanie wykorzystany mechanizm obsługi

wyjątków, który wypisze na standardowym wyjściu odpowiedni komunikat błędu.

Następnie wczytywana jest gramatyka poprzez metodę wczytajGramatyke, według ścieżki

podanej w pliku konfiguracyjnym. Następnie poprzez metody klasy RemoteSession

kolejno przekazywana jest do sesji (SetGrammar) oraz ustanawiana jest sama sesja

(StartSession).

Kluczowym elementem algorytmu jest zastosowanie delegata, czyli wywodzącej się z C++

idei wskaźnika na funkcję/metodę, która w C# została rozwinięta o bezpieczeństwo

zwracanego typu oraz możliwość zwracania również obiektów. Ograniczeniem delegatów,

jest przymus wskazywania na metody zwracające oraz przyjmujące jako argumenty

jednolite typy. Delegatem zastosowanym w dynamicznie linkowanej bibliotece jest

OnASREventDlg, który jako argument przyjmuje metodę obsługującą zdarzenia. Taką

metodą jest target z klasy Program przyjmującą jako argument obiekt klasy

ASREventArgs dziedziczącej z EventArgs czyli klasy bazowej .Net zawierającej

informacje o zdarzeniu. Metodę target należy również dodać do listy przerwań instancji

klasy RemoteSession – OnEvent. Gdy interfejs Sarmaty otrzyma odpowiedz na żądanie,

wykonywane jest zaplanowane zdarzenie – w tym wypadku metoda target, która w

zależności od otrzymanego jako argument typu wyliczeniowego EventType wypisuje na

standardowym wyjściu odpowiednio rozpoznane słowo lub błąd wraz z jego kodem.

Rozpoznana fraza przekazywana jest również przez obiekt klasy ASREventArgs, a

mianowicie jego pole Phrases[0].RecognizedWords;

Następnym krokiem jest załadowanie gotowego nagrania głosowego w formacie wave

próbkowanego z częstotliwością 16 kHz, opisanego na 16 bitach, posiadający tylko jeden

kanał mono. Format wave opiera się w wersji podstawowej na nagłówku o długości 40

bajtów oraz ciągu niezakodowanych próbek. Do programu wczytywany jest sam ciąg liczb

reprezentujących dźwięk, z pominięciem nagłówka. Mając pewność, iż nagranie jest w

pełni skończone wywoływane są kolejno metody ProcessSamples obiektu klasy

RemoteSession przyjmująca jako argument wektor próbek w formacie short, która

Page 19: Implementacja gry komputerowej z interfejsem głosowym

str. 19

odpowiedzialna jest za wysłanie ciągu próbek na adres serwera Sarmaty wraz z poleceniem

rozpoczęcia procesu rozpoznawania mowy oraz bezargumentowa metoda Flush obiektu tej

samej klasy, która informuje system dopasowujący, iż wszystkie próbki zostały

rozpoznane i interfejs oczekuje na jak najszybszą odpowiedź.

Aby połączyć stworzony interfejs Sarmaty z grą implementowaną w Unity3D stworzono

funkcjonalności oparte na klasie skryptMikrofonu. W metodzie start, uruchamianej przy

stworzeniu instancji danej klasy przeprowadzana jest detekcja urządzenia

przetwarzającego głos. Odbywa się to z wykorzystaniem klasy Microphone, która

automatycznie sprawdza podłączone urządzenia. Jeśli choć jedno zostaje znalezione

częstotliwość jego próbkowania jest ustawiana na 16 kHz oraz definiowany jest obiekt

klasy AudioSource jako właśnie mikrofon. Po wykryciu wciśnięcia klawisza

odpowiedzialnego za rozpoczęcie sekwencji wydawania polecenia, rozpoczynane jest

nagrywanie próbek, trwające 2 sekundy. Proces ten odbywa się w Coroutine. Po

zakończeniu nagrywania następuje zapis do pliku. Aby uzyskać pożądany format

wykorzystano gotowy kod napisany przez Calvina Riena[16]

. Tworzy on zarówno nagłówek

zgodny ze standardem wave o długości 44 bajtów, wycina fragmenty ciszy aby zmniejszyć

rozmiar pliku oraz co najważniejsze dokonuje konwersji z próbek typu float do 16

bitowych.

Algorytm zamiany polega na przemnożeniu każdej próbki przez stałą równą 32767 i

rzutowaniu typu wyniku na short. Reprezentacja obiektu 16 bitowego realizowana jest za

pomocą tablicy dwóch bajtów. Za konwersję z liczby typu short na 16 bit odpowiada klasa

BitConverter oraz jej metoda GetBytes.

Za uruchomienie interfejsu sarmaty w nowym procesie odpowiedzialna jest klasa

System.Diagnostics.Process. Po ustawieni szeregu flag informujących o sposobie

wywołania procesu oraz jego reprezentacji graficznej uruchamiana jest kluczowa metoda

start(), która zapoczątkowuje wykonywanie algorytmu.

Oczekiwanie na wyniki zostało zaimplementowane jako Coroutine, w której po jednej

sekundzie uruchamiana jest metoda czekajNaSarmate(). Jeśli spełnione są odpowiednie

warunki, tj. interfejs Sarmaty został uruchomiony poprawnie, sczytywane są wszystkie

dane wyświetlone na jego wyjściu standardowym. Na podstawie tych informacji

podejmowana jest decyzja i ustawiany odpowiedni typ i kształt czaru. Realizuje to metoda

podejmijDecyzje, która jest zbiorem instrukcji warunkowych.

4.4 Opis elementów

4.4.1. Gracz

Model postaci jest reprezentacją wirtualnego awatara gracza. Poprzez odpowiednio

skonfigurowane interfejsy człowiek uzyskuje możliwość jej kontroli w pewnych

zakresach. Postacią gracza jest czarodziej pozyskany z zasobów systemu Mixamo

należącego do Adobe.

Page 20: Implementacja gry komputerowej z interfejsem głosowym

str. 20

Gracz na scenie jest reprezentowany przez obiekt klasy GameObject. Zawiera on

podstawowe algorytmy, pozwalające na poruszanie się w trójwymiarowym świecie.

Posiada on szereg komponentów, które zostały zastosowane również w innych elementach

gry. Podstawowym komponentem jest Transform, przechowuje on współrzędne gracza

oraz posiada metody pozwalające na przemieszczanie obiektu w przestrzeni. Ważnym i

również wykorzystywany w prawie każdym ruchomym obiekcie sceny komponentem jest

instancja RigidBody. Jest to kolejna klasa Unity która odpowiada za podstawy fizyki.

RigidBody posiada metody odpowiedzialne za dodawanie siły jak również wykrywanie

kolizji. Klasy te są dokładnie opisane w dokumentacji Unity3D. Do obiektu załączone są

również autorskie klasy odpowiadające za ruch oraz strzelanie.

Klasa ruch jest odpowiedzialna za poruszanie się postaci. Za pomocą klasy Input

reprezentującej wbudowany menadżer wejścia ze środowiska Unity3D, zrealizowane jest

pobieranie przycisków z klawiatury, które następnie przetwarzanie są na pożądany

kierunek ruchu postaci. Sterowanie odbywa się poprzez wciskanie klawiszy WSAD.

Input Manager interpretuje wciśniecie klawisza przekładając go odpowiednio na dodatnie

lub ujemne wartości z przedziału [-1:1] w zależności od ustawień kierunków osi np. oś

horyzontalna ma przypisane klawisze A oraz D gdzie wciśnięcie A zmniejsza wartość, a

wciśniecie D zwiększa, poruszanie się po wartościach zmiennoprzecinkowych pomaga

uzyskać większą precyzje sterowania. Detekcja wciśnięcia następuje dzięki metodzie

GetKey z klasy Input, która jako argument może otrzymać zarówno string odpowiadający

danemu klawiszowi jak i odpowiedni typ wyliczeniowy. Jednak samo uzyskanie wartości

w celu określenia kierunku ruchu obywa się przy pomocy metody GetAxis z klasy Input

która jako argument przyjmuje string z określeniem wczytywanej płaszczyzny. W tym

przypadku są to osie „Horizontal” dla ruchu na boki oraz „Vertical” dla ruchu do przodu i

do tyłu. Gracz porusza się wzdłuż osi X oraz Z. Za pomocą myszki uzyskuje się

możliwość obracania postaci wokół osi Y. Realizacją tej operacji w kodzie zajmuje się

również metoda GetAxis przyjmując jako argument „Mouse X”. Wartości wejścia

sprawdzane są w funkcji Update() czyli co każdą kolejną klatkę.

Rysunek 7 Gracz

Page 21: Implementacja gry komputerowej z interfejsem głosowym

str. 21

Wartości zmiennoprzecinkowe pobierane z osi poziomej i pionowej są również używane

do łączenia animacji w wbudowanym w Unity narzędziu do łączenia animacji. Sam

animator gracza jest również bardzo złożony. Animacje ruchu są dostarczane z BlendTree,

jednak samo narzędzie działa tylko w momencie ustawienia zmiennej „move” poprzez

naciśnięcia przycisku ruchu z poziomu klasy odpowiedzialnej za ruch. Animator gracza

jest dwuwarstwowy. Na jednej warstwie odbywają się animacje ruchu, a na drugiej

uruchamiane jest każdorazowo animacja rzucania zaklęcia. Animacje pomiędzy

warstwami są łączone za pomocą suwaków w edytorze. Pozwala to uzyskać w pełni

animowaną postać korzystając jedynie z pojedynczych animacji będących reprezentacją

jednej czynności.

Rysunek 8 BlendTree odpowiedzialne za animacje ruchu gracza

Klasa odpowiedzialna za rzucanie zaklęć jest podobnie jak ruch klasą behawioralną opartą

o metodę Update(), a więc wykonującą się co klatkę. Sprawdzane jest wciśnięcie lewego

przycisku myszki, a kiedy ono nastąpi wywoływana jest metoda quasi-współbieżna

shootingEvent()[19]

uruchamiająca procedurę strzału. Metoda ta ustawia zmienna w

animatorze wybierając jedną z dwóch dostępnych animacji strzału i czeka 0.6s, aż

animacja postaci dotrze do miejsca kiedy ręce czarodzieja są gotowe do wystrzału, wtedy

wywoływana jest metoda shoot() odpowiedzialna za instancjonowanie pocisku.

Instancjonowanie pocisku gracza odbywa się za pomocą wbudowanej w edytor metody

Instantiate()[18]

służącej do instancjonowania obiektów. Za pomocą tej metody tworzony

jest obiekt z uprzednio przygotowanego elementu pocisku. Sam pocisk został opisany w

podrozdziale czary.

Page 22: Implementacja gry komputerowej z interfejsem głosowym

str. 22

W metodzie Update() klasy odpowiedzialnej za strzelanie znajduję się również kod

odpowiedzialny za zaznaczanie celów dla Chowańca - minotaura. Zaznaczenie celu

odbywa się poprzez wypuszczenie promienia równoległego do kierunku wzroku maga,

zaznaczony zostaje więc cel którego komponent Collider zostanie przecięty promieniem.

Promień jest instancjonowany metodą Instantiate(), gdy cel zostanie zaznaczony referencja

do jego obiektu na scenie zostanie przekazana do minotaura, który będzie oczekiwał na

rozkaz ataku.

4.4.2. GameMaster

Założenia gry przedstawionej w pracy inżynierskiej opierają się na kolejnych falach

atakujących potworów. Realizacja rozwiązania tego problemu odbywa się za pomocą tzw.

„spawnera” czyli obiekt typu GameObject. Element mimo tego, że znajduje się na scenie

nie jest widzialny dla gracza. Odpowiada za utrzymywanie stałej liczby przeciwników

zależnej od aktualnego poziomu.

Po stworzeniu obiektu klasy GameMaster na scenie pojawia się zadana ilość potworów.

Można ją kontrolować poprzez podanie jako argument komponentu. W każdej klatce gry

sprawdzana jest ilość przeciwników danego typu. Jeśli jest mniejsza niż maksymalna

tworzony jest nowy wróg i umieszczany na planszy. Pozycja nowego przeciwnika jest

losowana. Podczas uzupełniania puli, jeśli nowa pozycja znajduje się zbyt blisko punktu

docelowego, następuje przesunięcie o wektor o długości zadanej jako minimalna

odległość.

GameMaster odpowiada jednak nie tylko za tworzenie określonej liczby wrogów.

Przechowuje również podstawowe informacje o aktualnym postępie gracza wynik

punktowy oraz aktualny poziom. Gracz zdobywa punkty zabijając wrogów. Jako, że

podstawowym celem gry jest utrzymanie się jak najdłużej przy życiu realizacja tego celu

jest premiowana. Co minutę wzrasta poziom, a wraz z nim wzrasta ilość otrzymywanych

przez gracza punktów. Podstawowe wartości punktowe otrzymywane za każdego z

wrogów są mnożone przez aktualny poziom. Gra z czasem staje się jednak coraz

trudniejsza z każdą minutą wzrastają maksymalne progi zadanej ilości potworów. Z

każdym poziomem w grze przybywa po jednym barbarzyńcy i mutancie oraz co drugi

poziom jednym demonie.

Klasa GameMaster zawiera również metodę odpowiadającą za resetowanie gry metoda ta

wyszukuje wszystkich wrogów w grze i zabija ich, wyszukuje również gracza którego

przestawia w miejsce startu przywracając mu podstawowe wartości życia oraz resetuje

poziom i wynik punktowy. Metoda ta znajduje zastosowanie w menu głównym przy

starcie nowej gry.

4.4.3. Capzone

Page 23: Implementacja gry komputerowej z interfejsem głosowym

str. 23

Capzone to kluczowy z punktu widzenia gracza obszar na mapie. Głównym zadaniem

maga jest obrona strefy od której zależy jego życie. Strefa znajduję się w centralnej części

mapy i jest również miejsce w którym gracz rozpoczyna swoje zmagania. Jej graficzną

reprezentacją jest fioletowa półsfera stworzona jako efekt cząsteczkowy dzięki czemu

wygląda jakby była animowanym polem siłowym zgodnie z założeniem gry. Zadaniem

zarówno barbarzyńców jak i mutantów jest dotarcie do strefy, gdzie są one niszczone przez

pole siłowe, ale w wyniku zderzenie z nim graczowi odbierana jest cząstka życia. Z punktu

widzenia kodu odbywa się to w klasie Destroyer przypisanej jako komponent do obiektu

Capzone znajdującego się na scenie. Klasa Destroyer zawiera referencje do obiektu gracza.

Referencja do obiektu gracza jest przypisana w celu czysto wydajnościowym. Zamiast

przechowywać referencje można w razie konieczności wyszukać obiekt za pomocą funkcji

FindObjectOfType<>() jednak ta funkcja powoduje spadki wydajności co w przypadku

grafiki 3D jest bardzo niekorzystne zwłaszcza jeżeli ta funkcja miałaby być wywołana przy

każdym kontakcie wroga z półsferą. Obiekt Capzone zawiera komponent Collider w

kształcie sfery, połowa z niej znajduję się jednak pod powierzchnią terenu, jest więc

pomijalna, Istotna pół sfera znajduję się nad powierzchnią i pokrywa się z graficzną

reprezentacją pola siłowego. Komponent ma ustawioną flagę isTrigger, oznacza to, że z

punktu widzenia fizyki obiekt jest przeźroczysty. Collider obiektu Capzone jest związany z

klasą Destroyer która posiada metodę edytora Unity - OnTriggerEnter(). Mimo

transparentności kolizje obiektu z obiektami kolidujących warstw są rejestrowane. Jeżeli

obiekt wchodzący w strefę, pochodzi z warstwy reagującej z warstwą obiektu Capzone ( co

zależy od ustawień fizyki w Unity przedstawiony na poniższym diagramie), metoda jest

wywoływana.

Capzone znajduje się na warstwie Capzone, a wrogowie na warstwie Enemy – jak widać

zachodzi między nimi reakcja, a więc za każdym razem gdy wróg wejdzie w strefę

uruchamiany jest kod znajdująca się w ciele metody. Sprawdzane jest słowo kluczowe

przypisane do obiektu wchodzącego w kolizje, jeżeli jest nim "Enemy" na obiekcie gracza

przez referencje wyszukiwany jest (za pomocą GetComponent<>()) komponent LifeTime

Page 24: Implementacja gry komputerowej z interfejsem głosowym

str. 24

przypisany do gracza, a wtedy wywoływana jest na nim metoda Hit() z argumentem

równym obrażeniom zadawanym graczowi. Z punktu widzenia demo jest to 10 docelowo

jednak wartość ta może być zmieniona na przykład przypisana do każdego z wrogów.

Następnie GameObject wroga jest niszczony, co jest równoznaczne ze zniszczeniem

całego obiektu.

Poza graficzną reprezentacją pola siłowego Capzone posiada jeszcze dwa dodatkowe

efekty cząsteczkowe, słup światła opadający na środek strefy oraz drobne cząsteczki

emitowane ze szczytu kopuły. Efekty te mają na celu umożliwienie zlokalizowania strefy

przez gracza z dużej odległości w sytuacji gdy się od niego oddali.

Capzone jest elementem skończonym możliwym do przeniesienie i zaadaptowania na

każdej możliwej arenie walki. Jest on także dobrym przykładem wykorzystania emulacji

fizyki zawartej w Unity3D.

4.4.4. Magia

Podstawowym narzędziem walki każdego czarodzieje jest magia. Gracz w walce z

przeciwnikami posiada szeroki zasób zaklęć zmienianych jak zostało wspomniane

wcześniej poprzez interfejs głosowy. Wystrzeliwaniem magicznych pocisków zajmuje się

opisany w dziale gracz komponent odpowiedzialny za strzelanie. Przechowuje on także

referencje do instancjonowanego wzorca pocisku który ustawiany jest za pomocą innego

komponentu. Tym komponentem jest klasa zmienCzar. W tej klasie znajdują się dwa

obiekty typów wyliczeniowych, zawierające odpowiednio typ czaru oraz jego żywioł.

Klasa zawiera również listę przygotowanych wzorców poszczególnych pocisków

magicznych zmienianych, wybór i instancjonowanie odpowiedniego wzorca odbywa się

poprzez zawartą w klasie metody. Zmienna używanego zaklęcia jest inicjowana poprzez

użycie klienta rozpoznawania mowy. Po poprawnym rozpoznaniu wywoływana jest

metoda zmieniająca czar na podstawie instrukcji warunkowych co zostało opisane przy

okazji opisu implementacji sarmaty. Po stworzeniu wybranego wzorca wykonywana

ustawiany jest licznik dostępnych użyć czarów, a także wywoływana jest kolejna z metod.

Metoda ta przyjmuje jako argument GameObject reprezentujący instancjonowany czar.

Służy ona przeładowaniu czaru, niszczy stary wzorzec, przypisuje nową instancje do

hierarchii gracza, ustawiając Transform gracza rodzicem zaklęcia. Deaktywuje również

obiekt (aby zatrzymać wykonywanie akcji na wzorcu), nadpisuje też referencje wzorca.

Poniższa tabela przedstawia dostępne zaklęcia – ich nazwy są równoznaczne z

koniecznymi do wypowiedzenia słowami.

Page 25: Implementacja gry komputerowej z interfejsem głosowym

str. 25

Nazwa: Kula Magii Kula Ognia Wybuch Ognia Kula Lodu Wybuch Magii

Obrażenia: 20 20 50 30 50

Zasięg: 1 1 12 1 7

Ilość użyć: 7 6 3 5 4

W tabeli przedstawiono nazwy, a także poszczególne szczególne parametry każdego z

czarów takie jak obrażenia zadawane wrogom. Zasięg jest istotny tylko w przypadku

zaklęć obszarowych, jedynka oznacza, że zaklęcia atakuje tylko pojedynczy cel. Ilość użyć

to ilość możliwych do oddania strzałów od zmiany zaklęcia. Wprowadzenie takiego

mechanizmu ma na celu wymuszenie na graczu zmianę, a co z tym idzie skorzystanie z

interfejsu głosowego.

Każdy z dostępnych czarów jest przygotowanym według określonego schematu obiektem.

Indywidualne parametry zaklęć są ustawione ręcznie w panelu inspektora. Obiekty

zawierają również specjalne komponenty wspólne dla wszystkich zaklęć. Kluczową klasą

jest klasa Ammo zawierającą takie zmienne jak zadawane obrażenia, czas życia oraz flaga

dwustanowa która służy oznaczeniu czy zaklęcie jest obszarowe czy atakuje pojedynczy

cel. Klasa Ammo poza metodą Update() opisywaną wielokrotnie posiada jeszcze dwie

wbudowane metody edytora Unity. Pierwsza z nich to OnTriggerEnter() jest ona

wywoływana w momencie kolizji dowolnego obiektu z obiektem posiadającym

komponent z tą metodą. Jako argument przyjmuje ona obiekt klasy Collider będący

komponentem obiektu wchodzącego w kolizje z obiektem na którym wywoływana jest

metoda. Kolizje są rozpoznawane pomiędzy obiektami w zależności od ustawień fizyki w

edytorze. Unity pozwala na ustawienia warstw pomiędzy którymi mają zachodzić kolizje.

Pociski wystrzeliwane przez maga mają ustawione w komponencie Collider flagę isTrigger

oznacza tą, że z punktu widzenia fizyki są one przeźroczyste, natomiast sam komponent

pozwala na wykrycie przenikania się obiektów fizycznych. Metoda OnTriggerEnter() ta w

momencie wywołania instancjonuje efekt cząsteczkowy będący oznaka reakcji pocisku na

kolizje, a także za pomocą metody GetComponent edytora Unity wyszukuje na

wywołującym metodę OnTriggerEnter() obiekcie czyli wrogu komponent LifeTime na

którym wywołuje metodę Hit opisana w dziale wrogowie. Metoda ta za argument

przyjmuje obrażenia mające być zadane wrogowi przez zaklęcie. Jeżeli jednak pocisk jest

obszarowy obrażenia zadawane w tym momencie są równe zero, ponieważ są one

zadawane w kolejnym kroku wszystkim wrogom w zasięgu. Niszczony jest także pocisk.

Drugą metodą jest OnDestroy() metoda ta jest wywoływana w momencie rozpoczęcia się

niszczenia obiektu, a jest faktycznym zniszczeniem. Jest ona używana do zadawania

obrażeń w przypadku zaklęć obszarowych. Ich wzorce posiadają jednak dodatkowy

komponent, klasę odpowiedzialna za znalezienie wrogów w obszarze rażenia. Klasa

znajduję wszystkich wrogów na scenie, następnie sprawdza czy ich odległość od danego

punktu jest mniejsza od zadanego promienia, jeżeli tak jest są oni dodawani do listy

Page 26: Implementacja gry komputerowej z interfejsem głosowym

str. 26

wykorzystywanej między innymi przez amunicje. W tym przypadku metoda Hit() jest

wywoływana na wszystkich wrograch znajdujących się w zasięgu.

Jako grafiki pocisków wykorzystywane są efekty cząsteczkowe, pobrane z AssetStore.

Efekty cząsteczkowe są dobrą reprezentacją żywiołów, ze względu na ich płynną

wbudowaną animacje. Emisja niewielkich cząsteczek może emitować ogień czy śnieg.

Gotowe, pobrane ze sklepu Unity efekty są złożeniem kilku odpowiednio połączonych

emiterów cząsteczek jak również odpowiedniej operacji światłem.

Magia jest jednym z kluczowych elementów gry, dlatego działanie czarów, różnice między

nimi, oraz ich wygląd wymagają bardzo dużego nakładu pracy. Komponenty oraz

hierarchia wzorców poszczególnych pocisków są przygotowane w taki sposób, aby

dodawanie kolejnych nowych zaklęć było łatwe i odbywało się poprzez duplikowanie

gotowych wzorców, zmianę parametrów, efektu cząsteczkowego oraz oświetlenia.

Pozwala to na szybką produkcję zawartości i rozwój gry w kierunku zamkniętego

produktu.

4.4.5. Minotaur

Koncepcja minotaura została wprowadzona w celu poszerzenia funkcjonalności gry o

nowe elementy sterowania głosowego. Sterowany jest on za pomocą komendy głosowej

będącej alternatywą do sposobu rzucania czarów. Po poprawnym wykryciu polecenia

ataku i uprzednim oznaczeniu celu, minotaur rusza w kierunku przeciwnika. Po

znalezieniu się w zasięgu ataku cel zaczyna tracić punkty życia. W standardowym trybie

minotaur podąża za graczem czekając na jego rozkaz. Model minotaura został pobrany z

Asset Store Unity wraz z kompletem animacji.

Klasa opisująca logikę minotaura nazwana została zachowanieMinotaura. Zawiera metody

odpowiedzialne za podążanie za celem. Główną metodą, wywoływaną co klatkę jest

update. Zarządza ona stanami zbioru flag, odlicza czas potrzebny do wywoływania

animacji czy zadawania obrażeń oraz po uprzednim przygotowaniu wyżej opisanych

elementów, wywołuje metody z właściwą funkcjonalnością.

Pierwsza z nich to follow - metoda typu void, nie przyjmująca żadnych argumentów,

odpowiedzialna za przeprowadzenie odpowiednich akcji na aktualnym celu. Jeśli została

wydana komenda, ustawiona jest flaga mówiąca czy ostatni atak został przeprowadzony w

zadanym okresie czasu oraz minotaur znajduje się wystarczająco blisko celu wykonywany

jest cios. Polega on na zdaniu obrażeń celowi, wylosowaniu jednej z trzech dostępnych

animacji oraz jej odtworzeniu.

W przypadku gdy minotaur znajduje się zbyt daleko od swojego celu ruszy w jego

kierunku po prostej przecinającej jego położenie oraz położenie przeciwnika. Jeśli

minotaur w danym momencie nie zadaje ciosów może wejść w tryb podążania lub

spoczynku. W każdym z nich odgrywana jest odpowiednia animacja.

Page 27: Implementacja gry komputerowej z interfejsem głosowym

str. 27

Klasa posiada również dwie metody pomocnicze – shouldFollow, która nie przyjmuje

żadnych argumentów i decyduje czy minotaur jest w stanie spoczynku, czy podąża za

celem oraz posToRadius, czyli metodę która oblicza odległość w przestrzeni

dwuwymiarowej minotaura od przekazanych w argumentach współrzędnych.

4.4.6 Przeciwnicy

Zadaniem przeciwników jest dotarcie do obszaru, którego broni gracz. Za utrzymanie ich

liczby jest odpowiedzialny spawner. Ich modele wraz z animacjami pozyskano z systemu

Mixamo firmy Adobe. Zostały wyróżnione trzy odmienne typy wrogów, których

podzielono na dwie klasy w zależności od pełnionej przez siebie roli. Pierwsza z nich

opiera się na zdolności samodzielnego ataku na broniony przez gracza obszar. Przeciwnicy

tej kategorii są wytrzymali, ale poruszają się w przewidywalny, liniowy sposób.

Każdorazowo po osiągnięciu przez przeciwnika celu gracz traci ustaloną ilość punktów

życia. Drugim typem jest kategoria wspomagająca, która dzięki nieliniowemu sposobowi

poruszania oraz zaklęciom wspomagającym jego towarzyszy staje się trudnym do

pokonania oponentem. Postacie wspomagające nie mają możliwości przejścia do

bronionego obszaru, jedynie zbliżają do jego granic swoją pozycje. Każdy z przeciwników

poza klasą odpowiadającą za ich zachowanie zawiera również komponent klasy LifeTime

będący reprezentacją cyklu życia wszystkich obiektów możliwych do zniszczenia.

Instancję klasy LifeTime zawiera również obiekt gracza, ponieważ gracz również posiada

punkty życia i otrzymuje obrażenia za pomocą wywoływania tych samych metod, jednakże

przez klasę capzone, a nie jak w przypadku wrogów przez kolizje z amunicją. Klasa ta

przechowuje parametry związane z życiem obiektów możliwych do zniszczenia. Zawiera

również referencje do paska życia czy animatora obiektu macierzystego. Referencje te są

konieczne, ponieważ obiekty do których się odnoszą są wykorzystywane w metodach

znajdujących się w klasie. W animatorze ustawiana jest wartość flagi „Hit” mającej w

przypadku gdy postać posiada animację obrazującą reakcje na otrzymane obrażenia

odtworzyć ją. Pasek życia gracza jest widoczny na interfejsie jest również uaktualniany

instancję tej klasy będącą komponentem gracza. Takie rozwiązanie pozwoli w przyszłości

na dodatnie pasków życia również wrogom. Klasa LifeTime posiada dwie autorskie

metody oraz dwie standardowe opisywane wielokrotnie Start() i Update(). Pierwszą

metodą jest Kill() wywoływana automatycznie w Update() kiedy spełniony jest

odpowiedni warunek. Jest nim sprawdzenie punktów życia obiektu, jeżeli ich liczba jest

mniejsza niż zero jednostka jest zabijana. Zabicie odbywa się w następującej kolejności

ustawiana jest flaga oznaczająca że obiekt jest martwy, tworzony jest efekt cząsteczkowy

będący oznaką śmierci jednostki, następnie w przypadku wrogów dodawana jest do

wyniku odpowiednia dla każdego z nich wartość punktowa przemnożona przez aktualny

poziom, a sam obiekt zostaje przeznaczony do zniszczenia. Aby jednak punkty życia

zostały zredukowane konieczna jest metoda odejmująca je. Tą metodą jest Hit()

wywoływana każdorazowo przez klasę Ammo w wypadku kolizji pocisku gracza z

komponentem Collider wroga bądź w razie konieczności gdy wróg znajduje się w obszarze

rażenia pocisku obszarowego.

Page 28: Implementacja gry komputerowej z interfejsem głosowym

str. 28

Barbarzyńca i mutant

Są to postacie czysto ofensywne, których jedynym celem jest bieg na przód. Barbarzyńca

jest dużo mniej wytrzymały względem mutanta, za jego zabicie graczowi przyznawane jest

tylko 10 punktów (mutant dostarcza ich aż 20), jednak występuje trzykrotnie częściej. Po

stworzeniu przez spawner postaci, automatycznie ustawiana jest ona przodem do punktu

docelowego, do którego biegnie w linii prostej.

Page 29: Implementacja gry komputerowej z interfejsem głosowym

str. 29

Page 30: Implementacja gry komputerowej z interfejsem głosowym

str. 30

Demon

Przeciwnik demon powstał z myślą o postaci wspomagającej, która nie brała by czynnego

udziału w walce, czy utracie przez gracza punktów życia. Wspiera on swoich sojuszników

za pomocą magii oraz unika pozostawania zbyt długo w jednym miejscu, poruszając się

nie liniowo. Może rzucić on obszarowe zaklęcie, zwiększając szybkość każdego

barbarzyńcy w zadanym promieniu.

O czasie trwania przyspieszenia decyduje publiczna zmienna buffTime, która standardowo

ustawiona jest na 1 sekundę, zaś o promieniu publiczna zmienna typu float zasięg

znajdująca się w klasie pomocniczej znajdzObszar, ustawiona na 10. Kluczowa jest tutaj

metoda randAndCheckTimeToTP, przyjmująca jako argumenty początek oraz koniec

przedziału, z którego będą losowane liczby, odpowiadające za czas pozostania demona w

określonym miejscu. Gdy ciągle dekrementujący się licznik osiągnie wartość zero oraz

uprzednio został wylosowany czas (który właśnie upłynął) metoda zwróci flagę,

informującą algorytm iż po zakończeniu aktualnej akcji należy wykonać operację

teleportacji. Za natychmiastowe przemieszczenie odpowiedzialna jest metoda nie

zwracająca typu performTP. Losuje ona nową pozycję tak długo, aż znajdzie taką, która

jest bliżej punktu bronionego przez gracza niż aktualna. Wykonywana jest wtedy animacja

teleportacji oraz samo przemieszczenie modelu. Po jej zakończeniu, odtwarzana jest druga

część animacji, która kończy proces. Algorytm, jeśli uzna iż w danym momencie nie

odbywa się inna akcja, będzie ciągle rzucał czar wspomagający.

Page 31: Implementacja gry komputerowej z interfejsem głosowym

str. 31

W klasie znajdzObszar zawarta jest funkcjonalność wyszukiwania wrogów w danym

obszarze. Każdy z oponentów oznaczony jest specjalnym słowem kluczowym „Enemy”.

Klasa ta, od momentu stworzenia co klatkę odświeża i przechowuje listę wszystkich

dostępnych postaci z tej kategorii. Jeśli zostanie wywołana metoda znajdzWrogow, która

w argumencie otrzymuje promień wyszukiwania, którego centrum jest obiekt ją

wywołujący – lista wrogów zostanie przejrzana, sprawdzając kolejno czy ich położenie

spełnia założenia. Jeśli tak, zostają dodani do specjalnej publicznej listy o nazwie

wrogowieZasieg. Używając referencji do niej, inne klasy mogą wykonywać operacje na

wszystkich przeciwnikach w niej zawartych, np. zwiększając ich szybkość.

4.4.7. Interfejs użytkownika.

Interfejs użytkownika jest wzorowany na standardzie stosowanym w wielu grach

komputerowych. Z względu na fakt, że jest to demo gry mające na celu prezentacje

określonego elementu, a więc zastosowanie rozpoznawania mowy w grze to menu

zarówno menu główne jak i menu pauzy są stworzone z podstawowych elementów

dostępnych w edytorze. Tworzenie interfejsów użytkownika z punktu widzenia

oprogramowania w Unity3d jest bardzo proste ze względu na fakt iż każdemu elementowi

interfejsu odpowiadają klasy takie jak „Button” czy „Image”. Jednak jest również bardzo

czasochłonne, ponieważ wymaga umiejętności projektowania grafiki oraz zdolności

artystycznych. Dostępne w Internecie gotowe paczki z elementami graficznego interfejsu

użytkownika są zazwyczaj nieużyteczne i nie pasujące do stylistyki samej gry. Zawodowi

deweloperzy korzystają z usług grafików którzy tworzą projekty menu na zamówienie. Ze

względu na brak grafiki i bardziej programistyczne nastawienie pracy posłużono się

szczątkowymi grafikami.

Page 32: Implementacja gry komputerowej z interfejsem głosowym

str. 32

Zarówno menu główne jak i menu pauzy są stworzone w oparciu o obiekt typu Canvas,

jest to wirtualne płótno na którym umieszczane są wszystkie elementy mające być

wyświetlone na wierzchniej warstwie obrazu. W przypadku menu zastosowano ustawienie

pozwalające na wyświetlenie płótna bezpośrednio na pierwszym planie kamery

zostawiając resztę sceny pod spodem. Elementy są umieszczane jako obiekty klas

pochodzących z biblioteki UI edytora Unity. Komponenty te mogą być interaktywne i być

automatycznie połączone z instancją EventSystem odpowiedzialną za śledzenie

wykonywanych przez gracza akcji. Menu składają się z przycisków (obiekty klasy Button),

obrazów (klasa Image), oraz tekstu (klasa Text), są rozmieszczone w sposób czytelny i

funkcjonalny, co przedstawiono na poniższych zrzutach ekranu. Wszystkie elementy UI

znajdujące się na płótnie zamiast zwykłej instancji Transfrom zawierają RectTransfrom

jest to specjalna klasa pozwalająca na dobranie takich parametrów jak rozmiar okna

zawierającego komponenty danego obiektu jak również pozwala na zakotwiczenie obiektu,

co z kolei daje możliwość tworzenie odpornego na zmiany rozdzielczości interfejsu

użytkownika. Wszystkie panele interfejsu posiadają referencje do klasy

MainMenu stworzonej w celu zarządzania poszczególnymi panelami menu, oraz

przejściami pomiędzy nimi. Klasa MainMenu posiada również referencje do obiektów

wspólnych dla poszczególnych paneli takich jak tło czy zacienienie.

Na ilustracji menu głównego widzimy panel przycisków oraz tytuł. Tytuł nie jest

oficjalnym tytułem demo gry, jest to tylko tymczasowy tekst napisany, aby możliwe było

zakotwiczenie obiektu typu Text na scenie, oraz dobranie odpowiedniego rozmiaru i

Rysunek 9 - Screen menu głównego[20]

Page 33: Implementacja gry komputerowej z interfejsem głosowym

str. 33

koloru czcionki. Obiekt ten został związany z górną krawędzią płótna (obejmującego

obszar wielkości zgodnej z rozdzielczością ekranu), dzięki temu tekst pozostanie w górnej

części ekranu w każdej rozdzielczości. Tło to grafika JPG uzyskana z darmowych zasobów

dostępnych w Internecie, przetworzona za pomocą Unity w obiekt typu Sprite i

umieszczona w komponencie typu Image na wirtualnym płótnie (Canvas). Przyciski to

wspominane wcześniej obiekty z komponentami klasy Button, w swojej hierarchii

zawierają one również instancje klasy Text dzięki czemu możliwe jest umieszczenie na

nich tekstu informującego do czego służy dany przycisk. Przyciski posiadają wbudowaną

metodę OnClick śledzoną przez EventSystem. W inspektorze możemy przypisać do niej

dowolną akcje. Najczęściej jest to jednak wywołanie odpowiedniej metody z klasy

odpowiedniego panelu. Przycisk rozpocznij grę wywołuje przy naciśnięciu metodę

StartGameButton() z klasy MainPanel. Metoda ta restartuje grę i dezaktywuje elementy

interfejsu związane z menu, uruchamiając te związane z bieżącą sesją gracza (pasek

zdrowia czy punkty). Metoda wyłącza także pauzę aktywną kiedy menu jest na ekranie.

Przycisk instrukcje ukrywa panel menu uruchamiając panel instrukcji. Podobnie jak

przycisk wyjdź z gry który uruchamia panel QuitGame i powoduje zniknięcie tytułu.

Panel QuitGame posiada dwa przyciski, przycisk „Tak” wywoła metodę zamykającą grę,

natomiast przycisk „Nie” metodę GoToMainMenu z klasy MainMenu która zamknie

bieżący panel i otworzy panel MainPanel czyli menu główne, oraz obraz z tekstem

widocznym na powyższym zrzucie ekranu.

Panel instrukcji w jest półprzezroczystym panelem zawierającym krótki opis tego jak grać,

co ważne jest on dostępny zarówno z poziomu menu głównego jak i pauzy. W zależności

od miejsca wywołania przyjmuje tło które znajdowało się pod panelem poprzedzającym,

panel instrukcji posiada zmienną do której podczas otwierania go zapisywana jest

referencja do poprzedniego panelu. Wciśnięcie „Escape” powoduje powrót do miejsca

Page 34: Implementacja gry komputerowej z interfejsem głosowym

str. 34

zapisanego w zmiennej. Panel instrukcji w obu wersjach przedstawia poniższe zrzuty

ekranu.

Poniższy zrzut ekranu przedstawia menu pauzy uruchomionej w trakcie gry za pomocą

wciśnięcia klawisza „Escape”. Ze względu na to, iż wszystkie bieżące akcje w projekcie

są wykonywane w Update(), a więc w kolejnych klatkach co oznacza zależność od czasu

pauza jest realizowana poprzez ustawienie skali czasu na zero. Unity dostarcza klasę Time

pozwalająca na zarządzanie upływem globalnego czasu w grze. Po ustawieniu wartości

timeScale statycznego parametru klasy Time na zero czas w grze zostaje zatrzymany. W

tym momencie w kolejnych klatkach będą odbywać się tylko akcje które zostały

Page 35: Implementacja gry komputerowej z interfejsem głosowym

str. 35

skonfigurowane jako niezależne od czasu. Ze względu na brak konieczności wykonywania

się na przykład animacji w trakcie pauzy, zastosowanie tej metody pauzowania gry nie

sprawia żadnych trudności.

W menu pauzy jest widoczny pasek zdrowia gracza, pozostałe elementu interfejsu gracza

są chowane ze względy na czytelność menu. Wraz z panelem uruchamiany jest także

obiekt „Shadow” posiadający półprzezroczysty komponent Image z czarnym obrazem

znajdujący się pod elementami panelu, a nad grą pozwalający na uzyskanie lepszego

kontrastu pomiędzy światem gry, a menu. Naciśniecie przycisków spowoduje wywołanie

odpowiednich metod. Menu pauzy opiera się o identyczne przyciski co menu główne,

zmienione zostały tylko napisy oraz funkcjonalności przypisane do metody OnClick(). W

przypadku przycisku „Instrukcje” jest to ta sama metoda. „Wróć do gry” powoduje

zamknięcie panelu pauzy i ustawienie parametru timeScale na wartość jeden (czyli

domyślną). Wciśnięcie przycisku wyjdź do menu wywoła metodę GoToMainMenu() z

klasy MainMenu która zamknie menu pauzy i uruchomi menu główne.

Dzięki dostarczanej przez Unity w wersji wyższej niż 4.3 bibliotece UI realizacja interfejsu

staje się bardzo łatwa. Wcześniej każdy element umieszczało się przy pomocy

odpowiednio napisanego kodu. Elementy menu takie jak przyciski czy tekst przesuwało się

w odpowiednie miejsca przy pomocy wektorów, podobnie określało się wymiary okien czy

funkcjonalności. Nauczenie się korzystania z nowszej wersji interfejsu pozwoliło na

wprowadzenie do gry elementów interfejsu użytkownika korzystając z minimalnej ilości

kodu. Dodanie zarówno menu głównego jak i pauzy pozwalają graczowi poczuć się w

demonstracyjnym projekcie jak w zamkniętym produkcie.

Page 36: Implementacja gry komputerowej z interfejsem głosowym

str. 36

4.4.8 Kamera

Tworzona gra jest osadzona w koncepcji Third Person Perspective. Oznacza to, że kamera

umieszczona jest w taki sposób, aby gracz widział świat zza pleców sterowanej przez

siebie postaci.

Kamera w świecie gry jest gotowym komponentem dostarczanym w silniku Unity.

Komponent posiada wiele parametrów, które można dowolnie modyfikować, większość z

nich jest jednak nie istotna w tym projekcie dlatego ich wartości są domyślne. Wbudowana

kamera zapewnia parametr pozwalający na dobranie tła. Tło jest wirtualną sferą

obejmującą całość umieszonej na mapie sceny. Pozwala to na wypełnienie pola widzenia

kamery w którym nie znajduję się żadna grafika tłem. Element pełniący rolę wypełniacza

to Skybox. Jest to standard w grach o trójwymiarowej grafice. Stosowanie takiego

rozwiązania pozwala na uzyskanie wrażenia rzeczywistego nieba. Starsze gry

komputerowe posiadały obiekt nieba będący sześcianem stąd nazwa Skybox, obecnie

jednak przyjmuje się za najbardziej rzeczywiste odwzorowanie użycie sfery, dlatego też

zastosowane zostało właśnie takie rozwiązanie. Kolejnym istotnym parametrem kamery

jest jej pole widzenia manipulując polem widzenia możemy tworzyć efekty przybliżenia

czy oddalenia będące istotne na przykład przy tworzeniu trybu snajperskiego bądź trybów

kamery dostosowanych do różnych akcji. Sam komponent Camera nie zapewnia jednak

śledzenia gracza czy odpowiedniego ustawienia się kamery na scenie, odpowiada za to

autorska klasa CameraScript. Klasa ta zawiera bardzo wiele parametrów, większość z nich

odpowiada za różnego rodzaju przesunięcia kamery w poszczególnych stanach.

Kamera posiada dwa stany. Stan Normal oraz Aim przełączane prawym przyciskiem

myszki. Stan Aim jest przybliżeniem pomagającym w celowaniu. Celem stworzenia

wyjątkowego stanu była koncepcja, aby wprowadzić widoczny celownik zmieniając

również prędkość rotacji oraz precyzje celowania. Rozwiązanie jednak nie zostało

zrealizowane ze względu na problemu implementacyjne. Stan w kamerze pozostał,

ponieważ z punktu widzenia gracza strzelanie z tej perspektywy jest wygodniejsze,

jednakże sterowanie w tym stanie pozostaje bez zmian. Stan normalny pozwala na

spoglądanie na plecy gracza delikatnie z góry, obejmując również szeroki obszar terenu co

z kolei daje możliwość wypatrywania wrogów. Różnica między stanami polega na zmianie

parametru FieldOfView kamery, a także przesunięciu obiektu kamery poprzez manipulacje

parametrów komponentu Transfrom obiektu kamery. Klasa CameraScript zawiera także

referencje dwóch instancji klasy Transform obie znajdują się w hierarchii gracza. Jedna z

nich to środek postaci gracza, a drugi znajduję się przed graczem. Oba służą jako punkty

na które patrzy kamera, w zależności od aktualnego stanu. Po transformacji położenia

kamery i ustawaniu rotacji, wywoływana jest metoda wbudowana klasy Camera LookAt()

która jako argument przyjmuje instancje klasy Transfrom. Zmiana punktu na który patrzy

kamera w momencie zmiany stanu odbywa się w sposób płynny, ponieważ zastosowana

Page 37: Implementacja gry komputerowej z interfejsem głosowym

str. 37

jest metoda Lerp z klasy Mathf. Metoda ta pozwala na płynną zmianę parametru pomiędzy

dwoma z jej argumentów z szybkością podawaną jako trzeci argument.

Sterowanie kamery jest tylko odbywa sie tylko wokół osi Y wraz z obrotem postaci, w

miarę rozwoju projektu docelowo kamera powinna posiadać jeszcze stan Orbit

pozwalający na swobodny obrót kamery wokół własnej osi w momencie kiedy gracz

znajduje się w stanie spoczynku, całość powinna być także bardziej intuicyjna. W

projekcie postawiono jednak na implementacje własnych komponentów zamiast

kupowania gotowych dostarczanych przez AssetStore komponentów komercyjnych. W

trakcie dalszej implementacji projektu element ten prawdopodobnie uległby gruntownej

zmienia.

4.5 Sposób podziału pracy – Metodyka Agile

Jednym z podstawowych problemów zespołowego wytwarzania oprogramowania jest

synchronizacja zadań, które ma wykonać każdy z programistów. Odpowiedni podział

obowiązków, zadań i odpowiedzialności pozwala na tworzenie działającego kodu.

Temat zespołowego tworzenia oprogramowania jest poruszany od samego początku

istnienia układów programowalnych. Przeszedł wiele ewolucji i ciągle się rozwija.

Pierwszą koncepcją był model kaskadowy – nazwany po ang. waterfall. Jego idea opiera

się na wykonywaniu kolejnych czynności jedna po drugiej, przechodząc do następnej tylko

w przypadku, gdy poprzednia została ukończona i zaakceptowana. Koncepcja ta ma jednak

spore ograniczenia, nie pozwala elastycznie tworzyć kodu - praca wykonywana jest

szeregowo, błąd w dowolnej fazie projektu jest bardzo kosztowny i wymaga powtórzenia

całego etapu. Ze względu na swoje wady, które przekładały się wprost na koszty – firmy w

celu zmaksymalizowania zysków stworzyły kontr koncepcje programowania zwinnego –

ang. agile.

Metodyki zwinne pozwalają tworzyć kod równolegle, poprzez starannie podzielone

zadania oraz ciągły kontakt osób współtworzących projekt. W tej koncepcji od znalezienia

błędu do jego poprawienia mija bardzo mało czasu, gdyż znika ograniczenie oczekiwania

na kolejne etapy występujące np. w waterfallu[21]

. Jest to również doskonały wybór dla

zespołów z dynamicznymi wymaganiami względem kodu. Każda zmiana założeń projektu

nie zabiera dużo czasu.

W pracy zdecydowano się użyć metodyk zwinnych. Głównym argumentem

przemawiającym za tym właśnie sposobem była konieczność podziału pracy na dwie

osoby, które poświęcając niewielką ilość czasu na zadania biurokratyczne byłyby w stanie

niezależnie dążyć do zadanego celu. Naturalnym wyznacznikiem rytmu pracy były w tym

przypadku zajęcia projektowe z przedmiotu Gry Komputerowe, odbywające się raz w

tygodniu. Iteracja dla projektu zaczynała się więc w każdy piątek i trwała tydzień.

Page 38: Implementacja gry komputerowej z interfejsem głosowym

str. 38

Zastosowany model współpracy najbliższy jest scrumowi, który opiera się na codziennych

spotkaniach zespołu, gdzie każda z zaangażowanych osób zobowiązana była przedstawić

swój postęp prac, jak i wypowiedzieć się o aktualnych dla niej problemach.

Jeszcze podczas definiowania założeń pracy, przetestowano trzy sposoby gromadzenia

kodu w repozytorium. Pierwszym z nich było skorzystanie z oprogramowania Dropbox[22]

.

Pozwala on na współdzielenie poprzez sieć Internet katalogów. Jednak podczas

korzystania z Unity3D, zmieniane jest wiele plików tymczasowych – nie potrzebnych z

punktu widzenia współtworzenia kodu, które w tym podejściu były ciągle, niepotrzebnie

synchronizowane. Kolejną próbą było skorzystanie z GitHub’a[23]

, co również zostało

zaniechane z powodu konieczności synchronizowania dużej ilości modeli, plików

graficznych jak i ustawień samego Unity3D – dla którego GitHub nie proponował

odpowiedniego interfejsu. Rozwiązaniem tego problemu okazało się zastosowanie

wbudowanego w Microsoft Visual Studio rozwiązania Team Foundation, które dzięki

zastosowaniu odpowiedniego filtru, jak możliwości powiązania go z narzędziami do

organizacji metodyk zwinnych okazał się rozsądnym podejściem.

Stworzono także listę koniecznych do zrealizowania zadań, którym nadano tzw.

„estymatę” czyli liczbową wartość odpowiadającą ilości koniecznej pracy, by zakończyć

konkretne zadanie.

Aby zapewnić projektowi przejrzystość skorzystano z tablicy kanbanowej, czyli zbioru

zadań pogrupowanych według postępu prac nad nimi. Dostęp do takiego narzędzia

zapewnia wspomniane już wcześniej Microsoft Visual Studio Team Foundation. Już

podczas planowania projektu zdefiniowano większość zadań, które miały być zawarte w

jego ostatecznej formie.

Rysunek 10 Fragment tablicy Kanban

Page 39: Implementacja gry komputerowej z interfejsem głosowym

str. 39

Przed każdorazowym uaktualnieniem wspólnego kodu w systemie kontroli wersji, zmiana

była omawiana w obrębie zespołu oraz następnie zostały wprowadzane do niej poprawki

jeśli którykolwiek z członków projektu zgłosił zastrzeżenia.

4.6 Fazy projektowania

Praca została podzielona na wiele etapów. Pierwszym z nich było zdefiniowanie

początkowych założeń, które docelowo miały być spełnione lub zmienione po uprzednim

przedyskutowaniu. Podjęto próbę stworzenia gry opartej na rozgrywce dla wielu osób,

która dostarczała by wielu wrażeń użytkownikowi, pozwalając mu cieszyć się grą w

kooperacji lub pojedynku ze swoim towarzyszem. Plansza miała być odzwierciedleniem

krakowskiego rynku, jednak już po pierwszych próbach pracy w programie Blender

otrzymane wyniki były bardzo niesatysfakcjonujące ze względu na brak doświadczenia

zespołu w kwestii tworzenia profesjonalnej grafiki oraz brak koniecznych umiejętności

artystycznych, takich jak myślenie przestrzenne, dobór czy wytwarzanie tekstur.

Kolejnymi problemami były niska jakość animacji tworzonej na własnoręcznie robionych

modelach oraz czasochłonność procesu. Dlatego zdecydowano się na zaniechanie

tworzenia skomplikowanych modeli i skupiono się na ich doborze z gotowych źródeł jak

na przykład Asset Store. Takie podejście wymuszało stworzenie krajobrazu według

upodobań i wyobraźni zespołu, bez wzorowania się na jakimś konkretnym, istniejącym

miejscu.

Po zdobyciu modeli postaci wpasowujących się w założony na samym początku klimat

fantasy, zdecydowano się realizować mechanikę gry, odpowiadającą za rozmieszczenie i

logikę wrogów na planszy, warunki przegranej oraz możliwość odpierania kolejnych

napastników. W końcowej fazie tego projektu pojawiła się konieczność stworzenia

interfejsu dla systemu rozpoznawania mowy Sarmata, umożliwiającą spełnić

najważniejsze założenie – wprowadzić interfejs głosowy. Dzięki zastosowaniu metodyk

programowania zwinnego oraz dostępności odpowiednich zasobów postanowiono

prowadzić prace równolegle. Po stworzeniu działającego interfejsu i zintegrowaniu go z

grą oraz zakończeniu prac nad mechaniką przystąpiono do realizacji części ostatniej, przed

zakończeniem tworzenia nowej funkcjonalności – poprawieniu grafik, dodania szczegółów

i tła oraz innych obiektów nadających grze charakterystyczny klimat.

Tutaj również zespół połączył swoje siły, działanie w metodyce Agile pozwoliło na

równoległą pracę nad wykończeniem gry bez zbędnego blokowania się nawzajem, czyli

sytuacji gdy jeden programista uzależniony jest od pracy drugiego i musi czekać na jej

ukończenie.

Projekt nie był wolny od wad i dopiero w fazie testów, gdy prowadzono konsultacje z

graczami zgłoszono konieczność wprowadzenia kilku poprawek. Jedną z największych

wad wskazywanych przez graczy było połączenie sterowania z kamerą. Powstający w

trakcie biegania chaos został jednak zlikwidowany poprzez poprawienie stworzenie nowej

wersji skryptu kamery. Gracze wskazywali więcej drobnych wad, starano się je naprawić

Page 40: Implementacja gry komputerowej z interfejsem głosowym

str. 40

jak najlepiej, nie burząc gotowej już koncepcji i mechaniki gry jednocześnie rozwiązując

znaleziony problem. Według teorii testowania niemożliwe jest stworzenie przypadków

testowych i pokrycie nimi kodu w taki sposób, aby sto procent błędów zostało znalezione i

naprawione w taki sposób, który nie powoduje konieczności wprowadzania dalszych

zmian. Dzięki doświadczeniu zdobytemu podczas studiów, praktyk oraz w podjętej pracy

stwierdzono, iż niektóre z przypadków mimo tego że są potencjalnymi błędami nigdy nie

wystąpią, gdyż są na przykład blokowane przez inny element funkcjonalności kodu, które

potraktowano podobnie jak te z niską szkodliwością, praktycznie niezauważalnych –

zdecydowano się na pozostawienie je w kodzie bez żadnych poprawek, po uprzedniej

inwestygacji każdego przypadku.

5. Zakończenie

5.1 Podsumowanie

Implementacja gry komputerowej to złożone zajęcie, wymagające od zespołu

podejmującego się tej pracy dużej ilości zaangażowania oraz całego wachlarza

umiejętności. Osoby pracujące nad projektem powinny potrafić tworzyć zarówno grafikę

jak i modele trójwymiarowe, organizować pracę np. w metodykach zwinnych, posiadać

umiejętności z obszaru architektury jak i tworzenia oprogramowania oraz zbiór założeń,

które definiują kiedy praca jest uznana za gotową. Kluczowa jest również komunikacja

zarówno wewnątrz zespołu, jak i z osobą definiującą założenia. Wybór Unity jako

głównego silnika gry pozwolił na elastyczne tworzenie gry. Pomniejsze sposoby realizacji

ulegały ciągłej ewolucji, koncepcja zmieniała się zarówno po natrafieniu na barierę, jak i

znalezieniu prostszego lub bardziej eleganckiego rozwiązania. Projekt pochłonął bardzo

dużo czasu, który potrzebny był między innymi na tworzenie nowych rozwiązań,

wprowadzania poprawek do już istniejących czy ich wzajemne łączenie.

5.2. Problemy

Zespół podczas tworzenia pracy stanął przed wieloma wyzwaniami oraz natrafił na wiele

problemów. Głównym elementem sprawiającym problemy było połączenie modułu

interfejsu sarmaty z grą. Początkowe trudności ze stworzeniem działającej wersji napisanej

w języku C# spowodowane były brakiem równoważnych bibliotek użytych w

standardowej implementacji w C++. Został on rozwiązany po otrzymaniu od zespołu DSP

skompilowanej biblioteki dynamicznie linkowanej, z przeprowadzoną konwersją wersji

C++ do C# za pomocą CLI. Tak działający zbiór klas i metod potrzebnych do nawiązania

poprawnego połączenia z serwerem Sarmaty nie był jednak możliwy do użycia w

Unity3D. Pierwszym podejściem do rozwiązania tego problemu była próba włączenia dll

jako plugin natywny (czyli taki, który stworzony jest za pomocą innego języka niż

wspierany przez Unity3D C# oraz JavaScript). Zdecydowano się pominąć to rozwiązanie,

z powodu braku możliwości tworzenia instancji klas w nim zawartych, dostępne było

Page 41: Implementacja gry komputerowej z interfejsem głosowym

str. 41

jedynie używanie funkcji, co w tym przypadku nie rozwiązywało niczego. Podczas drugiej

próby, uzyskano bibliotekę skompilowaną z użyciem .Net w wersji 2.0. Niestety ta próba

również się nie powiodła, z powodu użycia części kodu skompilowanego w wersji 4.0,

ukrytego wewnątrz biblioteki. Ostatecznie zdecydowano się na stworzenie oddzielnego

programu odpowiedzialnego za utrzymanie sesji i wyświetlenie wyników.

Kolejnym problemem, jest spadek wydajności w klatkach, w których odbierana jest

informacja od interfejsu Sarmaty. Taka forma rozwiązania problemu jest jednak jedynie

tymczasowa, planowane jest ponowne stworzenie interfejsu.

Dużym kłopotem okazała się również implementacja kamery i celownika. Wzorując się na

profesjonalnych grach typu Assassins Creed firmy Ubisoft, próbowano uzyskać pływającą

kamerę, przełączaną w tryb celowania po użyciu odpowiedniego przycisku. Jednak

okazało się to zbyt trudne w realizacji i zdecydowano się na implementację prostszej

wersji, która jednocześnie pozwalała bezproblemowo poruszać się w świecie gry.

Gra działa bezproblemowo na komputerach z nowoczesnym i wydajnym sprzętem,

posiadających stałe łącze lub dostęp do sieci bezprzewodowej o wysokiej jakości. Wraz z

pogorszeniem się jakości łącza drastycznie rośnie czas odpowiedzi serwera Sarmaty,

głownie spowodowane koniecznością wysyłki dużego pliku zawierającego nagrany głos.

W ramach przygotowań do stworzenia właściwego projektu stworzono dwie inne gry, obie

zakończone fiaskiem. Zespół obeznał się wtedy z problemami dotyczącymi tworzenia

prostych gier, oraz sposobów pozyskiwania modeli z Internetu, jak i produkować własne.

Po kilku próbach tworzenia budynków i postaci w programie Blender, zdecydowano się na

korzystanie z gotowych już obiektów tego typu dostępnych w Internecie, z powodu niskiej

jakości własnych dzieł.

Główną rolę odgrywał również czas, terminy prezentacji kolejnych etapów pracy,

konieczność pogodzenia studiów, pracy zawodowej oraz życia osobistego z tworzeniem

zarówno gry, jak i jej opisu.

5.3. Przyszłość projektu

Projekt informatyczny, nigdy nie można uznać za zakończony. Wymaga on ciągłej troski i

wprowadzania kolejnych zmian. Wraz z czasem zmieniają się potrzeby klienta, pojawia się

nowa technologia pozwalająca na wydajniejszą implementację, czy pojawiają się nowe

pomysły na jego rozwój.

Kolejnym krokiem rozwoju projektu będzie reorganizacja interfejsu Sarmaty, w taki

sposób by działał jako niezależny serwer. Po wysłaniu pakietów na adres loopback

kierowałby dane do odpowiedniego serwera Sarmaty, a odpowiedź przebywałaby tą samą

drogę. Jest to o tyle wygodne w użyciu w połączeniu z grą w Unity3D, iż nie wymagało by

uruchamiania osobnego procesu, a jedynie utworzenia nowego obiektu na scenie

odpowiedzialnego za komunikację między serwerami.

Page 42: Implementacja gry komputerowej z interfejsem głosowym

str. 42

Większej dbałości wymagają również elementy grafiki – tutaj kluczową kwestią są

fundusze na zakup profesjonalnych grafik lub wynajęcie osoby, która współtworzyła by

grę pod tym kątem.

Istnieje możliwość rozbudowania rozgrywki o tryb dla wielu graczy. Pozwoliłoby to

umieścić drugą postać w świecie gry, której zadaniem była by obrona zadanego punktu,

lub współuczestniczenie w ataku. Będzie to dość pracochłonny projekt, ponieważ oprócz

stworzenia nowej mechaniki istnieje również potrzeba zbalansowania rozgrywki.

Zastosowany system czarów jest prototypem, wraz z pojawieniem sie informacji

zwrotnych od graczy zostaną opracowane nowe zaklęcia, które znacznie urozmaicą

rozgrywkę. Rozważane jest również wprowadzenie nowych map oraz przeciwników.

Aby wprowadzić powyższe zmiany w życie istnieje potrzeba uzyskania odpowiednich

zasobów w postaci funduszy lub osoby odpowiedzialnej za grafikę, oraz zespołu gotowego

poświęcić czas na jej dalszy rozwój.

Rysunek 1 Screen z gry Warcraft 3 obrazujący mapę typu Hero Defense[4]

......................... 7

Rysunek 2 Screen edytora Unity .......................................................................................... 11

Rysunek 3 Screen z gry z widocznym interfejsem .............................................................. 13

Rysunek 4 Screen z gry - Las ............................................................................................... 15

Rysunek 5 Screen z gry - Ciała niebieskie ........................................................................... 15

Rysunek 6 Screen z gry - wzgórze ....................................................................................... 16

Rysunek 7 Gracz .................................................................................................................. 20

Rysunek 8 BlendTree odpowiedzialne za animacje ruchu gracza ....................................... 21

Rysunek 9 - Screen menu głównego[20]

............................................................................... 32

Rysunek 10 Fragment tablicy Kanban ................................................................................. 38

Page 43: Implementacja gry komputerowej z interfejsem głosowym

str. 43

Bibliografia

1. http://dsp.agh.edu.pl/sarmata/

2. http://www.theesa.com/wp-content/uploads/2015/04/ESA-Essential-Facts-2015.pdf

3. https://en.wikipedia.org/wiki/List_of_best-selling_video_games#PC

4. http://www.hiveworkshop.com/forums/members/218181-albums5902-

picture64818.png

5. http://store.steampowered.com/app/336420

6. https://pl.wikipedia.org/wiki/Multiplayer_online_battle_arena

7. https://play.google.com/store/search?q=hero%20defense&c=apps

8. https://pl.wikipedia.org/wiki/Rozpoznawanie_mowy

9. http://www.slideshare.net/aerjotl/automatic-speech-recognition

10. http://www.gry-online.pl/S016.asp?ID=23688

11. http://store.steampowered.com/app/319740

12. http://store.steampowered.com/app/21800/

13. https://www.assetstore.unity3d.com/en/#!/content/38913

14. https://www.assetstore.unity3d.com/en/#!/content/21140

15. https://www.assetstore.unity3d.com/en/#!/content/22755

16. http://forum.unity3d.com/threads/119295-Writing-AudioListener.GetOutputData-

to-wav-problem?p=806734&viewfull=1#post806734

17. https://cafe.bevocal.com/docs/grammar/abnf.html

18. http://docs.unity3d.com/ScriptReference/Object.Instantiate.html

19. http://docs.unity3d.com/Manual/Coroutines.html

20. http://absfreepic.com/free-photos/download/the-full-moon-on-the-mountain-

3706x2622_70947.html

21. http://www.agilenutshell.com/agile_vs_waterfall

22. https://www.dropbox.com/

23. https://github.com/

24. https://unity3d.com/

25. https://www.visualstudio.com/en-us/products/visual-studio-team-services-vs.aspx

26. https://www.mixamo.com/