Pokazywanie postów oznaczonych etykietą kc. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą kc. Pokaż wszystkie posty

24 listopada 2025

To ja go tnę!

Udało się (prawie, patrz na koniec wpisu) dodać losowanie biegłości postaci  i wybór broni oraz pancerzy. To jest na prawdę masa kodu. Zasady w KC są niemiłosiernie skomplikowane w tym aspekcie i przerzucenie ich do postaci klas c# zajęło mi bardzo dużo czasu. 

ALE działa i jest.


Stan wyjściowy po wylosowaniu bohatera.


Dodanie broni do postaci

Podbicie specjalizacji do podwójnie biegłego

Dodanie zbroi


I cyk tarcza
    
Nie ograniczamy się też do jednej możliwej broni, można mieć ich wiele.

Albo i kilka z jednej grupy. Tu espadon i miecz półtoraręczny.



Współczynniki przeliczane są na bieżąco. 


Błędy? Jakie błędy!

Mechanizm ma jeszcze kilka wizualnych błędów, np. po dodaniu tarcz nagle przestał mi działać podgląd wybranych broni w zakładce broni i widać tylko ostatnią.  Inna niedoróbka to nie uwzględnianie wzrostu biegłości per poziom postaci czy pancerza naturalnego wynikającego ze skóry. Są to już jednak drobiazgi w porównaniu z całym mechanizmem
Ważne, że się pojawił. Błędy to rzecz pewna w tak rozbudowanym kodzie.

19 listopada 2025

Krótki wpis o broni

 Może to i mała aktualizacja ale jakże ważna w kontekście całego generatora. Do postaci można dodać broń i wylosować biegłość. Nie działa to jeszcze idealnie (miałem mało czasu na zrobienie tej zmiany), ale dzięki tak małym i działającym modyfikacjom chce się pisać dalej. 


Może i nie ma wszystkich parametrów ale ważne
jest że się pojawiają w opisie bohatera.



Leaked instance

Z niedoróbek - w kodzie często posługuję się klasami od typu `Node` i jeśli taki typ źle się zrzuca z pamięci nie używając polecania  

      public void Dispose()
        {
            QueueFree();
        }
   

dochodzi do wycieków... 

Przy zamykaniu aplikacji są ich ... dziesiątki :D. Pomyślę kiedyś czy to porawiać



16 listopada 2025

Więcej pomysłów niż dostępnego czasu

 Kilka ostatnich dni pozwoliło mi na wprowadzenie sporej ilości zmian w generatorze. Problematyczne stało się to, że rozgrzebałem jednocześnie kilka funkcjonalności i żadna nie działa tak jak powinna, a ja przeskakuję na kolejną i tu trochę kodu wrzucę, tam dodam trzy linijki... Przy takim trybie pisania ciężko kończy  się jakikolwiek projekt. Postaram się poniżej opisać co dodałem i może takie podsumowanie pozwoli mi na spojrzenie z góry na projekt i dokończenie po kolei rozgrzebanych elementów.

Dwie profesje

Dodałem możliwość wybrania dwóch profesji do generowanej postaci oraz uwzględnieniu w nich poziomów zaawansowania. Spora zmiana na plus względem poprzedniego podejścia do tego tematu. Teraz wiem skąd wynikają wartości składające się na cechy oraz raczej nie ma w tym błędów (tak mi się przynajmniej wydaje) Stworzenie opisanej wcześniej meta-profesji z dwóch było dobrym kierunkiem.

Postać dwu profesyjna z uwzględnionymi w cechach
poziomami per profesja

Na zakładce statystyk widać skąd wynika suma. Tu  
Żywotność dla poziomów 1-3 została powiększona o większą 
wartość wynikającą z profesji Wojownika a poziomy 4-5 już z Kupca

I tu pierwsza (grubsza) niedoróbka,
Na zakładce z odpornościami można dodać
bonus wnikający z poziomów ale tylko do.... odporności psychicznej

Plus jest taki że przynajmniej dobrze się liczy. 
Musze dodać jakichś... checkbox czy coś wskazujący,
w którą bazową pompujesz rzuty.


Zakładka Broni

Dodałem dwie nowe zakładki do generatora, w których będzie można dopełnić definicje postaci. Pierwsza z nich to zakładka broni.

Rzeczona zakładka

