Maniacs Patch nie gryzie #5 – Prosty HUD

Nowa możliwość edytowania obrazków otwiera nie tylko drzwi do tworzenia zaawansowanych rzeczy, ale też do upraszczania istniejących już systemów. Jednym z nich jest HUD gracza – paski hp, many, staminy i tym podobne. W przeciwieństwie do klasycznego sposobu korzystającego z dziesiątek obrazków różniących się kilkoma pikselami, prezentowany sposób potrzebuje ich tylko dwóch!

Przygotowania

Na początku potrzebujemy przygotować dwie grafiki: tła HUDu (części stałej) oraz samego paska (części zmiennej). Ich wielkość czy styl nie ma znaczenia, za to ważne jest, żeby ich rozmiar był taki sam. Na potrzeby tutoriala przygotowałem przykładowe grafiki o kulistym kształcie (rozmiar 40×40):

Oprócz tego potrzebujemy 3 zmienne:

  • aktualną ilość HP bohatera;
  • maksymalną ilość HP bohatera;
  • pomocniczą zmienną zawierającą ilość linii do zamalowania.

Wszystko gotowe? To do dzieła!

Wyświetlanie

Tworzymy nowy Common Event i ustawiamy jego działanie na Parallel Process, w końcu chcemy, żeby informacje na ekranie były aktualne. Następnie wyświetlamy oba obrazki, przy czym obrazek z tłem musi mieć niższe ID od obrazka ze zdrowiem. Pozostałe parametry ustawiamy wedle uznania – przykładowo, ja ustawiłem wyświetlanie względem lewego górnego rogu w punkcie (8, 8). Ważne, żeby te wartości były takie same dla obu obrazków!

Pomiary

Zanim użyjemy funkcji Edit Picture, musimy jeszcze pomierzyć kilka rzeczy. Potrzebny nam jest najmniejszy prostokąt/kwadrat zawierający grafikę zdrowia, a dokładniej jego lewy górny punkt oraz wysokość i szerokość. W tym celu musimy skorzystać z jakiegoś narzędzia graficznego – najprościej skorzystać z Aseprite, ale jeśli go nie mamy, wystarczy też jakiś GIMP lub nawet ręczne liczenie pikseli.

Zaznaczamy grafikę tak, abyśmy nie mogli już zmniejszyć zaznaczenia bez pominięcia jakiejś jej części. Następnie kładziemy kursor na lewym górnym pikselu zaznaczenia.

W lewym dolnym rogu programu naszym oczom ukażą się trzy pary wartości, z których będziemy potrzebować tylko pierwszej i trzeciej. Zapiszmy je gdzieś na boku i wróćmy do Makera.

Obliczenia

Kolejnym krokiem będzie obliczenie, ile linii pikseli obrazka zdrowia chcemy schować. Pomyślmy – najpierw potrzebujemy:

  • znaleźć brakującą liczbę HP
    MaxHP - CurrentHP
  • obliczyć jaką część całości stanowi brakujące HP
    \frac{MissingHP}{MaxHP}
  • wysokość najmniejszego kwadratu zawierającego grafikę zdrowia (co zrobiliśmy przed chwilą!)
    32

Po połączeniu tego wszystkiego w całość otrzymujemy:

\frac{32 * (MaxHP - CurrentHP)}{MaxHP}

Wszystko jasne! Wklepujemy do naszej zmiennej HUD Blank Lines powyższą formułę w polu Expression, powinno to wyglądać w ten sposób:

Czy to wszystko? Prawie – musimy jeszcze przygotować obszar zmiennych, które Edit Picture ma brać za kolor. Weźmy dowolnie duże ID zmiennych, do których na pewno nie zdążymy dojść (ale bez przesady!), przykładowo: 100 000 (słownie:sto tysięcy). Trzeba też policzyć ile pikseli w najgorszym przypadku zamalujemy: wystarczy pole wcześniej znalezionego najmniejszego kwadratu, czyli w tym przpadku 32 * 32 = 1024. Oznacza to, że nasz obszar zmiennych znajduje się w miejscu od zmiennej 100 000 aż do zmiennej 101 024. A jaką wartość powinna mieć zmienna reprezentująca przezroczysty piksel? Otóż… 0. Wypełnijmy zatem ten obszar zerami:

To już prawie koniec! Za pomocą F3 otwieramy TPC i wpisujemy komendę na edycję obrazka: @pic[ID].setPixel .xywh x, y, w, h .src v[ID]. W naszym przypadku ID obrazka będzie wynosić 2, to zmierzony w Aseprite lewy górny punkt, czyli 4w to zmierzona szerokość, czyli 32, ale za h wstawiamy już zmienną oznaczającą ilość linii, którą chcemy zakryć – czyli v[43]. I na koniec źródło pikseli, wskazujemy początek naszego obszaru zmiennych wypełnionego zerami – v[100000].

Efekt końcowy

I to już wszystko! Dodajmy jeszcze na mapę zdarzenia zmieniające ilość HP bohatera i sprawdźmy działanie skryptu.

Sposób szybki, łatwy i przyjemny, ale przede wszystkim prosty w powielaniu. Co sprytniejsi mogą pokusić się o np. animację znikającego HP.

