10 lipca 2017

Paragrafówka w Angularze

Wspominałem w poprzednim wpisie o pewnej niespodziance przygotowywanej wraz z przygotowaną paragrafową grą Przygoda barbarzyńcy Sladuma. Tydzień temu nie wiedziałem jednak czy będę miał czas i chęci (jakże są ważne), aby zrobić to co miałem na myśli.


Zaczęło się niewinnie. Nie dalej jak dwa tygodnie temu stwierdziłem, że nauczę się AngularJS - webowego frameworka do JavyScript. Umożliwia on - podobnie jak jQuery - na zaawansowaną pracę na poziomie przeglądarki z wyświetlanym kodem HTML. Trochę takie jQuery na sterydach. Jak pewnie podejrzewacie, nauka czegokolwiek związanego z programowanie wiąże się z pisaniem miej lub bardziej skomplikowanych programów pokazujących podstawy języka czy frameworku. I w tym wypadku zacząłem tak samo, ale po przerobieniu tego i owego z książki (zawierającej błędy w napisanym kodzie!)  doszedłem do wniosku, że ten sposób nauki jest, ogólnie rzecz ujmując, mało wydajny i do dupy. Robienie pseudostron z opisanych w książce przykładów czy wyświetlanie przysłowiowego "Hello world" nie jest zbyt rozwijające i bynajmniej nie pozwala na nauczenie się czegokolwiek w sensownym czasie. Trzeba podejść do tematu tak, aby nie znudził po kilku godzinach nauki.

Z tego też powodu wpadłem na pomysł, aby przy nauce Angulara zrobić całkowicie interaktywną grę paragrafową. Połączę dzięki temu przyjemne (robienie gier) z  pożytecznym (nauka frameworku). Częściowo jest to też efekt malkontenckich uwag mojego kolegi, którego mierził obowiązek wyjmowania kości do gry w grę uruchomioną na przeglądarce oraz że jest tak mało interaktywna. 

 W efekcie mam na tapecie paragrafówkę Przygoda Sladuma przerabianą na, ni mniej, ni więcej, grę tekstową, w której interakcja, poza klikaniem na paragrafy i okazyjnie na aktywne przyciski, nie wymaga od grającego więcej wysiłku. Testy i walka rozwiązywane są przez wbudowany silnik gry paragrafowej napisany w javaScript na frameworku Angular.

W tej chwili postęp prac w stworzeniu w pełni interaktywnej paragrafówki oceniam na jakieś 50%. Zbudowałem mechanizm przekierowań między paragrafami (oparty $location), szablonów ekranów (angularowe szablony), prowadzenia walki, testów pojedynczej cechy, losowania kostek (angularowe serwisy), wyświetlanie paragrafów i wstępna obsługa błędów (angularowe kontrolery). Brakuje dobrej obsługi błędów przekierowań i kilku aspektów mechaniki gry paragrafowej. Muszę też popracować nad  wyglądem np. listy wyników rzutów przy walce czy wygląd ekraniku ekwipunku. 

Efekty są zachęcający. Wszystkie działania gracza oraz podjęte akcje trzyma w pamięci przeglądarka, nie trzeba przechodzić między stronami, aby otworzyć kolejny paragraf. Wbudowałem proste zabezpieczenie przed oszukiwaniem poprzez cofanie stron :p. Prace trwają.


Poniżej kilka zrzutów:

Walka:

Przykład walki z dwoma przeciwnikami
Ciąg dalszy walki, dla postaci Sladuma, w zależności od potrzeb, aktywują się umiejętności przydatne w walce. Oczywiście
paski Żywotności zmieniają się dynamicznie.



Wygląd paragrafu przed testem wymagającym jednego rzutu.

Test nieudany + przekierowanie


Test udany + przekierowanie


p.s.
Jeśli zajrzy tu ktoś zainteresowany ja działa Angular użyty do stworzenia gry oczywiście mogę o tym napisać.

04 lipca 2017

Gra paragrafowa z KC w tle

Zapewne wiecie czym są gry paragrafowe. Jeśli nie to odsyłał do Wikipedii. A dlaczego o tym piszę? Powód jest prosty.
Właśnie jedną napisałem.
Tak - nie kłamie :). Pomysł pojawił sie przypadkiem podczas pisania postów na forum kc-towym.  
Dzięki zaangażowaniu i silnej woli udało się skończyć projekt!.