Wybór będzie standardowy - dobieramy grupę broni, dobieramy broń i losujemy biegłość. Na razie pracuję nad tym, aby w ogóle działała poprawnie, a postać prawidłowo się aktualizowała.

Wybór grup broni

Wybór broni noszonej przez postać

I efekt wyboru broni do postaci. Jak widać prace nad nim trwają.

Bez kłopotu można dobrać wiele broni.


W tej zakładce kryje się multum logiki i do tej pory pokryłem niewielką  jej część. Podstawowe problemy to oznaczenie, że broń jest preferowana w kontekście wybranej rasy i później zawodu (vide profesja Kowal i jego bonus do młotów) . Generator musi też wiedzieć jakie grupy broni wylosowano żeby per wybór np. różnych mieczy nie losował biegłości wielokrotnie, podobnie z poziomem biegłości, oburęcznością itp. itd. Znawcy zasad KC-tów wiedzą, że to ciężki kawałek charakterystyki postaci. Później trzeba do tego dodać cechy postaci, przeliczyć możliwe obrażenia (możliwe 6! rodzajów - ponieważ broń może być do walki wręcz i zasięgowa). W skrócie multum kodu. Na koniec trzeba to wyświetlić na podsumowaniu postaci w kc-towym szablonie.


Zakładka Zbroje

Tutaj na szczęście nie będzie jakichś cudów. Jest o wiele prostsza niż to co jest w zakładce broni. Wybór elementu i wrzucenie do cech w postać. Praca jest zaledwie rozgrzebana do poziomu wczytania listy pancerzy i tarcz na ekran.

Wybór pancerza

I sam efekt rozwinięcia listy. Jak łatwo zauważyć
 sama lista rozwijalna ma pewne niedoróbki.

I tyle można zrobić, wybrane elementy nigdzie nie są uwzględniane.


Podsumowując

Zostało jeszcze sporo od napisania. Z samego c# i godota zaczęły przychodzić mi z pomocą EventHandlery ponieważ zwykłe przenoszenie do głównego kontrolera informacji o zmianach na zakładce broni jest tak rozbudowane, że w przypadku próby zbudowania tego przez zwyczajne przenoszenie danych między klasami doprowadziłoby do powstania kilkudziesięciu metod mających tylko za zadanie przerzucania stanu.

Stąd też powstała klasa-singleton trzymająca definicje sygnałów (powoli skłaniam się do podzielenia jej per zakładka oraz per główne akcje na ekranie).

using Godot;
using OptionsMetadata;

partial class GeneratorSignal : Node
{
    [Signal]
    public delegate void AddLevelClickedEventHandler(int index);

    [Signal]
    public delegate void CharacterReadyEventHandler();

    [Signal]
    public delegate void ReloadCharacterEventHandler(CharacterSheet character);

    [Signal]
    public delegate void CharacterChangedEventHandler();

    [Signal]
    public delegate void WeaponGropupRemovedEventHandler(WeaponMetadata metadata);

    [Signal]
    public delegate void WeaponSkillIncreaseEventHandler(WeaponMetadata metadata);

    [Signal]
    public delegate void WeaponDoubleHandAddedEventHandler(WeaponMetadata metadata);

    [Signal]
    public delegate void WeaponSkilUpdatedEventHandler(WeaponMetadata metadata);

    private static readonly GeneratorSignal _Instance = new();

    private GeneratorSignal() { }

    public static GeneratorSignal Instance
    {
        get { return _Instance; }
    }
}

I zwykła obsługa emisji sygnałów przez Emit

    public void OnAddDoubleHandPressed()
    {
        GeneratorSignal.Instance.EmitSignal(
            GeneratorSignal.SignalName.WeaponDoubleHandAdded,
            weaponMetadata
        );
    }


i przechwytywania przez Connect i obsługa Callable

private void ConnectSignals()
    {
        GeneratorSignal.Instance.Connect(
            GeneratorSignal.SignalName.AddLevelClicked,
            new Callable(this, nameof(OnSomethingHappened))
        );

        GeneratorSignal.Instance.Connect(
            GeneratorSignal.SignalName.CharacterChanged,
            new Callable(this, nameof(CharacterChanged))
        );
    }

 

31 października 2025

Zmiany idą

 Musiałem zmienić wygląd gui. Poprzednie całkowicie nie sprawdza się na telefonie. Mam nadzieję, że nowe będzie czytelniejszy oraz wygodniejsze w użyciu. Niestety jego pełne uruchomienie będzie wymagał sporo pracy i zmian w projekcie


