Ustalenie kolejności rysownia obiektów na scenie (w kierunku ↖)

0

Witam.
Od razu napiszę, że szukałem po google, lecz niczego co by mi pomogło nie znalazłem. Zwracam się do Was o pomoc, bo już nie mam pojęcia jak to zrobić.
Mianowicie. Posiadam mapę zrobioną z kafelków (każdy kafelek ma pole, w którym trzyma wskaźnik na kafelek nad nim i pod nim).
Pierwszą warstwę rysuję całą i nie ma z tym problemu, bo są na tym samym poziomie. Jednak co do drugiej są już problemy. Jako, że jest na równi ze wszystkimi obiektami, które nie mają stałej pozycji trzeba je jakoś ułożyć. Posiadam std::vector<Drawable*>, w którym zbieram wszystkie Tile i Entity jakie będą rysowane z uwzględnieniem kolejności rysowania (Aktualnie skały i gracz). Poniżej załącz link do obrazka, który pokazuje jak to wygląda.
http://screenshooter.net/2148672/rikhckk
http://screenshooter.net/2148672/alpbahm
Klasa Drawable implementuje metody do pozyskiwania współrzędnych x i y najniższego punktu na obrazku (czyli prawy dolny róg).
używam std::sort z custumową metodą porównywania. Próbowałem różnych obliczeń, ale niektóre tylko po części dają dobre rezultaty (np z 2/3 stron), a tyle to nic, raczej szczęście ;d.
Myślałem też nad tym, czy może ta ilość informacji jest niewystarczająca? Jeśli jest potrzebne coś więcej to bardzo proszę o nakierowanie, mogę dodać do implementacji trochę wartości, jeśli samo x i y nie wystarcza.
Ogólnie główne pytanie brzmi, jak posortować te obiekty tak, żeby było złudzenie trójwymiarowości. Jak już pisałem wyżej, jeśli jest potrzebne w kodzie więcej informacji do obliczeń to nie ma problemu.

PS. Rozmyślałem też na próbą wyliczenia kątą pomiędzy dwoma obiektami i bazowanie na tym przy sortowaniu. Nie wiem jak to wypali.
PS2. Jeśli to w czymś pomoże to używam allegro 5. Również chciałbym uniknąć korzystania z Z-buffera jeśli to możliwe.
PS3. Ad PS cos niezbyt

0

Odświeżam. Mam nadzieję, że ktoś mi pomoże, bo inaczej zostanę w miejscu ;d

0

A mógłbyś krótko opisać jak próbowałeś to zrobić? Może łatwiej będzie "naprawić" twoją metodę ;)

0

Okej postaram się opisać moje próby.

int ax = a->getX(); // to są koordynaty prawych dolnych rogów obiektów/spritów
int ay = a->getY(); //ta czesc jest stała oczywiscie
int bx = b->getX();
int by = b->getY();

Tutaj dam kilka moich prób, niektóre wypadły lepiej, a niektóre jedynie z mojego założenia powinny wypaść lepiej. Od razu mówię, że na początku dużo czasu spędziłem nad myśleniem jak to zrobić, jak to może wyglądać, ale potem zacząłem próbować trochę na pałe ;d. Od razu mówie, że będzie dużo linków do obrazków, żeby dobrze to zobrazować.

if(ax<bx)return true;
return false;

To jest najbliższe tego co potrzebowałem. Wszystko działa idealnie oprócz dolnej ściany.
Analogicznie próbowałem z ygrekami, działało gorzej, ale to przecież nie bierze pod uwagę dwuwymiarowości przestrzeni, więc można się było tego spodziewać.
http://screenshooter.net/2148672/xfdrvwa
http://screenshooter.net/2148672/xhkdcvv
http://screenshooter.net/2148672/hltxvkf działa, ale po przekroczeniu linii oznaczonej a obrazku przestaje. Co jest w sumie zrozumiałe
http://screenshooter.net/2148672/atvnpny
Próbowałem to ogarnąć czymś w stylu.

if(ay>by)return false;
if(ax<bx)return true; 
return false;

jednak zdarzają się dość często pozycje, w którch to nie działa.
http://screenshooter.net/2148672/qubxldk

if(ax+ay<bx+by)return true;
return false;

ma podobne problemy
http://screenshooter.net/2148672/yuuiast
Ogólnie próbowałem to rozwiązać jak najprościej było to według mnie możliwe, teraz trochę mam wątpliwości co do mojego toku myślenia.
Na internecie znajdowałem tylko przykłady do tego 'właściwego' rzutu izometrycznego, ale to zupełnie inna bajka.

Teraz z ostatniej chwili

if(ax*ay<bx*by) return true;
return false;

Problemy ma tylko z prawą stroną.

Myślałem nad tym długo, ale innego rozwiązania bazującego jedynie na koordynatach, które mam nie wymyśliłem. Dlatego zwróciłem się do Was z pomocą.

PS. sądzę bardziej, że moja metoda jest bardziej zła niż zepsuta ;d

0

Ale jaka logika w ogóle za tym stoi, bo chyba nie do końca ogarniam. Chcesz ustalic kolejność rysowania obiektów, ok. Ale czemu bierzesz do tego koordynaty z płaskiej siatki? o_O Jak to niby może działać?
Czy nie powinno być tak że rysujesz obiekty "od dołu" tzn od obiektów położonych najniżej? Jak dla mnie to w związku z tym każdy element siatki powinien mieć informacje o swojej "wysokości".

0

U mnie każdy obiekt (z tych, które muszą być posortowane) na razie jest na takiej samej wysokości i ma taką samą wysokość, więc chyba nie muszę tego brać pod uwagę. Myślałem, że skoro nie muszę tego brać pod uwagę, to to co mam powinno wystarczyć. Nie mówię, że tak na pewno jest, dlatego pytam.

Czy nie powinno być tak że rysujesz obiekty "od dołu" tzn od obiektów położonych najniżej?

W tym problem, że nie mogę brać pod uwagę jedynie kolejności na osi y, bo nie jest to gra w takim rzucie jak ta poniżej.
http://sandbox.yoyogames.com/extras/image/name/san2/62/305062/original/pokemon-emerald-image1.jpg
Prędzej już myślałem, że bardziej się przyda ich szerokość i głębokość. Dziś już trochę jestem nieświeży, jutro w wolnej chwili spróbuję coś wymyślić.

0

Okej. Wracam. Tym razem z rozwiązaniem, które mam nadzieję, że nie sprawi później problemów.
Tak jak mówił @Shalom wziąłem pod uwagę wysokość i jeszcze szerokość i głębokość.
Kod porównujący wygląda tak. X,Y są koordynatami prawego dolnego rogu.

int ax = a->getX(); //not working properly ;/
int ay = a->getY();
int bx = b->getX();
int by = b->getY();

int aw = a->getWidth();
int ah = a->getHeight(); //tutaj trochę pomieszałem. Jako, że wszędzie używam koordynatów na płaszczyźnie nie chciałem zmieniać nazewnictwa, więc rzeczywista wysokość obiektu to Depth, a na płaszczyśnie Height
int ad = a->getDepth();

int bw = b->getWidth();
int bh = b->getHeight();
int bd = b->getDepth();

return ax+ay+ad-aw-ah<bx+by+bd-bw-bh; //Gdy szukałem po internecie natknąłem się na podobny kod do rzutu izometrycznego. Trochę go pozmieniałem i na razie hula.
}

Nie wiem jak to się sprawdzi dla późniejszych przykładów. W razie czego jeszcze tu będę pisał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1