Gra została zamknięta w 80 paragrafach.
Spytacie - a gdzie można w nią zagrać?

A TUTAJ: Przygoda barbarzyńcy Sladuma

p.s. W związku z tym projektem przygotowuje jeszcze jedną niespodziankę. Jest jeszcze w fazie tworzenia i opracowywania koncepcji, ale efekty są obiecujące!

23 marca 2017

Rogalik

Oho, ale zrobiłem długą przerwę.

Niestety spowodowana jest brakiem czasu na rozwój gry. Ciężko zmusić się do pisania kodu, gdy wolne godziny, które możesz na to poświęcić, mieszczą się w granicy od 23:30 do 0:30 :).
Może aktualizacje będą się pojawiać jak wrócę do tematu chociaż na 15 min dziennie?

Rozważałem (za namową kolegi) do umieszczenia kodu na jakimś githubie czy innym gicie online. Tak, abym sam miał do niego łatwy dostęp z dowolnego komputera jak i z tego powodu, że może tajemnicze ktosie będą chciały partycypować w projekcie (i nie zaorają kodu wirusami:) ) podsuwają pomysły i poprawiając istniejące rozwiązania.

Jednak w tej chwili kod podróżuje w mailach, a powyższa propozycja pozostaje w sferze marzeń :).




12 grudnia 2016

Rogalik - grafika cd

W weekend poprawiłem trochę kod, znalazłem kilka miejsc, w których nadmiernie zapychałem pamięć grafiką i pewnie jeszcze wiele takich miejsc zostało.
Ale.
W tej chwili połączyłem generator mapy (ten z kwadracików widoczny kilka postów temu) z główną pętlą graficzną rysującą mapę. Pokoje planszy generowane są w momencie wejścia z wszystkim elementami składowymi jak pułapki/potwory/skarby - tylko nie ma to jeszcze przełożenia na wygląd pomieszczeń. Może do końca tygodnia się to zmieni, problemem jest przygotowanie odpowiedniej ilości plików opisujących cięte na potrzeby gry obrazków.

Szybkość odświeżania grafiki to 60 klatek / sekunda - i to ze względu na to iż przewijanie mapy przy mniejszej ilości klatek generowało uciążliwy lag.
Sama mapa nie jest jeszcze generowana tylko w widocznym dla gracza obszarze, ale już przygotowuję kod, który jest gotowy na takie zadanie. Właściwi w tym co widać poniżej brakuje tylko wyświetlenia pozycji drużyny tak, aby było wiadomo w którym klocku jesteśmy i mogę dalej wrócić do rzeźbienia mechaniki gry oraz poprawienia błędów w animowaniu poklatkowym (niestey kilka dziwnych błędów się wdarło)







W międzyczasie znalazłem coś takiego:

Jest to jakieś przykładowe (chyba- nie mam pewności|) gui "plecaka postaci" jakiegoś rogalika. W ten deseń chciałbym zrobić to w swojej gierce.
Trzeba przyznać że to co ludzie linkują do Pinteresta jest inspirujące:)


Aktualizacja
Poziom wygenerowany z animującymi się potworami.





ps.
Spojrzałem ile pamięci zjada moja "gierka" - w skrócie tak z 10x za dużo w stosunku do tego co oferuje ...


07 grudnia 2016

Rogalik - grafika!

Ostatnie dni miałem uciążliwie męczące i po powrocie do domu niebardzo miałem ochotę na jakiekolwiek prace przy grze. Nie znaczy to jednak, że zarzuciłem jakikolwiek jej rozwój. Poświęciłem kilka godzin na napisanie podstawowego mechanizmu animującego aktorów na ekranie. Oczywiście wiązało się to z przeczytaniem masy dokumentów, kilku rozdziałów książki Killer Java Game Programming, kilku wątków na StackOverflow, czegoś o javiefx, paru (nastu?) wpisów z blogów o programowaniu...