Axer

5 thoughts on “Maniacs Patch nie gryzie #5 – Prosty HUD

  1. Axer i jego umiejętności w Maniacsu Patchu są niesamowite – i cieszę się, że widzę kolejny tutorial z tej serii. Metoda rzeczywiście brzmi prosto i przyjemnie w wprowadzeniu, a przy okazji pozwala na łatwe dopasowanie.

    Przyznam jednak, że jedna część mnie onieśmiela i muszę się upewnić, że donrze rozumiem metodę. w którym miejscu kodu jest czas na wprowadzenie edycji, by sprawić, by HUD działał w poziomie? Czy na to jest miejsce w ostatniej komendzie TPC i zamianie miejscami wartości:
    @pic[ID].setPixel .xywh 4, 4, v[43], 32 .src v[10000] ?

    1. Jest dokładnie tak jak piszesz, chciałem nawet to zawrzeć w tutku, ale jakimś cudem wypadło mi z głowy

  2. Dobry tutek, ale brakło mi po prostu wyjaśnienia, opisu jak ta metoda działa, co dokładnie po kolei się dzieje w silniku RM – nawet chociaż głupiego zrzutu z całością kodu na końcu.
    Ale doszedłem do tego i nie jestem do końca zawodolony. Wiem że RM2k3 od któreś tam wersji nie przeładowuje obrazków z dysku jeśli te są już wczytane, ale jednak wolałbym tego w miarę możliwości nie robić – to znaczy wczytać tło tylko raz i tyle, a nie co klatkę. Sam zaś wskaźnik HP rozumiem, że działa na takiej zasadzie że wczytujemy co klatke jego nietkniętą wersję i szybko zamieniamy odpowiednią ilość linii na przeźroczystą. Ale w takim razie jednak musimy na nowo przeładować obrazek z dysku, bo ten w pamięci gry pozbawiony jest już danych na temat wymazanych pikseli – czy czegoś nie rozumiem? No zabrakło mi takiego opisu, a nie lubię ślepo kopiować kodu którego nie rozumiem – choć czasem tak się mimo wsio robi, to w tym przypadku nie wydaje mi się, by tego zrozumienie było jakieś trudne. No i jak to się dzieje, że jednak ten obrazek jest przeładowany, normalnie najnowsze makery 2k3 olały by przeładowanie obrazka drugi raz pod ten sam numer i o tej samej nazwie – choć może tu sama komenda setPixel sprawia, że maker widzi już ten obrazek jako coś innego.
    Kolejna wątpliwość – co się stanie jeśli nie ustawimy wartości zmiennych na zero – znaczy jeśli olejemy zaklepywania miejsca na nie w pamięci. Normalnie wszystkie zmienne i tak domyślnie mają zero, ale czy setPixel jeśli nie znajdzie ich w pamięci – po prostu wywali program, czy i tak ustawi je na 0?
    No i jak już się tak rozpisałem to od razu narzekanko: Missing to zgubione, a Current to co – aktualnie – po kiego te anglicyzmy? No i zamiast płatnego aseprite, czy nawet topornego darmowego gimpa, tu styknie prosty paint.

    1. W zamyśle to miał być prostszy tutek do Maniacsa bez większego zagłębiania się w szczegóły, żeby zachęcić ludzi do korzystania z dobrodziejstw patcha, ale nie przeładować ich informacjami, stąd też brak bardziej technicznych uwag, o których mówisz. Ale odpowiadając na pytania:

      „Ale w takim razie jednak musimy na nowo przeładować obrazek z dysku, bo ten w pamięci gry pozbawiony jest już danych na temat wymazanych pikseli – czy czegoś nie rozumiem?”
      Dokładnie tak, teoretycznie można by też zapisać piksele obrazka w innym obszarze zmiennych i potem edytować obrazek zamiast wczytywać go od nowa, jednak daje to marginalny wpływ na wydajność – o ile nie próbuje się ładować setek obrazków w jednej klatce.

      „No i jak to się dzieje, że jednak ten obrazek jest przeładowany, normalnie najnowsze makery 2k3 olały by przeładowanie obrazka drugi raz pod ten sam numer i o tej samej nazwie – choć może tu sama komenda setPixel sprawia, że maker widzi już ten obrazek jako coś innego.”
      O ile dobrze pamiętam to BingShan przy implementacji oprócz tworzenia kopii z editami rozważał trzymanie oryginalnej, nieedytowanej kopii obrazka, ale zrezygnował z tego ze względu na wydajność, więc przypuszczam, że działa to na zasadzie Show Picture o tym samym ID, ale już z nowym obrazkiem.

      A co do ustawiania zmiennych na zero – szczerze mówiąc zwyczajnie zapomniałem, że maker i tak zeruje zmienne poza zakresem :v W tym przypadku można to pominąć, ale jeśli chcemy zmienić piksele na coś innego na przezroczyste, to już trzeba będzie wypełnić obszar odpowiednią liczbą.

  3. Ciekawe. Ja robię w RM XP, więc mam dostęp do skryptów w Ruby, ale nigdy nie ogarnąłem jak robi się takie paski, choć podejrzewałem, że trzeba przycinać obrazek. Może odwzoruję to sobie 🙂

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.