Pokaż kod IV – Nigdy niedokończone projekty

Kolejna część serii z napisanym przeze mnie kodem. Zapraszam.


Ostatnio przypomniało mi się o paru niedokończonych grach i mając okazję podpiąłem stary dysk do komputera, żeby je zbackupować na kiedyś, zanim do reszty o nich zapomnę, a szkoda, bo całkiem miło do nich wrócić. Krótko tu podsumuję co odzyskałem.

7DaysToColonise

output

Gra którą zacząłem robić tuż po wrzuceniu Memo Boxes, mocno pod wpływem gry AdVenture Capitalist. Miał to być typowy klikacz, ale ponieważ baaardzo lubiłem i do teraz z sentymentem wspominam przeglądarkowe Ogame, postanowiłem, że będzie w kosmosie.

Mechanika gry – budować fabryki na startowej planecie Ziemi, pieniądze generowane w fabrykach można za kliknięciem zebrać i zainwestować w kolejne (będą generować więcej pieniędzy), lub też w kolonizację następnej planety. Do gracza należałaby decyzja co bardziej się na dany moment opłaca, pamiętając, że w ciągu 7 dni (prawdziwych 7 dni) musi skolonizować Układ słoneczny. Pieniądze z fabryk zbierałoby się za każdym ponownym otwarciem gry na telefonie, pieniądze które w tym czasie powinny się wygenerować obliczałbym z delty czasu pomiędzy ostatnim a aktualnym uruchomieniem. Jeśli ktoś przestawiłby datę i wykryłbym to (musiałby w końcu kiedyś przestawić ją ponownie na aktualną), musiałby liczyć się z dwoma problemami: Komunikatem od gry – twoje finansowe imperium zostało zbombardowane przez nieznaną, międzygwiezną cywilizację, a także zwykłą nieopłacalnością takiego procederu – w końcu budowa fabryk też trwałaby swoje i byłaby to strata czasu, gdyby dla 1 dnia generowania się pieniędzy stracić powiedzmy 12 godzin w których nic by się nie budowało.

Prototyp zrobiłem na paru darmowych assetach z internetu, kod, poza tym, że jest porażką, nie kryje nic specjalnego. Mogę w charakterze ciekawostki pokazać obliczanie pozycji w ruchu eliptycznym planet:

pozycjaplanet

ileDodacX i ileDodacY to zwyczajne offsety na układzie współrzędnych, height i width to szerokość i wysokość takiego zakreślonego okręgu/elipsy, po pierwszym if-ie uaktualniam również obrót planety wokół własnej osi.

Mad Pirates

Gra pisana przez chwilę, pare miesięcy przed Speechlist. W gimnazjum sporo grałem w Empire: Total War, gdzie w bardzo przyjemny sposób zrealizowano bitwy morskie, dla przykładu:

Chciałem zrobić coś podobnego, również byłoby możliwe sterowanie okrętem ręcznie, ustawianie żagli, rodzaju kul (kartacze, łańcuchowe), oddawanie salw lewą lub prawą burtą, do tego dodałbym możliwość zarządzania załogą, ekwipunkiem i losowy świat – Karaiby. Całość oczywiście dwuwymiarowo, jeśli ktoś jeszcze miał złudzenia, że porwałbym się na trójwymiar.

Całość zarzuciłem na rzecz sporo ciekawszego Speechlist które faktycznie skończyłem po paru miesiącach.

Ciekawe rozwiązania w kodzie?

Przez jakiś czas walczyłem z ruchem statku w kierunku ostatniego kliknięcia, niby banał, ale w końcu postawiłem na rozwiązanie z internetu, bo w rozwiązaniu z mojej ręki statek zamiast powoli się obracać w nakazanym kierunku – twerkował:

outpu3t

Po poprawkach:

output