Pierwsza wersja aplikacji rysującej (gdy zaczęła cokolwiek rysować) psuła się dosyć poważanie ponieważ zjadała nieograniczone ilości pamięci. Szukając rozwiązania problemu (rosnący w nieskończoność GrowableBuffer w obiekcie Canvas) ściągnąłem przykłady z sieci dotyczące animowania w javieFX. Te zaś zjadały kosmiczne ilości czasu procesora (jedna animująca gwiazdki
w ekranie 400x600px zjadała ... 25% czasu procka CoreI5!) lub zatrzymywały się po kilkunastu minutach pracy.

Moja pętla rysująca zawierała błąd, który powodował, że animacja zatrzymywała się samoczynnie po kilku minutach. Aktualnie  mam problem z tym, że animacja działa, ale spowalnia po ok 10 minutach pracy.  Spaliłem duuużo czasu na znalezienie prawidłowego sposobu animowania klatek z użyciem komponentów javyfx tak, aby ciężar rysowanego obrazu nie rósł w nieskończoność. Przy okazji przypomniałem sobie trochę o obsłudze wątków i grafiki.
No i  udało  się - przynajmniej w ramach ograniczonego testu jaki wykonuję.  W tej chwili aplikacja animuje i rysuje to co trzeba, a poniżej zrzut z efektu jej działania.

Z technicznego punktu widzenia na ekranie gry będzie sześć warstw (w tej chwili rysowane są 3)
  • tło (jest)
  • podłoga (aktualnie połączona z warstwą ścian)
  • ściany
  • dodatki do pomieszczeń (np. skrzynie)
  • aktorzy (jest)
  • efekty specjalne

Warstwy, które są odświeżane dynamicznie (co klatkę) to tylko aktorzy. W niektórych momentach dojdzie odświeżanie dodatków do pomieszczeń - np. pochodni oraz w miarę potrzeb animacje na warstwie efektów specjalnych. Zaoszczędza
to duużo czasu i obliczeń komputera.


Napisany kod nie jest w 100% optymalny i da się jeszcze ograniczyć ilość wykonywanych przy grafice obliczeń. Widoczne obok okienko "zjada" na stałe ~100 MB pamięci - nie udało mi się zejść poniżej tej liczby. Taka już chyba uroda javyfx połączonego z moim kodem.
Niestety z czasem (> 20 minut) animka zwalnia znacząco i jednocześnie zaczyna zjadać więcej pamięci. Coś z moim kodem jest jeszcze poważnie nie tak...


Nie zrobiłem jeszcze pełnego opisu wszystkich rysunków używanych w grze stąd brak jakichś upiększaczy na załączonym zrzucie - w tej chwili mam opisanych 16 bohaterów i ich dwuklatkową :) animację, niebieską podłogę oraz ściany, tło oraz drzwi.

01 grudnia 2016

Rogalik, pułapki

Małymi kroczkami do przodu. Pojawiły się drobne moduły:
- możliwość wylosowania (predefiniowanych) bohaterów i wejście na mapę. Niestety nie ma jeszcze możliwości dobrania czarów do postaci ale to już niedługo się zmieni.
- pułapki. Jest to pierwsza rzecz jaka jest sprawdzana po wejściu do nowego pomieszczenia. W tej chwili można wybrać postać która spróbuje - jeśli ma odpowiednią umiejętność - rozbroić pułapkę i efekty tego działania - czyli rozbrojenie i przejście do kolejnej fazy lub uwolnienie pułapki i otrzymanie obrażeń. Wersja mocno 'beta' ale działa nawet sprawnie. Postać może nawet zginąć!


22 listopada 2016

Rogalik cd. :)


Projekt toczy się powoli do przodu.
Program (bo daleko mu jeszcze do jakiejkolwiek gry) rozrasta się i zyskuje kolejne moduły. Proces jest czasochłonny, ale z mojego punktu widzenia dosyć ciekawy. Pokazuje inne podejście do programowania i wymaga zmiany niektórych przyzwyczajeń.
Ekran gry. W pasku widać wylosowane potwory.
Sama gra - z punktu widzenia osoby patrzącej z zewnątrz - zmienia się niewiele. Od ponad tygodnia nadal mam tylko główne okno gry, które generuje labirynt. Z tą różnicą ze klocki są większe niż ostatnio - w oczekiwanej przeze mnie wielkości 112x112 px. Wynika to z tego, że krawędź pola pokoju będzie składała się z 6 grafik ścian i jednej grafiki drzwi. Tak ja widać poniżej - pole typu pokój. Wersja ASCI:


            ╔══─══╗
            ║               ║
            ║               ║
            │               │
            ║               ║
            ║               ║
            ╚══─══╝

