TO_mek Opublikowano 19 Stycznia 2011 Udostępnij Opublikowano 19 Stycznia 2011 Witam! Jak dokładnie działa instance_nearest? Wybiera najbliższy obiekt po okręgu (najkrótszy promień)? Jest dostępna jakaś lista znalezionych obiektów posortowana wg odległości? Potrzebuje znajdować najbliższy obiekt ale na dużym roomie w zakresie całej szerokości ale w ograniczonym zakresie wysokości czyli w prostokącie o zadanej wysokości. Może coś na zasadzie znajdowania najbliższego obiektu a później sprawdzania czy ten obiekt ma y w odpowiednim zakresie (tyle sam potrafię) ale w momencie kiedy jednak ten najbliższy obiekt jest poza szukanym zakresem (za duży lub za mały X) jak wyszukać "drugi w kolejności najbliższy obiekt"? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Platyna Opublikowano 19 Stycznia 2011 Udostępnij Opublikowano 19 Stycznia 2011 Najłatwiej przejrzeć wszystkie obiekty. Dla każdego sprawdzić czy się znajduje w zadanym obszarze, a jeśli tak to czy jest bliżej od aktualnie najbliższego. W takim przypadku zapomnieć o poprzednim i zapamiętać jego. GML var xxx; var yyy; var dist; var obj; dist = 1000000000; //Tu będziemy przechowywać dystans to aktualnie najbliższego znalezionego. Na początku jakaś wielka wartość. obj = 0; //Tu będziemy przechowywać id tego najbliższego xxx=x; yyy=y; //zapamiętujemy w globalnych tymczasowych współrzędne od których odległość chcemy mierzyć with(nazwa_obiektu) //przeglądamy wszystkie obiekty nazwa_obiektu w pętli { if(x>granica_lewa && x<granica_prawa && y>granica_gorna && y<granica_dolna) //jeśli nasz obiekt jest w zadanym obszarze... { if(point_distance(xxx,yyy,x,y)<dist) //jeśli nasz obiekt jest bliżej od aktualnie znalezionego { dist = point_distance(xxx,yyy,x,y); //zapamiętujemy nową, mniejszą odległość obj=id; //oraz zapamiętujemy id znalezionego obiektu } } } Na końcu skryptu w zmiennej obj masz id znalezionego obiektu. Tylko pamiętaj, że obj jest zmienną tymczasową. Po zakończeniu skryptu zniknie więc przepisz wartość do innej zwykłej zmiennej. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TO_mek Opublikowano 20 Stycznia 2011 Autor Udostępnij Opublikowano 20 Stycznia 2011 No to inaczej. Czy takie sprawdzanie nie będzie wolniejsze niż sytuacja jaką mam teraz czyli: - jeden obiekt "hero" - dużo obiektów "przeciwnik" (na razie 10 ale docelowo pewnie 100 albo więcej) Obecnie sprawdzam w każdym obiekcie "przeciwnik" odległość od "hero": if (point_distance(x,y,hero_obj.x,hero_obj.y) < gonic) and (abs(y-hero_obj.y) < 30) then { przeciwnik_atakuje_hero(); } gdzie: gonic - to odległość na jaką reaguje przeciwnik (abs(y-hero_obj.y) < 30) - zakres pionowy czyli interesuje mnie tylko pasek ekranu o wysokości +/- 30px przeciwnik_atakuje_hero() - skrypt który powoduje atak na hero (przyspieszenie przeciwnika w kierunku hero) Czyli za każdym razem w stepie każdego przeciwnika wykonuje się zbędny kod a ja chciałem uzyskać by podobny kod był wykonywany tylko w step jednego obiektu hero bo i tak atakować powinien tylko najbliższy przeciwnik ale nie w okręgu tylko w pasie ekranu o wysokości +/- 30px (a szerokości maksymalnej rooma). Jedyny problem to znalezienie tego najbliższego przeciwnika w danym zakresie (bo często będzie sytuacja gdzie będą przeciwnicy dużo bliżej ale na wyższym/niższym piętrze niż znajduje się hero i oni nie mogą atakować przez sufit/podłogę). Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Platyna Opublikowano 20 Stycznia 2011 Udostępnij Opublikowano 20 Stycznia 2011 Kod, który Ci dałem jest w porządku. Myślę, że jak go dasz w stepie to nie będzie to bardzo powolne. Musiałbyś mieć bardzo dużo tych przeciwników. Jak nie ma ich więcej niż, powiedzmy, sto to śmiało możesz użyć tego kodu. Oczywiści dałoby się zrobić to szybciej używając bardziej skomplikowanych algorytmów, ale myślę, że nie ma co się bawić w takie rzeczy. Mój kod działa liniowo do ilości przeciwników. To całkiem nieźle. Jakiś taki pierwszy pomysł, który mi się nasuwa by zrobić to szybciej to dla każdego piętra trzymać posortowaną po współrzędnych x tablicę przeciwników i później algorytmem wyszukiwania binarnego sprawdzić między, którymi 2 przeciwnikami jest hero i wybrać bliższego z nich. Jednak to by się sprawdzało tylko w przypadku gdy porządek w tej tablicy się nie zmienia czyli przeciwnicy nie mogą się wyminąć. Ale naprawdę uważam, że kod jaki podałem jest wystarczający. To nic strasznego jeśli dla każdego przeciwnika zrobi się taką drobnostkę w każdym step. Ewentualnie można go lekko przyspieszyć, np nie wywołując nie potrzebnie 2 razy funkcji point_distance(). GML var xxx; var yyy; var dist; var obj; dist = 1000000000; //Tu będziemy przechowywać dystans to aktualnie najbliższego znalezionego. Na początku jakaś wielka wartość. obj = 0; //Tu będziemy przechowywać id tego najbliższego xxx=x; yyy=y; //zapamiętujemy w globalnych tymczasowych współrzędne od których odległość chcemy mierzyć with(nazwa_obiektu) //przeglądamy wszystkie obiekty nazwa_obiektu w pętli { if(abs(y-yyy) < 30) //jeśli nasz obiekt jest w zadanym obszarze... { d=point_distance(xxx,yyy,x,y) if(d<dist) //jeśli nasz obiekt jest bliżej od aktualnie znalezionego { dist = d; //zapamiętujemy nową, mniejszą odległość obj=id; //oraz zapamiętujemy id znalezionego obiektu } } } Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
pablo1517 Opublikowano 20 Stycznia 2011 Udostępnij Opublikowano 20 Stycznia 2011 Bez sensu sposób. Zaraz dam lepszy. Bez sensu to jest ten post. Weź od razu załóż temat w Zapowiedziach i zapowiedz swój post! Po co się tak ograniczać. Platyna Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się