x-kom hosting

[C++] Isometric RPG Engine - work and changelog

Gość
utworzono
utworzono

Cześć, 
Po ustaleniu z Administratorem, zakładam długo wyczekiwany przez moją skromną osobę temat. 

Plusem dla mnie jest to, że będę w postaci edycji tego posta prowadzić changelog. 
Plusem dla Was jest to, że do znalezionych błędów, będę dodawać solucje. Także gdy ktoś utknie w podobnym miejscu , może znaleźć tutaj rozwiązanie. 

Postanowiłem po wielu problemach spowodowanych wysokopoziomowymi językami wrócić do macierzy, a macierzą u mnie jest C++. 
Przyznam się bez bicia, że od 8 właściwie lat nie ruszałem tego języka. Nie będę tutaj walić farmazonów o mojej przygodzie z JS, problemami związanymi z tym językiem, oraz dlaczego C++, a nie wyżej wspomniany JS, czy jakiś tam C# , Python, Assembler bądź też Java. Po analizie "za" i "przeciw", ma być C++ i tyle :)

Założeniem jest postawienie od podstaw silnika izometrycznego do gry typu crafting RPG. Ma on być napisany językiem, oraz bibliotekami tak, aby wymagania były rodem sprzed 10 lat, zaś grafika jak i mechanika odświeżona. W tym celu jako że znam JS, postawiłem na dość podobną w działaniu do Canvas bibliotekę Allegro 5 i darmowy kompilator Code::Blocks (następca Dev-C++ z którym kiedyś miałem do czynienia). 

Co działa:
- Listening klawiatury.
- Obsługa XYover/offload
- Podążanie kamerą za postacią
- Sterowanie (strzałki).
- Rendering do 2 poziomów.
- System kolizji
- System wysokości
- Animowane ruchy postaci
- Frame Limiter
- Dynamiczne przydzielanie wskaźników.
- Cycleblocker

Co nie działa:
*pusto

TODO: 
- zmiana kierunku postaci za pomocą kombinacji [ctr]+[strzałka]. 
- Rozdzielenie części statycznej od dynamicznej tła (obrazek od stripe). 


 

engine.JPG

Sebixxu
komentarz
komentarz

Hmm, niestety nie posiadam jeszcze umiejętności programowania poza jakimiś żałosnymi krokami, ale jako taki "noob" z otwartą buzią będę śledził owy projekt! Powodzenia i wytrwałości! :D

Gość
komentarz
komentarz (edytowane)

@Sebixxu Całość jest pisana na poziomie nooba, sam nie znam się na "twardych" językach programowania. Może być ciekawie.
Większość kodu portuję z JS na C++. Skoro miałem już napisane - przepisanie na inny język jest banalne.
Genialne w tym języku są wskaźniki oraz niskopoziomowość. Coś co w JS zarzynało procesor, tutaj schodząc na niższy poziom zużywa go prawie nie zauważalnie.  
Póki co, gra oprócz chodzenia po mapie, oferuje... nic :D 
Czeka na mnie przeportowanie systemu craftingu(261 linijek), fishingu(485 linijek) oraz skilli(200 linijek). Do tego nie zaprogramowałem jeszcze myszy i GUI. 
Akurat do GUI mam gotowe grafiki (muehehehe).

EDIT: No nie wytrzymałeś @Youki, musiałeś poprawić :D Chyba że tu jest jakiś inny grammar nazi, a ja Cię niesłusznie oskarżam. 

Sebixxu
komentarz
komentarz

Od siebie powiem, że zacząłem sobie "studiować informatykę" i pokazali nam tam garść C, nie zadowala mnie to i ostatnio mega nakręciłem się na C++, a co za tym idzie, "ogarnąć" obiektowe programowanie (jak kolwiek to mistycznie nie brzmi :D ) i poznać SFML, na razie są to puste hasła, ale po jutrzejszym ostatnim sprawdzianie mam zamiar nieźle siąść do tego by zrealizować wydaje mi się fajny pomysł Tower Defence wraz z koleżanką z która razem studiuję. Na razie kompletna abstrakcja, bo z postaw C muszę przenieść się do C++, zrozumieć metody, obiekty i całą resztę, a potem nauczyć się uczyć biblioteki, a potem ją zrozumieć i się jej nauczyć by móc coś napisać! Zapowiada się ekstra! :D Dlatego Twój projekt na pewno da mi jeszcze większego kopa do roboty i masę motywacji! :D 

Gość
komentarz
komentarz

Problem:

Nie działają duże obiekty, to znaczy, funkcja renderująca nadpisuje teksturę obiektu kolejnymi kafelkami.
Solucją może okazać się osobny rendering dla każdej z wysokości. Problemem natomiast może być spadek wydajności.
Myślę też aby "int k" wyciągnąć przed FOR, tak aby wpierw wykonało się ij dla k=0, zaś później ij dla k=1 itd... 