GUI upodobni się do tego jakie jest w starym generatorze
napisanym w java script



I po kilku chwilach pracy mam zmianę na lepsze

Teraz tylko muszę przywrócić pełną funkcjonalność.

03 stycznia 2025

Generator postaci do... Kryształów Czasu

 Nie żeby mi się nudziło, ale generator postaci oparty o zasady Kryształów Czasu był jednym z założeń zabawy w pisanie mini gry rpg i wykorzystania przygody Sladuma jako bazy do nauczenia się Godota i C# przy okazji. 

Stąd po bardzo krótkim czasie (zaledwie dwa-trzy dłuższe posiedzenia w ciągu ostatnich dni) udało się osiągnąć wstępny projekt kolejnej mechaniki gry (i kolejnej na tę chwilę nie dokończonej lecz nie mogłem się powstrzymać) czyli wspomnianego generatora postaci.
I tak patrząc na to jak szybko udało mi się stworzyć wyjściową wersję w C# generującą cechy w porównaniu z tym jak męczyłem się przy JavieScript, aby osiągnąć podobny efekt... jestem miło zaskoczony. Niby kod, a w sumie struktury obiektów POJO mógłbym przenieść niemal 1:1 jednakże zauważyłem w starym kodzie mnóstwo elementów, które były po prostu źle przemyślane. 

Nie ma się co oszukiwać - doświadczenie w programowaniu procentuje.  

Aktualnie kod w C# jest wygodniejszy w użyciu oraz czytelniejszy. Skomplikowane elementy dotyczące struktur potrzebne do wygenerowania cech stały się bardziej generyczne. Mechanizm losuje cechy główne i odporności w identyczny sposób w oparciu o takie same obiekty przenoszone w kodzie. W poprzedniej wersji nie udało mi się osiągnąć takiej spójności danych. Zawsze też jest opcja wstępnego refaktoru napisanych klas ponieważ już teraz widzę kilka elementów, które z powodzeniem mogę skrócić.

Oczywiście nowy generator nie ma pełnej obsługi wszystkich kroków wymaganych do stworzenia pełnoprawnej postaci. Brakuje w nim losowania wagi, pochodzenia, uwzględnienia wszystkich profesji i ras czy zalet i wad postaci, zawodów...  ale już teraz widzę, że dodawanie tych elementów będzie o wiele prostsze niż w JavieScript. Dobrze też, że pliki które tworzyły bazę danych dla starego generatora, w miarę łatwo będę mógł przekształcić w pliki jsona i wczytać do kodu zamiast mozolnie wszystko przepisywać na nowo. 

Ale koniec lania wody, pora na prezentację. 

Można wylosować  człowieka (mężczyznę) w profesji wojownika na poziomie 0. Elementy wchodzące w definicji rasy oraz profesji są zgodne z tym co jest w KC-tach.

Mam trzy zakładki grupujące dane.
Ogólny wygląd jest paskudny, ale nie to było celem.

Wylosowane statystyki postaci wraz z wyświetlonymi
składowymi (po prawej stronie od cech) z których zostały obliczone


I to samo, ale dla odporności.

Stary generator postaci (dostępny tutaj Generator postaci Kryształy Czasu ) pod względem zawartości bije na głowę to co teraz napisałem jednakże siedziałem nad nim z miesiąc(jak nie dwa) a tu to dopiero początek. I w innym języku :) 

I trochę o kodzie

Jak wiecie pisze w dla Godot w C#.  Struktura klas nie jest nadmiernie skomplikowana.
Jest generator cech (zlany w jedną gównianą klasę z kontrolerem ekranu wyświetlającym cechy i to musze obowiązkowo poprawić) i generator dla odporności oraz klasy wspierające. 

I o ile część losująca nie jest zbyt interesująca najfajniejsze klasy to StatDefinition odpowiadająca za definicję cech postaci - tak głównych jak i odporności oraz klasa odpowiedzialna za kostki. Poniżej jak wygląda w kodzie (zwykłe POJO ale o szerokim zastosowaniu)

public class StatDefinition
{
    /* nazwa cechy*/
    public StatName Name;
    /* długa nazwa parametru*/
    public string LongName;
    /* wartośc bazowa */
    public int BaseValue;
    /* czy powinna być losowana w generatorze */
    public bool ShouldBeRolled = true;
    /* czy to zdolnosć profesji lub rasy i możliwa przerzucana dla lepszego wyniku */
    public bool ProffStat = false;
    /* definicja kostki jaka trzeba rzucać */
    public RollDefinition RollCode;
}