Korytarze będą oczywiście węższe i opakowane grafiką. :).
Napisałem też pierwsze elementy, które wiążą rozsypany kod gry ze sobą. W efekcie rośnie poziom komplikacji i pojawiają się trudne w stworzeniu moduły - np. zarządzanie fazami gry czy główna pętla graficzna. Ale do rzeczy.

 W tej chwili jest (i działa - dodałem testy w JUnit :) ) :
- losowania zdefiniowanych przez grę bohaterów
- wstępny projekt gui dla statystyk i ekwipunku bohaterów (wzorowany na tym z Diablo / Torchligt ale bez grafiki)
Ekran bohatera
- moduł określający fazę gry (to chyba będzie, poza walką i rozpatrywaniem czarów, jeden z najbardziej skomplikowanych elementów gry)
- wyświetlanie okien wykrywania pułapek, przekupstwa, napotkania potworów, ekwipunku i statystyk postaci
- pełny mechanizm generujący labirynt (na tę chwilę 1 poziomowy)
- wylosowane w ramach labiryntu pomieszczenia otrzymują w pełni funkcjonalne wyposażenie w postaci pułapek/potworów/skarbów
- mechanizm generowania potworów i ich cech
- mechanizm generowania skarbów i cech skarbów
- wstępne mechanizmy dotyczące bufora grafiki i cięcia grafiki na klocki (będą w wielkości 16x16 pixeli)
- wstępny mechanizm silnika graficznego do animacji

Posiedziałem przy generatorze mapy (właściwie to główne okienko gry), tak aby był przyjazny użytkownikowi - np. poprzez centrowanie obszaru na klocku, w którym znajduje się drużyna czy też umożliwienie przeglądania obszaru z pomocą myszy. Jednak po zmarnowanych na to kilku godzinkach doszedłem do wniosku, że za wcześnie na ten element i powinna nim zarządzać pętla generująca grafikę, a nie z poziomu javaFX.
Zrezygnowałem też z włączenia wcześniej wykonanego generatora podziemi do gry bo efekt końcowy nie był tak fajny jak zastosowanie znalezionej grafiki.

Ale jeszcze go wykorzystam!

W tej chwili (nie liczę grafiki) gra "zbudowana" jest z ok. 68 klas, a pewnie dojdzie drugie tyle. Tak właśnie wygląd ta prostota :].

Ehh siadając przy tym nie sądziłem, że tyle tego wyjdzie, a nie oszukując się - to dopiero początek.



14 listopada 2016

A może roguelike?

Idę za ciosem.

Zachęcony efektem działania generatora podziemi stwierdziłem, że użyję go w większym projekcie. Generator ma stać się częścią prostej (tak wydawało się na początku) gry roguelike.
Żeby nie wymyślać koła i zasad gry od zera wykopałem starą planszówkę znaną na zachodzie jako Citadel of Blood, a w Polsce skopiowaną (zpiraconą przez Encore) i znaną pod nazwą Labirynt Śmierci. Generator będzie odpowiedzialny za tworzenie wyglądu poszczególnych klocków z których będą się składać podziemia, tak aby nie korzystać z niezbyt pięknych kafelków z których składała się oryginalna plansza.
W tej chwili wersja 0,0001 beta tworzy planszę z możliwymi połączeniami oraz ustala typ pomieszczenia, do którego trafia drużyna. W tle dzieje się trochę magii programistycznej
i  staram się robić te elementy gry, które nie sprawiają mi kłopotów programistycznych. W tej chwili dostępne są pierwsze wersje maszyny losującej potwory i skarby oraz mechanizm zarządzający turami gry.

Poniżej widać przykładowy działania generatora.