Na ten moment mam pomysł na recykling tego kodu, w końcu potrzebna nam gra do dźwiękowego backendu z serii Sound Processing. Czemu by więc nie przerobić Mad Pirates na klona Steam Birds, gdzie między turami za pomocą dźwięku wymieniane byłyby wektory po których miałyby poruszać się statki graczy.

sidetorotate

Kod, który obliczał  na podstawie X i Y miejsca kliknięcia kąt, o jaki powinien obrócić się statek, aby tam zmierzać.

Black Hat

W styczniu 2016 zebraliśmy się w 4 osoby w celu zrobienia gry pod konkurs którego nazwy już nawet nie pamiętam. Celem było stworzenie gry takiej jak Uplink, ale mocno fabularyzowanej, z wielotorową historią, różnymi zakończeniami etc. Cała gra miała dziać się na ekranie komputera wewnątrz gry, stąd nasz cel numer jeden – stworzyć dobrą mechanikę i niebanalną historię, aby zapełnić deficyt jaki tworzyła nasza prosta grafika.

Całkiem poważnie się za to zebraliśmy, spotkaliśmy się raz lub dwa na dłużej, gdzie jeden robił za skrybę a reszta dzieliła się pomysłami, do tego na dysku mam ~300 MB rozmowy na Skype, gdzie robimy dokładnie to samo.

Jak szybko zaczęliśmy, tak szybko całość zarzuciliśmy na etapie prac pokazanym na filmiku wyżej. Czekało nas mnóstwo pracy, którą można było podsumować smutnym “nawet nie wiadomo czy to wypali”.

Poniżej przedstawiam jeden z kilku skryptów naszych ustaleń:

Wstęp do gry

Po włączeniu gry włącza się intro wykonane w komiksowy sposób – przedstawia ona historię poruszając kamerą po statycznych obrazkach, z lektorem w tle. Być może lektor będzie ważną częścią rozgrywki, w tle będziemy słyszeli myśli bohatera gry, jego wewnętrzne przemyślenia wobec trudnych decyzji. Być może chwilowe cutscenki również w komiksowy sposób, a na ekranie pojawią się też “mrugnięcia” oczu bohatera gdy będzie mówił i jego spoglądanie po pokoju.

Ale wracając:

Po intrze płynnie trafia się przed komputer do pokoju głownego bohatera, przed jego komputer (z jednym lub dwoma monitorami)(Miejscem całej rozgrywającej się akcji jest jego pokój i komputer) – Kamera skierowana jest na monitor, pokój jest zaciemniony, monitor wyłączony. Świeci się jedynie na czerwono przycisk włączenia monitora.

Cała akcja stoi, aż do momentu właczenia monitora przez gracza.

Wtedy odgrywa się nieco przerażający dźwięk (8 bitowy, włączania komputera).

Po paru sekundach monitor się lekko rozjaśnia ale nadal jest ciemny. Pojawia się logo EnvyOS.

Czekanie kilku sekund (w tle dźwięki pracy dysku, komputera, przydadzą się takie efekty dźwiękowe).

Ekran jaśnieje na kolor kremowy/beżowy.

Pojawiają się na nim pytania (a raczej wyostrzają się, są na początku rozmyte, lekko przeźroczyste).

Rozpoczyna się kwestionariusz.

Są to pytania, kreujące przeszłość bohatera jakim kierujemy, początkowy podział jego punktów umiejętności i możliwe że część początkowej fabuły.

Kwestionariusz znajduje się w dokumencie kwestionariusz.
Po wykonaniu kwestionariusza ekran znowu ciemnieje.

Tym razem gdy po paru sekundach się rozjaśnia trafiamy na pulpit.

Dalszą część obejmuje dokument fabuła.

Aby zobaczyć wygląd systemu i jego działanie, zajrzyj do dokumentu system.

Czyste pomysły

Wśród znalezisk znalazłem również krótki plik tekstowy z koncepcjami do użycia w nieokreślonej przyszłości, znalazły się tam m.in:

Klon “Miecze i sandały z fabułą osadzoną gdzieś w czarodziejskim świecie, analogicznie ulepszamy ekwipunek – różdżki, runy, cokolwiek, a zdobyte punkty ładujemy w jakieś drzewko umiejętności. Być może dodałbym multiplayer, nie byłoby to specjalnie trudne ze względu na to, że gra byłaby turowa, jak chociażby Hearthstone, wystarczyłoby więc zwyczajnie postować i getować co jakiś czas jakieś RESTowe API jak to robię w Speechlist przy pobieraniu testów.

Dwuwymiarowy, pixel-artowy klon League Of Legends; miałem w planach przełożyć mechanikę gry praktycznie 1:1, z tą różnicą, że na dwuwymiarowy świat. Pomijam, że nawet teraz ambitne byłoby się za to zabrać, mogąc faktycznie kupić jakieś assety i przejmować się jedynie programowaniem (co ze względu na aspekt interakcji graczy na żywo, gdzie liczyłyby się dziesiętne części sekundy, mogłoby mnie przerosnąć).

Klon Don’t Starve. Tu chyba nie muszę tłumaczyć, takich gier robionych w różnej maści Game Makerach jest aż za dużo.


dsp2017-1

Pokaż kod III – Turn The Snake

Trzecia część przeglądu kodu moich gier/aplikacji. Zapraszam.


Gra której większość napisałem w zasadzie w ciągu weekendu. Niepotrzebne były jakiekolwiek assety z Open game art czy temu podobnych stron stron (poza dźwiękami kliknięcia i czcionką). Wariacja na temat Snejka i kręcących w głowie kolorowych gierek.

Pisałem to dość dawno, stąd od razu ostrzegam przed powtarzaniem złych praktyk pisania kodu, jaki jest w tym repozytorium.

Przed dalszym czytaniem polecam ściągnąć tutaj, lub obejrzeć poniższy filmik.

Gameplay

Film mocno klatkuje, prawdopodobnie ze względu na niezmierzone pokłady mocy mobilnego celerona.

Technologie:

Przez jakiś czas wspierałem również reklamy poprzez AdMob (wykupione przez Google w 2009) i darmowe Google support library do współpracy z Androidem. Działało O.K (chociaż zwiększały wagę całej gry z 1 MB do >5MB), ale nie było powodu by z niego korzystać – na dłuższą metę reklamy przeszkadzały w grze a pieniądze z reklam…

Monetyzacja

Po ponad roku od wrzucenia TTS i półtora roku po wrzuceniu Memo Boxes, moje konto AdMob wygląda następująco:

admob

admob

admob

admob

Nie, żebym liczył na więcej, ale takie są realia. Nie ma co liczyć na randomowe pobierania osób kręcących się po Google Play, jeśli nie porozsyłasz gry ani nie dotrzesz w żaden inny sposób do odbiorcy to licznik pobrań stanie na 50. Wydaje mi się, że nawet zatrudniając grafików i tworząc zawartość postawioną na jakość, jest to bariera nie do przeskoczenia. Co stawia nas przed kolejnym problemem.

Marketing

Napisałem kiedyś osobny post o tym jak zerowym kosztem podnieść sobie licznik pobrań, tymczasowo wskoczyć na top kilkaset według pobrań danego dnia i mieć trochę szansy na wybicie się. Żeby nie powtarzać się, krótko podsumuję to, co sam próbowałem:

Udostępnianie linków do pobrania na gamedevowych grupkach na Facebooku, m.in:

Po wrzuceniu na grupki odnotowałem +200 pobrań w ciągu kilku następnych dni.

Są serwisy, które same szukają zawartości do wrzucenia i mają formularze kontaktowe, gdzie można podesłać swoją grę. Wysłałem Memo Boxes i po 3 miesiącacach dostałem w zwrocie odpowiedź:

playplayfun