I sama definicja przykładowo Żywotność dla człowieka , której w KC nie przerzucamy przy generowaniu 
    internal StatDefinition HitPoints { get; } =
        new()
        {
            Name = StatDefinition.StatName.HP,
            LongName = "Hit points",
            BaseValue = 100,
            ShouldBeRolled = false,
        };

Tutaj inaczej dla Siły, którą nie dość że rzucamy z użyciem k100 to jest także zdolnością profesyjną i mamy możliwość wybrania większego z dwóch rzutów
    internal StatDefinition Strength { get; } =
        new()
        {
            Name = StatDefinition.StatName.SF,
            LongName = "Strength",
            BaseValue = 50,
            ProffStat = true,
            RollCode = Generator.RollCode.D100,
        };

A tutaj oparta o ten sam szablon odporność na iluzję
internal StatDefinition Illusion { get; } =
        new()
        {
            Name = StatDefinition.StatName.ILLUSION,
            LongName = "Illusion",
            BaseValue = 10,
            RollCode = Generator.RollCode.D10Premium,
        };

Powyższe pozwala szybko definiować statystyki i wrzucać do wspólnego kodu genrującego. Poprzedni kod w JavaScript nie dawał takich możliwości.

I druga klasa która wyszła dosyć zgrabnie - definiująca kostkę 

 public class RollDefinition
    {
        /* nazwa kostki */
        public string Name;
        /* min wartość dla kości */
        public int minValue;
        /* max wartość dla kości */
        public int maxValue;
        /* chyba do wyrzucenia */
        public int toAdd;
        /* czy kość premiowa */
        public bool premium;
        /* czy to pojedyncza kosc */
        public bool onedice;
        private Random rollStat = new Random();
        public int Roll()
        {
            var rolledValue = 0;
            if (minValue > -1)
            {
                if (premium)
                {
                    rolledValue = RollPremium();
                }
                else
                {
                    rolledValue = rollStat.Next(minValue, maxValue);
                }
            }
            return rolledValue;
        }

        private int RollPremium()
        {
            var rolledValue = rollStat.Next(minValue, maxValue);
            if (rolledValue == maxValue - 1)
            {
                rolledValue += RollPremium();
            }
            return rolledValue;
        }
    }


oraz przykładowa implementacja - tutaj k10 premiowe
 internal RollDefinition PremiumD10 { get; } =
            new()
            {
                Name = "PremiumD10",
                onedice = true,
                minValue = 1,
                maxValue = 11,
                premium = true,
            };

 A jakie zmiany jeszcze wejdą do kodu?

Poza wydaje się oczywistymi elementami czyli refaktorem nie używanych rzeczy (np. dwa pola w klasie RollDefinition  nigdzie nie zostały użyte czy wspomniane zlanie w jedno kontrolera ekranu z generatorem cech ) to obowiązkowe będzie wczytywanie charakterystyk dla cech czy definicji profesji z plików json. Aktualnie jest to zaszyte w kodzie (co widać po sposobie definiowania cech postaci podanym powyżej) i nie jest to nie jest optymalna metoda pracy. 
Docelowo oczywiście wrzucenie kodu do głównego projektu małej przygody Sladuma i uwzględnienie w mechanice walki. 

To na tyle.
Miłego!














03 września 2017

Paragrafówka przygoda w Angularze cz5 - KONIEC PRAC

Udało się! Paragrafówkowy silnik (o tyle o ile może to powiedzieć autor jakiegokolwiek programu) ukończony. Możecie się z nim zapoznać grając pod tym linkiem:


Życzę powodzenia w odkrywaniu sekretów świątyni Seta.

p.s.
W razie uwag, błędów cóż - piszcie :P

17 sierpnia 2017

Paragrafówka przygoda w Angularze cz3