i to wartość Y, j to wartść X, zaś k to wartość Z.
 

                for(int i=ymin; i <= ymax; i++)
                {
                    for(int j=xmin; j <= xmax; j++)
                    {
                        for(int k=0; k <= map_floor; k++)
                        {
                            obj_render_id = GetMapObject(i,j,k);
                            isEmpty = true;
                            budX_distortion = 0; budY_distortion =0;
                            if (obj_render_id == 3){obj_pointer = obj_3; isEmpty = false;}
                            else if (obj_render_id ==14){obj_pointer = obj_14; isEmpty = false;}
                            else if (obj_render_id == 4){obj_pointer = obj_4; isEmpty = false;}
                            else if (obj_render_id == 5){obj_pointer = obj_5; isEmpty = false;}
                            else if (obj_render_id == 6){obj_pointer = obj_6; isEmpty = false;}
                            else if (obj_render_id == 7){obj_pointer = obj_7; isEmpty = false;}
                            else if (obj_render_id == 8){obj_pointer = obj_8; isEmpty = false;}
                            else if (obj_render_id == 9){obj_pointer = obj_9; isEmpty = false;}
                            else if (obj_render_id == 10){obj_pointer = obj_10; isEmpty = false;}
                            else if (obj_render_id == 11){obj_pointer = obj_11; isEmpty = false;}
                            else if (obj_render_id == 12){obj_pointer = obj_12; isEmpty = false;}
                            else if (obj_render_id == 15){obj_pointer = obj_15; isEmpty = false;}
                            else if (obj_render_id == 16){obj_pointer = obj_16; isEmpty = false;}
                            else if (obj_render_id == 17){obj_pointer = obj_17; isEmpty = false;}
                            else if (obj_render_id == 18){obj_pointer = bud_1; isEmpty = false; budX_distortion = 96; budY_distortion = 192;}
                            if(isEmpty == false)
                            {
                                    al_draw_bitmap(obj_pointer,(((j-xmin)-(i-ymin))*32)+centreX-budX_distortion,(((j-xmin)+(i-ymin))*18)-(k*29)-budY_distortion,0);
                            }
                        }
                    }
                }

 

Matematyk0
komentarz
komentarz

Nie znam biblioteki Allegro, ale mam wrażenie, że coś jest nie tak z tą linijką:

al_draw_bitmap(obj_pointer,(((j-xmin)-(i-ymin))*32)+centreX-budX_distortion,(((j-xmin)+(i-ymin))*18)-(k*29)-budY_distortion,0);

Dla każdego obj_render_id różnego od 18, budX_distortion i budY_distortion to 0, przy 18 gdzieś to przesuwa - na pewno tak ma być?

 

Inna sprawa, że zamiast ciągłego if ... else można by było użyć switcha, a w ogóle (ale znowu mówię, że nie znam tej biblioteki, więc nie mam pojęcia co za co odpowiada) wszystkie te obj_liczba wrzucić do jednej tablicy (np. obj_tab[0] = obj_0; obj_tab[1] = obj_1; itd. - o ile się da, jak nie, proponuję tablicę wskaźników - wtedy na pewno będzie się dało :D), żeby później wszystkie te if-y zmienić na cuś takiego:

 

if ((obj_render_id >=3 && obj_render_id < 13) || (obj_render_id > 13 && obj_render_id <=17) //3-12 i 14-17
{
	obj_pointer = obj_tab[obj_render_id];
	isEmpty = false;
}
else if (obj_render_id == 18) //18
{
	obj_pointer = bud_1;
	isEmpty = false;
	budX_distortion = 96;
	budY_distortion = 192;
}

W najgorszym wypadku program 5 razy wykona instrukcję if (czy większe równe 3, czy mniejsze od 13, później czy większe od 13, czy mniejsze równe 17, później czy równe 18) zamiast 15 za każdym razem. Przy dużych renderach i słabym komputerze, powinno działać trochę szybciej. No i myślę, że taki kod wygląda lepiej niż ciągłe if ... else ;)

Gość
komentarz
komentarz (edytowane)

Te obj_liczba to są wskaźniki bitmap, niestety musi być jak jest; budX i budY distortion, dotyczy obiektów wielkogabarytowych, zajmujących powyżej jednego kafelka (64x64). Dopiero to piszę, bo np budY, da się pobrać z obrazka (do testów na sztywno), zaś budX będzie wyliczane z proporcji.
Gdyby nie było przesunięcia, wówczas wyświetli się tylko lewa, górna krawędź, zaś reszta obiektu wygląda jakby była pod ziemią. 

Wracając jednak, aby nie przepisywać za każdym if-em pełnego renderingu, zastosowałem przekazanie wartości np obj_3 do wskaźnika obj_pointer.
 

al_draw_bitmap(obj_pointer,(((X-zasięg minimalny X)-(Y-zasięg minimalny Y))*pół kafelki)+przesunięcie X mapy - przesunięcie niestandardowe obiektu X,(((X-zasięg minimalny X)+(Y-zasięg minimalny))*wysokość górnej ściany sześciany)-(Wysokość Z*wysokość sześcianu)-przesunięcie niestandardowe obiektu Y ,0);

 

Matematyk0
komentarz
komentarz

A wskaźnik na wskaźnik bitmapy? Ekstremalna konstrukcja, bardzo łatwo o błąd, ale jeżeli miałoby to skrócić kod i trochę przyspieszyć program, chyba warto spróbować, a przynajmniej ja bym próbował :) 

Gość
komentarz
komentarz

Owszem, z tym że się nie znam. Ostatni raz, dotykałem C++ jak miałem 16-17 lat, to było 9 lat temu :D 

Wciąż szukasz rozwiązania problemu? Napisz teraz na forum!

Możesz zadać pytanie bez konieczności rejestracji - wystarczy, że wypełnisz formularz.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Strona wykorzystuje pliki cookies w celu prawidłowego świadczenia usług i wygody użytkowników. Warunki przechowywania i dostępu do plików cookies możesz zmienić w ustawieniach przeglądarki.