Plus LibGDX jest taki, że piszesz raz i uruchamiasz w przeglądarce, Androidzie, na desktopie i przy odrobinie szczęścia na iOS. Udało mi się wyeksportować wersję .war Memo Boxes i im podesłać, przy czym coś musiałem zepsuć przy eksportowaniu ewentualnie wynikało to z niedoskonałości przenoszenia libGDX na stronę, ale MemoBoxes działało okropnie. Za to dostałem darmową reklamę i coś w rodzaju recenzji.

Do tego próbowałem podesłać TTS do Ketchappu (wydawali kiedyś właśnie takie proste, kolorowe gierki), zero odzewu po automatycznym zwrocie:

ketchapp

Do tego gdzieś w internecie znalazłem kiedyś listę maili (w tabeli Excela) do dziesiątek serwisów o telefonach które piszą o aplikacjach/grach (głównie anglojęzyczne), myślę że taka aktualna lista nadal jest gdzieś do pobrania po odpowiednim wyszukaniu.


Sekrety działania

Sposób poruszania węża

Gdyby wyłączyć obrót figury, wąż poruszałby się po funkcji liniowej równolegle do jednej ze ścian danej figury, po kliknięciu zmieniałby ścianę do której równolegle się porusza na następną. W zasadzie to robiłem to bardzo na wyczucie, renderując obrazek pięciokąta i zmieniając współczynnik funkcji tak, aby wąż nie zbliżał się, ani nie oddalał od śledzonego boku. W kodzie wyglądało to tak:

if(timerMove > 0.0000005f){
snakeX = (float) snakeX + waysX[way]*(float)(ogniwa -1f) ;
snakeY = (float) snakeY + waysY[way]*(float)(ogniwa -1f) ;

Gdzie waysX i waysY wyglądały następująco:

waysX[0] = 1;
waysX[1] = -1.5f;
waysX[2] = 1;
waysX[3] = -0.32f;
waysX[4] = 1;

waysY[0] = -1.74f;
waysY[1] = 0;
waysY[2] = 1.74f;
waysY[3] = 1;
waysY[4] = 0.725;

Jak zrealizowałem jednoczesny obrót figury i zmianę funkcji po której poruszał się wąż?
Przy każdym kliknięciu iterowałem po elementach tablicy zawierającej współczynniki kierunkowe, przechodząc do następnego, odpowiadającego kolejnemu boku.

Co do obrotu całości:

updatecamera

Wygląda to bardzo archaicznie i nie polecam pisać w ten sposób, ale działa tak:

w momencie kliknięcia ekranu, ustawiam buforCam na wartość 120, timerem steruję odpowiednią szybkość odejmowania, za każdym odliczeniem odejmując 8 od bufora i jednocześnie obracając całość o 8 stopni. To (w przypadku pięcioboku) da całkowity obrót o jeden bok. Bardzo nieczytelne i przekombinowane.

Kolory

Zdefiniowałem kilka barw skali 0/255 w które mogłem wcześniej sprawdzić np. tutaj. Następnie z każdym kliknięciem przesuwam się o jeden element po tablicy, stopniowo zmieniając aktualną barwę tła.

kolory

regulatecolors

Realizacja kolizji:

Nie korzystałem z chociażby Box2D (po co wyważać drzwi buldożerem). Zamiast tego, zdefiniowałem obiekty Rectangle dostępne w LibGDX i korzystając z gotowych funkcji liniowych przypisałem ich kilkaset wzdłuż boków. Do tego tworzę obiekt typu Rectangle na każdej z części węża, można więc przy każdej klatce zwyczajnie iterować po tablicach z Rectanglami i sprawdzać czy części wężą nie kolidują ze sobą albo z bokami.

Poniżej mocno nieczytelny przykład:

collisions

Odnośniki:

Link do pobrania gry:

Google Play

Udostępniam całość kodu za darmo tutaj, jakość pozostawia sporo do życzenia, nie polecam do nauki.

Repozytorium

Soundcloud kolegi który podsunął pomysł na TTS:

Soundcloud

 

Pokaż kod II – Memo Boxes

Moja pierwsza w miarę rozbudowana gra w Javie napisana parę lat temu, studium przypadku pt. Jak napisać brudny nieczytelny kod. To jest tutorial JAK NIE PISAĆ KODU. Przed czytaniem polecam zapoznanie się z grą aby wiedzieć za co odpowiedzialne są przytaczane fragmenty kodu. Google Play.


Pisanie językiem polskim w kodzie. Najgorsze co może być. Nawet jeśli masz problem z podstawowym angielskim, włącz sobie translator gdzieś w tle i alt-tabuj za każdym razem gdy potrzebujesz odpowiedniego słowa. Jak nie wiesz do końca jak nazwać zmienną aby dobrze opisała do czego służy – myśl nawet dłuższą chwilę. Wbrew pozorom, może i wygląda to głupio, ale to potrzebne. Konserwacja kodu boli, tym bardziej, jeśli ktoś to po tobie będzie czytał.

Untitled.png

Przykład 1. O co mi tu właściwie chodziło?

Z tego co pamiętam, to metoda odlicza i wypisuje sekundy w momencie wpisywania odpowiedniej kolejności kart (odsyłam do gry). Po if-ie którego sensu kompletnie już nie rozumiem następuje prawdopodobnie zmiana pozycji sprajta z odpowiednią sekundą, następnie… Wypisujemy go?
przyklad3

Przykład 2. Odpowiednik nazewnictwa po angielsku w Speechlist.

Zapominanie o OOP

Przenoś do klas co się da, przenoś do funkcji to co powtarzasz. To powinno być wkładane do głowy od pierwszego programu. Poniżej kod który min. zmienia teksturę przycisku skinu do kart który aktualnie jest wybrany – DLA POJEDYNCZEGO PRZYCISKU. Czyli powtórzyłem to dokładnie 6 razy. Dzisiaj stworzyłbym publiczną metodę dla przycisku która przyjmowałaby odpowiednie flagi (czy karta jest kupiona, czy aktualnie jest otwarte podmenu kupowania) i ją wywoływał dla każdego z przycisków (za pomocą jakiegoś prostego fora, wcześniej wrzucając je do tablicy).

2.png

Wszystko to co tutaj załatwiane jest w sposób rzemieślniczy, w skali masowej robię w klasie Screen projektu Speechlist, zamiast przejmować się ustawianiem przeźroczystości czcionki (w przejściach pomiędzy ekranami), robi to za mnie automatycznie klasa, dla każdego tekstu który do niej przypisałem:

przyklad5

Przykład 3. Odpowiednik w którym obiektowo realizuję cele.

Formatowanie i komentowanie
Tak właściwie, to jest gorsze od polskiego w kodzie. IDE SFORMATUJE ZA CIEBIE KOD JEDNYM SKRÓTEM (defaultowo InteliJ -> ctrl + shift +L, w Eclipsie zdaje się że ctrl + a żeby zaznaczyć cały plik a potem ctrl + shift + F – skróty mają to do siebie że wchodzą w pamięć mięśniową i plus minus uda ci się odpowiednio ułożyć palce ale jednocześnie możesz nie móc odpowiedzieć na pytanie jaka to kombinacja, nie mając klawiatury dosłownie pod rękami). Do tego te komentarze które niby miały coś przypomnieć, chwilowo usunąć linię kodu która coś psuła, ale właściwie to są na wieczne nieusunięcie w limbo pomiędzy żyjącym a nieżyjącym kodem.

3.png

Przykład 4. Niechlujnie sformatowany kod.

Przykład ze Speechlist, jak robić to dobrze; w zasadzie nie ma tu nawet czego komentować.

formatowanie

Przykład 5. Dobrze sformatowany kod.

Magic numbers

Ooo zapiszę sobie tutaj pozycję tego, w sumie to na chwilę, a nawet jeśli, przecież będę pamiętał co to miało oznaczać…

4.png

Przykład z kodu Speechlist jak robić to prawidłowo, w tym przypadku zadeklarowałem publiczną klasę na stałe:

przyklad

Przykład 6. Zadeklarowanie stałych czytelnymi nazwami w specjalnie do tego stworzonym pliku.

Całe repozytorium mogłoby być cytowane na jakichś wykładach, złoża przykładów są obszerne.Początkowym purystom językowym polecam ksiązkę Clean Code, przykłady w Javie ale mocno uniwersalnego zastosowania.Repozytorium z całym projektem do pobrania. Dla porównania, na odtrutkę, wrzucę prawidłowe odpowiedniki powyższych w moim ostatnim projekcie, Speechlist.

https://bitbucket.org/dbeef/speechlist


PS: Sorry za kod w postaci zdjęć, darmowy WP nie pozwala na wtyczki koloryzujące składnie, w sumie zrozumiały model biznesowy.

Bonus

Znalazłem w telefonie film pokazujący prototyp pierwszego Memo Boxes, minęło kilka miesięcy zanim wersja z filmiku stała się tą, która jest obecnie na Google Play.

Do tego parusekundowy filmik przedstawiający jakiś miesiąc przed wrzuceniem gry na Google Play, jak widać po monitorze w tle pracowałem nad cząsteczkami.

dsp2017-1

Pokaż kod I – Speechlist

Pierwszy post z serii o moich aplikacjach od zaplecza.

Zapraszam!


tl;dr
Stworzyłem aplikację na telefon do ćwiczenia języka angielskiego, polegającą na uzupełnianiu luk w tekście, z możliwością pobierania kolejnych, nowych testów z serwera.
https://play.google.com/store/apps/details?id=com.dbeef.speechlist.android


Przez kilka tygodni wakacji rozwijałem aplikację; cały pomysł zawiera się w rozwiązywaniu testów przez uzupełnianie luk gotowymi wyrazami.
O ile idea jest prosta (mnóstwo tego typu zadań w podręcznikach, na każdym etapie edukacji), rozwinąłem ją – w przeciwieństwie do ćwiczeń w podręcznikach, zeszytach, gdziekolwiek indziej – testy w telefonie mają 3 podstawowe plusy:

  • są w telefonie, zawsze pod ręką
  • wykonasz je wielokrotnie
  • co jakiś czas pula twoich testów się powiększa – możesz je pobrać z serwera, prosto w aplikacji, na który będę wrzucał co jakiś czas kolejne

Postawiłem też od razu na samo ćwiczenie i obycie z językiem;
Nie jest to zdecydowanie samouczek, który od podstaw nauczy języka.
Na pewno można jednak powiedzieć, że jest to coś pomiędzy czytaniem tekstu po angielsku, a uczeniem się na pamięć słówek, coś czego mi osobiście brakowało.

Czuję się zobowiązany wstawić link do materiału osoby która często pojawiała się w znaleziskach na wykopie, a wrzuca mnóstwo materiałów do nauki Javy pod względem pracy.
tl;dr wnioski bez oglądania tego filmu – pomysł na aplikację językową dokładnie pasuje w model aplikacji na staż, co napędzało pracę, bo przynajmniej z mojej perspektywy, często nad pracą nad tym projektem wpadała do głowy myśl z rodzaju “jak to bardzo bez sensu, co mi to niby da”.

Same testy staram się robić sam, w większości w oparciu o artykuły z Wikipedii, co zdaje się być wystarczające, ale:
testy podzielone są na 4 kategorie – vocabulary, idioms, tenses i various.
Jak można zauważyć – testy oparte o uzupełnianie ciągu tekstu, gdzie stawia się na naukę nowych słówek pasują do tej pierwszej – resztę uzupełniłem na podstawie materiałów z innych stron uzyskanych za mailową zgodą autorów.

Co do materiałów graficznych – skorzystałem z ikon dostępnych na prawach licencyjnych jasno pozwalających na takie użycie, każda jest z jednej konkretnej strony, toteż nie było zbyt dużo problemów z wstawianiem do aplikacji… hm. Uznania autorstwa? Tj. po prostu informacji o źródłach z których skorzystałem.

Koszty stworzenia takiej aplikacji i publikacji:

Publikacja na Google Play – 25 USD, płatne kartą, miałem już wcześniej bo robiłem proste gierki.
Wynajęcie serwera – za 1 miesiąc – 18 zł
Reszta – własna praca.

Tutaj kończą się ogólniki, a zaczynają szczegóły techniczne.


Szczegóły techniczne – co i jak działa (albo jak co czasem nie działa).

Szybko skacząc w głęboką wodę, technologie z których korzystałem:

  • Java SE
  • Hibernate
  • PostgreSQL
  • LibGDX
  • Tomcat8 (o ile to dodać jako technologię)
  • Jersey framework

Szybko tłumacząc;
Java SE, język w którym pisałem zarówno backend jak i frontend
Hibernate, framework z którego korzystałem aby połączyć web service z bazą danych, jaśniej;
aplikacja zajmująca się przesyłaniem odpowiednich testów w odpowiedzi na zapytania z jakiegoś telefonu, aby odpowiedzieć na zapytanie – jak wygląda test o id = 15 – łączy się z bazą danych na tym samym serwerze, pobiera z niego listę testów, sprawdza który ma identyfikator równy 15 i odsyła.
PostgreSQL – wspomniana baza danych
LibGDX – framework z którego korzystałem do napisania frontendu, zajmuje się wyświetleniem wszystkiego na właściwym miejscu na ekranie telefonu, teoretycznie do pisania gier – natomiast ja skorzystałem z niego ponieważ wcześniej miałem pewne doświadczenie w nim (dwie małe gierki i kilka takich których nie publikowałem, skazanych na wieczne niedokończenie), nie chciałem więc uczyć się od podstaw innego bo zbyt długo by to zajęło (zależało mi na czasie, nie chciałem żeby skończyło się jak z programami które zaczyna się i w którymś momencie odechciewa nad nimi pracować)
Tomcat8 – serwer aplikacji javowych, na nim uruchomiłem web service (jeśli już się poplątałeś, przypominam -> na komputerze (nazywanym też w innych miejscach tekstu serwerem) uruchomiłem tomcat, który jest z kolei serwerem aplikacji javowych, na którym uruchomiłem web service, który komunikuje się z bazą danych na tym właśnie komputerze, baza danych to po prostu inny program którego zadanie to dysponowanie danymi)
Jersey – po raz kolejny – framework, który odpowiada za konkretnie sieciowy aspekt backendu, czyli odbieranie/wysyłanie danych do klienta

Przechodząc do sedna , oto co dzieje się po uruchomieniu aplikacji:

  • Telefon wysyła zapytanie do serwera;
    podaj mi identyfikatory wszystkich testów jakie masz
  • Serwer odsyła odpowiednie dane
  • Telefon wczytuje testy które posiada na miejscu, w pamięci i porównuje ich identyfikatory z tymi z serwera – tworzy wtedy listę testów które są na serwerze, a których sam nie ma – wtedy wysyła kolejne zapytanie do serwera
    wyślij mi nazwy testów, o identyfikatorach o numerach { id testów których nie ma w telefonie }
  • Serwer odsyła odpowiednie nazwy
  • Telefon tworzy na ich podstawie przyciski z odpowiednimi podpisami, wkleja je do ekranu “downloads” i gdy użytkownik je klika, telefon zna ich identyfikator, więc wyśle po prostu kolejne zapytanie do serwera, o test o zadanym id.

Jak wygląda sam test?

Najłatwiej chyba będzie wkleić jeden z nich dla przykładu, potem omówić strukturę:

Jest to json, parsowany w kliencie by uzyskać konkretne dane, z odpowiednimi znacznikami (<<||>>) dla aplikacji aby wiedziała gdzie wstawić przycisk do wstawienia luki.
Słówka są podane w kolejności odpowiadającej lukom, w aplikacji natomiast ich wyświetlanie jest losowane, tak aby po prostu nie wstawiać słówek z listy jedno za drugim.
Różnica między id a uniqueID – id jest przypisywane przez bazę danych, odpowiada kolejności w liście z testami, natomiast uniqueID to id które samemu przypisuję, każdemu testowi z osobna, aby uniknąć konfliktu między klientem a serwerem, gdzie jeden nazywa swój test tak, a drugi inaczej. Z zasady przydzielam w jsonie wartość id taką samą jaką ma uniqueID, to bez znaczenia bo i tak ulegnie zmianie.

Perspektywy rozwoju (co działa lub nie i czy można to jeszcze bardziej… ulepszyć)

  • Zmieściłem aplikację w 3.7 mb, ale na pewno da się upakować ją w mniejszych rozmiarach (są odpowiednie narzędzia do odchudzania takich plików)
  • Graficzne zmiany, takie jak renderowanie tekstu w większej rozdzielczości i skalowanie go do mniejszej, tak aby uzyskać na klarowności, pasek przewijania pokazany podczas poruszania się po liście, płynniejsza praca kamery, wsparcie dla starszych Androidów
  • Wydanie aplikacji na iOS, co akurat jest trochę trikowe (na razie korzystając z maca kolegi dotarłem do momentu, gdzie za pomocą odpowiedniej wtyczki, kod z Javy konwertowany jest na odpowiednik w C#, potem należy do otworzyć w xcode i mając licencję dewelopera testować na urządzeniach Apple)

Co się tyczy materiałów do nauki:

Jeśli chodzi o Javę, ja zacząłem od Head First Java i z ręką na sercu mogę powiedzieć –na pewno nie od deski do deski.
Skończyłem gdzieś w rozdziale pisania aplikacji sieciowych, natomiast wydaje mi się że trochę wyćwiczyłem w praktyce, pisząc od tamtego czasu (jakieś 2-3 lata temu).

Jersey i Hibernate – proste do bólu tutoriale z sieci, prowadzące praktycznie za rękę do napisania własnego rest service
LibGDX – to samo co poprzednie, z tym że najważniejsze to ćwiczyć i ćwiczyć.

Inne

Przez jakiś czas miałem pomysł, aby Speechlist był sterowany… Głosem. Skorzystałem z Javowego API do Sphinxa i rezultaty możecie zobaczyć tutaj:

Pomimo niemal 100% rozpoznawalności słów (ograniczyłem Sphinxowy słownik tylko do słów z testu, dawału mu to bardzo małą bazę danych do porównania co przekładało się na szybkość i trafność) miałem trudności z przeniesieniem działającej wersji na telefon. Co prawda istnieje CMUSphinx na Android, ale sprawiał mnóstwo kłopotów.

Pokaż kod!!!111jeden

Mam pomysł aby nagrać kilka filmów, gdzie piszę Speechlist od podstaw, natomiast na ten moment zostawiam tu moje repozytorium z gotową aplikacją:

Frontend:

Główny branch – “new libgdx version”

Branch z rozpoznawaniem mowy – “master”

Branch “no speech recognition” – śmieci

https://bitbucket.org/dbeef/speechlist

Backend:
https://bitbucket.org/dbeef/speechlist-rest-service


PS: Wiecie co mnie denerwuje w blogerach? Skoro mam okazję to o tym napiszę: memiczność na siłę. Wrzucanie hehe śmiesznych obrazków gdzie tylko się da w taki sposób, że ma się ochotę rzygnąć. Stop.


dsp2017-1.png