Powoli pracę nad angularowa paragrafówką dobiegają końca. Od ostatniego wpisu poprawiłem wiele niedoróbek, dodałem obsługę warunkowego wyłączania wyjść/wejść do paragrafów dzięki czemu np. nie da się dwa razy przeszukać pomieszczenia czy dwukrotnie wejść w tryb walki z raz pokonanym przeciwnikiem.
Po drodze powstała obsługa pułapek i kilka mechanicznych elementów gry. Niewiele zostało do dopisania (min.: wliczanie bonusów z przedmiotów w walce czy leczenie się).
Nadal nie ma modalnego okienka ekwipunku postaci! Nie udało mi się pokonać problemów z wyświetleniem głupiego modalnego diva ze wsparciem Angulara. W sieci znalazłem co najmniej kilkanaście przykładów opisujących jak to zrobić, ale żaden te z tych, które użyłem nie zadziałał. W końcu i to zaziała ale sądziłem że jest to rozwiązanie przysłowiowo dostępne prosto z pudełka.
Fajnie działa opcja sprawdzenia czy dane wyjście z paragrafu jest dostępne lub niedostępne. Efekt jest lepszy niż sobie obiecywałem po tym rozwiązaniu. Pokaże to na przykładzie działających paragrafów.
W ramach oryginalnego paragrafu 27 definicja była następująca:
Widać, że ilość obsługiwanych opcji jest duża i ew. gracz może po prostu ominąć te, które są dla niego niewygodne.
Dzięki wprowadzeniu kilku mechanizmów obsługiwanych z poziomy angulara pierwsze podejście do paragrafu wygląda następująco:
Co się stało? Otóż pojawiły się następujące rzeczy:
  • Sprawdzane jest czy postać posiada w ekwipunku klucz do drzwi
  • Jeśli go nie posiada, blokowane są wyjścia odpowiadające za obsługę klucza
A teraz chwilę pozwiedzaliśmy dostępne paragrafy (i nie wyważyliśmy drzwi) i mamy w ręce klucz pasujący do drzwi. Dostępne wyjścia prezentują się następująco:
jednocześnie dzieje się coś dodatkowego. Bez klucza (lub wyważenia drzwi) nie można było wejść do świątyni, ale i przejście ze środka świątyni na dziedziniec było zablokowane! (paragraf 11)
jednak w momencie gdy trafimy do paragrafu 11 z kluczem zdobytym na dziedzińcu (lub też wyważyliśmy drzwi) zmienia się ilość dostępnych możliwości:
Efekt jest przyjemny i intuicyjny. Chciałbym już oddać to co napisałem, ale jeszcze muszę się powstrzymać. Nie wszystko działa tak jak trzeba.

01 sierpnia 2017

Paragrafowa przygoda w Angularze cz2

Wbrew pozorom prace nad angularowym silnikiem gry paragrafowej trwają dalej. W tej chwili dotarłem do momentu, w którym kod idzie w logikę obsługi  działania paragrafów niż naukę Angulara. Oczywiście staram się jak mogę wprowadzać rozwiązania angularowe, ale nie oszukując - nie da się wszystkiego napisać tak, aby powstało tylko na angularowy sposób.
W tej chwili próbuje nauczyć się jak wygenerować modalne okienko potrzebne do wyświetlania  stanu ekwipunku postaci. Już sprawiło mi to sporo kłopotów i ...  nadal nie działa.
Kolejny element framweworka jaki chce zastosować to fabryki do tworzenia źródła danych (teraz tworzonego statycznie w jednym z plików) oraz niemal najważniejszy element Angulara czyli dyrektywy. Tylko co ja tą dyrektywą będę robił to nie wiem :).

Takie podejście to trochę przerost formy nad treścią jednak bez użyci możliwie dużej ilości wbudowanych elementów frameworka nie da się go nauczyć na trochę bardziej niż podstawowym poziomie.

 Sam silnik w międzyczasie od ostatniego wpisu otrzymał kilka nowych funkcjonalności. W tym:
  • testy warunkowe
  • testy kumulatywne
  • zbieranie przedmiotów po testach i po walce (przykład na zrzutach)
    Przed walką
    Po walce
  • sprawdzenie czy postać posiada przedmiot potrzebny do przejścia paragrafu
  • zapis historii poruszania się po paragrafach
  • kilka poprawek blokujących wyświetlanie paragrafów
  • dużo innych drobnych poprawek

Pojawił się już efekt kuli śnieżnej - drobna zmiana w miejscu X powoduje ZŹŻ zmian w 3 innych miejscach. Powoduje to standardowe zamieszanie - rzeczy które działały tydzień wcześniej nie działają dzisiaj.