Kwadracik zielony to aktualna pozycja „drużyny” zwiedzającej podziemi. Podziemia tworzone są na bieżąco przy przechodzeniu między klockami (niebieskie kwadratowe pola) i na bieżąco określana jest liczba dostępnych wyjść/wejść z pomieszczeń. Czarne ramki to oczywście nieprzekraczalne „ściany”.

A tu widać w pełni wygenerowany poziom podziemi.




W tej chwili kwadraciki mają 64x64 px wielkości a sama plansza to 8x8 kwadratów (docelowo nie będzie tak skalowana).

Dla każdego z kafelków – w oparciu o ilość wejść – chcę wygenerować z pomocą już napisanego generatora wygląd. I tak do obszaru o 3 wejściach kafelek będzie wyglądał tak:





A tak dwa połączone klocki – jeden z 3 wejściami i drugi z jednym.








Taki przynajmniej jest plan. Na razie jestem jeszcze parę kroków przed połączeniem generatorów ze sobą.


Rzeczy wymagające dużo pracy idą w tej chwili na później – min. obsługa walki, grafika, ekrany i sensowne gui. Co do grafiki - będzie pixelartowa (oczywiście). Znalazłem w międzyczasie komplet grafik, które w 100% pokrywają moje zapotrzebowanie na elementy składające się na gry. Chcę wykorzystać DawnLike - 16x16 Universal Rogue-like tileset v1.81



Wygląda tak:


Będę mógł przećwiczyć obsługę grafiki i tworzenie animacji.

Mądrzy ludzie mówią, że najtrudniej napisać swoją pierwszą grę. Cóż – zobaczymy czy uda mi się ją zrobić i doprowadzić do grywalnej wersji. W miarę postępów (widocznych) będę dodawał kolejne wpisy.

Jeśli kogoś interesuje kod i co wykorzystuję - to także mogę go wrzucać. Piszę oczywiście w javie ze wsparciem javyfx  i kilku zewnętrznych bibliotek użytkowych.

03 listopada 2016

Generator map lekcje 5 / 6

Kolejny krok to zapewnieniu połączeń pomiędzy oderwanymi od siebie obszarami map. Lekcje zawierają się w ramach wpisów:  Connecting Rooms oraz Ensuring Connectivity

Lekcję dotyczącą tworzenia połączeń między oderwanymi do tej pory pomieszczeniami przerobiłem wraz z tutorialem. Jednak kolejną, w której zapewniamy połączenia pomiędzy wszystkimi obszarami mapy zrobiłem już samodzielnie bez zaglądania do tutoriala. W oparciu o zdobytą już wiedzę i własne umiejętności udało mi się to dosyć sprawnie zrobić. Ciężko mi ocenić czy mój kod jest tak dobry jak ten z tutoriala, czy może wręcz lepszy, ale działa i jestem z niego zadowolony bo jest mój :D.


Poniżej efekt pracy bez uruchomionego dodatkowo łączenia (lekcja Connecting Rooms):



i z łączeniem oderwanych obszarów (samodzielny kod):




Jak widać pojawił się nowy korytarz łączący oderwane strefy.


Teraz wyznaczone ścieżki trzeba przekształcić w korytarze. Czyli: Passageways.

31 października 2016

Generator map lekcja 4

Przerobiłem lekcję 4 Detecting Regions , w ramach której mapka była sprawdzenia pod obecność artefaktów w postaci zbyt małych obszarów pustych lub zbyt małych obszarów wypełnionych.
Przykładowo :
Mapka z dosyć dużą krawędzią dla kwadratu ściany (wartość Długość boku) z regionem o zdecydowanie zbyt małej wielkości. Powinien on zostać usunięty (wypełniony ścianą). Oczywiście w efekcie mapka będzie w 100% niegrywalna, ponieważ w całości zostanie wypełniona ścianami. 

Poniżej mapka przepuszczona przez filtr, z której usunięto dwa (musicie uwierzyć na słowo :) ) zbyt małe obszary puste. Algorytm usuwa także zbyt małe ściany.


  

W poniższej mapce widać zbyt mały obszar ściany, który powinien zniknąć z naszej mapy:


 Lekcja poszła dosyć szybko. Nie ustrzegłem się kilku błędów, ale udało się je w miarę szybko ogarnąć (nie pamiętam kiedy ostatnio używałem w javowego PriotytyQueue!)