MaxGaming Opublikowano 8 Listopada 2016 Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
Uzjel Opublikowano 8 Listopada 2016 Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
MaxGaming Opublikowano 8 Listopada 2016 Autor Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
I am vader Opublikowano 8 Listopada 2016 Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
MaxGaming Opublikowano 8 Listopada 2016 Autor Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
I am vader Opublikowano 8 Listopada 2016 Udostępnij Opublikowano 8 Listopada 2016 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 Więcej opcji udostępniania...
Administratorzy gnysek Opublikowano 9 Listopada 2016 Administratorzy Udostępnij Opublikowano 9 Listopada 2016 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 Więcej opcji udostępniania...
I am Lord Opublikowano 9 Listopada 2016 Udostępnij Opublikowano 9 Listopada 2016 No a co jak się nałożą obiekty z tego samego layeru na siebie? :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am vader Opublikowano 9 Listopada 2016 Udostępnij Opublikowano 9 Listopada 2016 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 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ę