jak dowiedzieć się jakie współrzędne są między punktami?

0

Witam, chciałbym zrobić aby gra renderowała sprity, które są na pozycjach zaznaczonych w obrębie żółtego pola. Chodzi mi o to, aby na mapie było pokazane to co widzą oczy gracza, a nie jego plecy. Wiadomo, że to co za ścianą też nie powinno być rysowane ale to zostawiam na kiedyś. Czy jest jakaś prosta funkcja, która to szybko obliczy czy dany punkt jest w kwadracie? Bardziej mi chodzi o jakąś zoptymalizowaną funkcję żeby mi fpsy nie spadały... bo już i tak coś przymula.
Zdjęcie:
https://imgur.com/9seGVEB

0

MAsz to w jakimś układzie współrzędnych i Masz współrzędne kwadratów?

0

Tak, kwadrat ma współrzędne x, y, rozmiar kafla to 50x50.
Mapa przechowuje kwadraty w tablicy wektor

2

Można, nawet na więcej niż jeden sposób.

Zakładam, że ten kwadrat reprezentujący "pole widzenia" postaci jest zawsze zorientowany tak samo, tzn. boki są zawsze pionowe / poziome?

Jeśli masz współrzędne sprite'a s i np. górny lewy i dolny prawy róg kwadratu (odpowiednio fov1, fov2) To wystarczy sprawdzić, czy współrzędne sprite'u mieszczą się w pewnym przedziale:

fov1.x <= s.x <= fov2.x # sprite znajduje się pomiędzy narożnikami FOV w poziomie
fov1.y <= s.y <= fov2.y # sprite znajduje się pomiędzy narożnikami FOV w pionie

Oczywiście może to sprawiać problemy, jeżeli współrzędna sprite'a znajduje się w jego narożniku zamiast pośrodku - w tej sytuacji może się okazać, że rzeczywiste pole widzenia (tj. widoczne kafelki, obiekty) będzie przesunięte.

W razie, gdybyś miał np. współrzędne prostokąta obejmującego sprite (taki, w którym sprite się zamyka) jako jakiś sbox1, sbox2 warunki się zmieniają:

Jeśli wystarczy, że sprite nakłada się z polem widzenia:

sbox2.x >= fov1.x # prawy dolny róg sprite'a jest na prawo od lewego górnego rogu FOV
sbox1.x <= fov2.x # lewy górny róg sprite'a jest na lewo od prawego dolnego rogu FOV
sbox2.y >= fov1.y # prawy dolny róg sprite'a jest poniżej od lewego górnego rogu FOV
sbox1.y <= fov2.y # lewy górny róg sprite'a jest powyżej prawego dolnego rogu FOV

Jeśli sprite musi w całości zawierać się w FOV:

fov1.x <= sbox1.x <= sbox2.x <= fov2.x # sprite zawiera się między bokami FOV w poziomie
fov1.y <= sbox1.y <= sbox2.y <= fov2.y # sprite znajduje się pomiędzy bokami FOV w pionie

W momencie, gdy dopuszczasz obroty FOV i/lub sprite'a takie proste porównania się nie sprawdzą i trzeba będzie policzyć nieco inaczej - de facto zrobić podstawowe wykrywanie kolizji między spritem a FOV. Tutaj trzeba będzie określać, czy np. odcinki się przecinają (to się chyba dało określić paroma iloczynami skalarnymi itp, ale nie pamiętam bo robiłem to ostatnio z 4-5 lat temu) i po której stronie odcinka (boku) znajdują się dane punkty, żeby określić nakładanie / zawieranie sprite'a z FOV.

Możesz też odpuścić całkowicie nakładanie się jakichś kwadratów, i zamiast tego mierzyć odległość od środka pola widzenia - możesz dodatkowo przyjąć dowolną metrykę odległości (euklidesową, Manhattan, dowolną inną - każda da inny efekt) i określać widoczność na podstawie metryki. Mając jeden punkt reprezentujący sprite i jeden reprezentujący FOV to będzie chyba najszybsze i niezależne od ew. obrotów, a przy okazji trywialne i łatwo rozszerzalne gdybyś chciał eksperymentować np. z innymi kształtami FOV ;)

0

Ok, dzięki. Jeszcze zapomniałem dodać, że będę musiał gdzieś przechowywać cztery kierunki: north, south, east, west.

0
Krwawy Ork napisał(a):

Ok, dzięki. Jeszcze zapomniałem dodać, że będę musiał gdzieś przechowywać cztery kierunki: north, south, east, west.

Ale w jakim celu chcesz przechowywać te kierunki, w kontekście wykrywania czy obiekt jest w polu widzenia?

Jeżeli to ma coś wspólnego z np. orientacją postaci (mówiłeś coś o widzeniu za plecami itd) to dla algorytmu wykrywania będzie bez znaczenia - co najwyżej pole widzenia będzie przesunięte względem postaci, ale nadal pokrywanie się sprite'ów z FOV będzie się odbywać w identyczny sposób.

0

Ale w sumie to nie pomyślałem, że kawałek roboty mam za sobą bo mam funkcję, która sprawdza czy Tile jest w konkretnej odległości od gracza. Bo aby gra nie muliła rysuję tylko to co jest w zasięgu np. 6 kratek dookoła, dodam jeszcze regułę if( position.y > player->GetPosition().y ). Ale oczywiście w tym przypadku tylko wtedy, kiedy patrzymy na south. Jest troszkę więcej do roboty, bo na mapie są jeszcze monstery i jakieś entity, które też muszę wziąć pod uwagę.

static double CalculateDistance( double dX0, double dY0, double dX1, double dY1 );

double Tools::CalculateDistance( double dX0, double dY0, double dX1, double dY1 )
{
return sqrt((dX1 - dX0)(dX1 - dX0) + (dY1 - dY0)(dY1 - dY0));
}

5

Weź to zrób jak należy. Zdefiniuj sobie struktury reprezentujące punkt i prostokąt, pododawaj wszystkie użyteczne metody np contains, intersects, ....
Jak będziesz to mia zrobione to, potem wykorzystanie tego w logice gry będzie proste.

0

Jezeli korzystasz z jakiejs gotowej biblioteki (a na pewno korzystasz) to maja gotowe metody, o ktorych pisze kolega wyzej. Jak udalo ci sie zrobic renderowanie mapy w jakims okreslonym obszarze, to tutaj robisz analogicznie. Bez kodu nie da sie podac gotowego rozwiazania

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