Skocz do zawartości

Prosty trick na sprawdzanie która instancja jest na wierzchu :)


Rekomendowane odpowiedzi

Witam GMClany,

chciałbym Wam przekazać banalny "trick" na sprawdzanie która instancja jest wyżej, mimo takiego samego depthu.

Większość z Was pewnie o tym wie, ale sam kilka lat temu się nad tym głowiłem, a dopiero dziś gdy znów stanąłem przed tym problemem uświadomilem sobie jak proste jest rozwiązanie :P

 

Problem:

Mamy kilka instancji o takiej samej wartości zmiennej Depth. Mimo to naturalne jest to, że jeden jest wyżej inny niżej.

Jak określić który z nich jest w takim razie na dole, a który na górze?

 

Trochę teorii:

Depth jak wiemy określa to które instancje maja być na wierzchu, a które pod spodem czym większy depth, tym niżej będzie instancja. Co się dzieje w takim razie gdy depth jest taki sam, czy gm sobie jakoś to ustala specjalnie? Otóż absolutni nie, gm po prostu robi co ma robić - rysuje je z tym samym depthem. I tu pojawia się pytanie dlaczego, więc coś jest wyżej, a coś niżej? No więc zróbcie sobie sami taki eksperyment, rysując dwa prostokąty nachodzące na siebie w dowolnym języku programowania(może być i gm w draw w jednej instancji). Ten który narysujemy później po prostu zakryje ten pierwszy. Jest w tym jakaś logika prawda?

Co to ma w takim razie do naszego problemu? No więc GM robi dokładnie to samo. Rysuje instancje po prostu po kolei i to jest właśnie klucz do rozwiązania tego problemu ;) A kolejność instancji określa zmienna id... coś już Wam świta? Wystarczy sprawdzić która instancja ma najmniejsze id i już wiemy która jest na wierzchu :)

 

Rozwiązanie:

skrypt porównujący dwie instancje i zwracający tą na wierchu:

GML
///instance_check_real_depth(instance, instance)

if(argument0.depth != argument1.depth)

{

if(argument0.depth < argument1.depth)

{

return argument0;

}else{

return argument1;

}

}else{

if(argument0.id < argument1.id)

{

return argument0;

}else{

return argument1;

}

}

 

@ps: po prostu starałem się zrobić mini-tutka dla początkujących i opisać to jak najbardziej zrozumiale, żeby nie napisać tylko kodu, ale także wytłumaczyć dlaczego tak się dzieje. Nie wiem czy zrobiłem to dobrze dlatego liczę na Wasze opinie ;)

Mam nadzieję że komuś kiedyś się to przyda ;p

Aha i wiem że możnaby to rozpisać w jednym ifie, ale myślę że tak jest o wiele czytelniej dla początkującego użytkownika ;p

Odnośnik do komentarza
Udostępnij na innych stronach

Fajnie :)

 

Popracował bym trochę nad czytelnością kodu, wiem że niby piszesz dla początkujących, ale w ten sposób raczej nie powinno się pisać - uczmy od razu lepszych rozwiązań.

 

Proponuję zabawę: ktoś chciałby/spróbować napisać to ładniej/krócej.

 

Twój kod jest oczywiście logiczny i będzie działał, ale może ktoś pokaże inne sposoby zapisu (np używając 1 raz return).

Odnośnik do komentarza
Udostępnij na innych stronach

Fajnie :)

 

Popracował bym trochę nad czytelnością kodu, wiem że niby piszesz dla początkujących, ale w ten sposób raczej nie powinno się pisać - uczmy od razu lepszych rozwiązań.

 

Proponuję zabawę: ktoś chciałby/spróbować napisać to ładniej/krócej.

 

Twój kod jest oczywiście logiczny i będzie działał, ale może ktoś pokaże inne sposoby zapisu (np używając 1 raz return).

Usiäde do kompa to napiszę i drugą wersję kodu, w jednym return ;p

 

@edit o to Ci chodziło? Nie testowałem, ale mam nadzieję że działa dobrze

GML
///instance_check_real_depth(instance, instance)

if((argument0.depth != argument1.depth && argument0.depth < argument1.depth) || (argument0.id < argument1.id && argument0.id < argument1.id))

{

return argument0;

}else{

return argument1;

}

Odnośnik do komentarza
Udostępnij na innych stronach

Tak też można.

GML
if argument0.depth=argument1.depth return min(argument0,argument1);

else if argument0.depth < argument1.depth return argument0;

else return argument1;

 

Mniej w oczy kole i korzysta z tej samej logiki.

Odnośnik do komentarza
Udostępnij na innych stronach

Tak też można.

GMLif argument0.depth=argument1.depth return min(argument0,argument1);

else if argument0.depth < argument1.depth return argument0;

else return argument1;

 

Mniej w oczy kole i korzysta z tej samej logiki.

Tak, ale więcej ifów i w dodatku funkcja min raczej powoduje że jest to mniej optymalne rozwiązanie, ale to już by musiał ktoś sprawdzić ;p

Odnośnik do komentarza
Udostępnij na innych stronach

Test wykonany poprzez wykonanie każdego z kodów po 30 tysięcy razy (Mikrosekundy):

Test #1

Max: 19698

LeD: 15277

Test #2

Max: 20191

LeD: 14837

Test #3

Max: 19748

LeD: 15226

Test #4

Max: 20021

LeD: 15076

Test #5

Max: 19868

LeD: 15270

 

 

Obawiam się, że mój jest szybszy.

 

Kod (GMS): http://puu.sh/sb5mt/3b2ddb200a.gmz

 

Edit: Zapomniałem dodać: Każde and czy or tworzy wirtualnie ify. Technicznie użyłeś ich wiele wiele więcej niż ja.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Dlatego właśnie w GM2 wprowadzono layery w roomach, żeby GM nie musiał sortować dephtów, a potem ID. Odpada jedno sortowanie (znaczy jest, ale tylko jak tworzymy nowy layer albo korzystamy z depth).

 

Edit: Vader, ostatniego "else" nie musi być. Środkowego też niekoniecznie, pytanie, jak to wpływa na czas wykonania.

Odnośnik do komentarza
Udostępnij na innych stronach

Edit: Vader, ostatniego "else" nie musi być. Środkowego też niekoniecznie, pytanie, jak to wpływa na czas wykonania.

Racja, przeciez i tak return konczy wykonywanie kodu. Jakis mi z glowy wypadlo :P

 

No a co jak się nałożą obiekty z tego samego layeru na siebie? :P

To pewnie po ID sortuje.

 

 

Edit:

Z ciekawości sprawdziłem wersję Gnyska, musiałem podkręcić cykle z 30K do 300K i ilość prób z 5 do 20 żeby móc zobaczyć różnicę, bo inaczej mają zbyt podobne czasy.

Rzeczywiście wydaje się być szybszę. Jakby ktoś miał pomysł na jeszcze mocniejsze wyciśnięcie tej funkcji, zamieniam się w słuch.

Edit 2:

Po kilku chwilach kopiujwklejki po usunięciu else jest średnio o 0.8% szybciej.

Tak, zrobiłem to z czystej ciekawości :D

Odnośnik do komentarza
Udostępnij na innych stronach

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ę
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...