Poważnie rozrosła się definicja pojedynczego paragrafu. Pierwotnie był tekst paragrafu plus linki przekierowań. Wraz z dodawaniem nowych funkcjonalności poziom komplikacji zmienił się i trzeba pamiętać o nowo dodanych rzeczach oraz o tym jak wpłyną na to co już jest napisane.

Poniżej przykłady jak wygląda definicja paragrafu w zależności od tego jak dużo operacji udostępnia.

Definicja zwykłego paragrafu z jednym przekierowaniem
new Paragraf({
    number: 2,
    text: '<p>Zajmujesz miejsce woźnicy. Brama otwiera się jak tyko do niej podjeżdżasz</p>',
    exits: [new Redirect({
        target: 30,
        text: '<p><a  class="more-link"  href="#/paragraf/30">Na dziedzińcu strażnicy podchodzą do Ciebie</a></p>'
    })],
    enemy: [],
    tests: [],
    treasure: []
}),


A tutaj mamy definicję paragrafu z wrogiem i możliwością zdobycia - po walce - przedmiotu, miecza do rąk dwóch. Oczywiście obiekt mieczDwureczny jest odpowiednio budowany wcześniej:
new Paragraf({
        number: 142,
        text: '<p>Paragraf na potrzeby podniesienia przedmiotu po walce</p>',
        exits: [
            new Redirect({
                target: 144,
                text: '<p><a  class="more-link" href="#/paragraf/144">Pokonałeś wroga</a></p>',
                type: FIGHT_WON
            }),
            new Redirect({
                target: 144,
                text: '<p><a  class="more-link" href="#/paragraf/144">Poległeś</a></p>',
                type: FIGHT_FAILED
            })
        ],
        enemy: [new Enemy({name: 'Czarodziej', hp: 1, deffence: 1, proffesion: MAGE, special: [], status: 1})],
        tests: [],
        treasure: [mieczDwureczny]
    }),


O i definicja miecza:
var mieczDwureczny =  new Treasure({
    id: 2,
    name:'Miecz dwuręczny',
    bonus:2,
    bonusType:'SF',
    diceType:'DYNAMIC_MD'
});


Tu zaś mamy definicję paragrafu z testem kumulatywnym. Sama definicja testu jest już skomplikowana...
new Paragraf({
        number: 139,
        text: '<img src="img/swiatynia_wejscie.png" style="width: 50%;height: auto;  float: right; margin: 0 0 10px 10px;"/> ' +
        'Test KUMULATYWNY (charyzmy) CH: 4(5)',
        exits: [
            new Redirect({target: 144, text: '<p><a  class="more-link" href="#/paragraf/144">Wyjscie jakie pojawi się ponizej 4 rund UDANE </a></p>'}),
            new Redirect({target: 144, text: '<p><a  class="more-link" href="#/paragraf/144">Wyjscie jakie pojawi się przy 4 rundach UDANE </a></p>'}),
            new Redirect({target: 144, text: '<p><a  class="more-link" href="#/paragraf/144">Wyjscie jakie pojawi się przy 5 próbach UDANE </a></p>'}),
            new Redirect({target: 144, text: '<p><a  class="more-link" href="#/paragraf/144">TEST NIEUDANY PO 5 probach</a></p>'}
            )
        ],
        enemy: [],
        tests: [new Test({parameter: CH, difficulty: 4, success: 5, cumulative: true, conditionalExits: ['WON:LT:4', 'WON:EQ:4', 'WON:GT:4', 'FAILED:GT:5']})],
        treasure: []
    }),


I tak dalej. Możliwości jest sporo w efekcie kod szybko puchnie.

Gdzieś przy okazji napisałem parser w javie, który przeniósł poprzednią wersję paragrafówki do wersji angularowej. Można prowadzić walki, przeprowadzać część testów i poruszać się między paragrafami. Dzięki temu zauważyłem też, że konstrukcja niektórych paragrafów stanowi poważny problem dla aktualnej wersji silnika.
Wygląda tak i jest w pełni grywalna (nie licząc problematycznych paragrafów)


Cyferki na górze ekranu to paragrafy, które minął bohater zanim dotarł do paragrafu 23.

 Tutaj przykład testu kumulatywnego i jego efekt:




i da się dojść do końca gry. Log paragrafów pokazuje co się działo po drodze :)






Mimo wszelkich problemów jadę z kodem dalej.


p.s.
Kod javascript generowany z hilite.me

10 lipca 2017

Paragrafowa przygoda w Angularze cz1

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ć.