atarionline.pl Wykrywanie kolizji z playfieldiem - Forum Atarum

    Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

    • :
    • :

    Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

      • 1: CommentAuthor_pepis
      • CommentTime13 Feb 2011 13:02
       
      Witajcie!

      W jaki sposób najsprawniej wykrywać kolizję sprite z tłem? Chodzi mi o to aby moja postać, która ma posiadać pewną "pseudo-inteligencję" będzie sprawnie sprawdzać swoje najbliższe otoczenie, tj. co jest nad nią, pod nią, obok itp. Ekran zbudowany jest na znakach w trybie 04 antica.
      Obecnie mam stworzoną osobną tablicę, która jest jakby osobną mapą ekranu przedstawiającą, który ze znaków ma być przeszkodą, który jest groźny, a który stanowi tylko tło dalszy plan. Procedurka ustala w obrębie którego znaku znajduje się obiekt pmg, następnie przesukuje sporą tablicę. Tablica jest duża, przeszukiwanie jej za każdym razem wiąże się z dużą ilością operacji, nie 8-bitowych na domiar złego.
      Może ma ktoś pomysł jakby można to zrealizować w inny sposób?

      Pozdrawiam,
      Peter
      • 2: CommentAuthorBluki
      • CommentTime13 Feb 2011 14:02
       
      A w jakim języku jest program?
      • 3: CommentAuthor_pepis
      • CommentTime13 Feb 2011 14:02
       
      W assebmlerze
      • 4: CommentAuthornosty
      • CommentTime13 Feb 2011 17:02 zmieniony
       
      A czemu te oprtacje nie są 8-bitowe?
      I czemu "sporą" tablice?

      Zakladam ze Twoja postac ma rozmiar kilkanascie na kilkanacie pixeli. To oznacza ze lezy na powiedzmy 9 - 16 znakach, prawda? I tylko je musisz sprawdzic.

      Ja robie dokladnie tak jak Ty (z tą mapą ekranu wskazującą który znak jest przeszkodą, a ktory jest tlem) i tez w trybie Antic 4.
      Tyle, ze ja wlasnie zaczynam kodowac bardziej szczgolowo: jesli z mapy (ja ją nazywam maską) wynika ze dany znak jest grozny, to chce jeszcze sprawdzac bitowo czy bohater wszedl w kolizje z "groznym bitem" - bo bede mial jeszcze maski dla kazdego znaku.
      I mam nadzieję sie wyrobic robiąc takie sprawdzanie co ramkę.

      BTW. Moze zainteresuje Cie wątek:
      ->link<-

      Jakub wlasnie pracuje nad dodaniem opcji edycji tych "masek" kolizji do EnvisionPC - edytora map ze znakow.
      • 5: CommentAuthor_pepis
      • CommentTime13 Feb 2011 18:02
       
      No tak, moja postać ma 8 pikseli na ok. 20. Zrobiłem kafelki 2x2 znaki (20 w linii) i to wystarcza do określenia kolizji. Tablicę miałem początkową w układzie 1bajt/kafel.
      Teraz chyba przerobię na 1 bit/kafel. Ostatecznie oczywiście pożegnałem się z tym 16 bitowym wariactwem ;).
      Zaczyna to jako tako działać, chociaż wciąż nie mogę się zgrać...
      Dzięki za pomoc!
      • 6: CommentAuthornosty
      • CommentTime14 Feb 2011 20:02
       
      Wcielo moj ostatni post (a moze pomylilem watki), wiec gdyby sie jakism cudem odnalazl to sorki ze sie powtarzam.

      Najpierw chcialem wyjasnic, ze 3 tygodnie temu po raz pierwszy w zyciu uruchomilem duszki w asm, a tydzien temu nauczylem sie wykorzystywac DLI do zmiany kolorow. Wiec raczej nie nalezy mnie pytac o porady w temacie programowania :)

      Ja to robie tak: maske kolizji dla kazdego ekranu (levela) trzymam bitowo. Mam ekran 40x24 znaki co daje 120 bajtow maski. Ale przed rozpoczeciem gry "rozpakowuje" te maske do bufora bajtowego: 1 bajt dla kazdego znaku. To dodatkowe 960 bajtow, ale stac mnie ;) A znacznie przyspiesza testowanie kolizji.
      U Ciebie jak masz kafel 2x2 znaki, bedzie to tylko 240 bajtow.
      Dalej bede pisal tak jak jest u Ciebie, czyli kafel 2x2 znaki i maska jest zrobiona dla kafli.

      I teraz tak: masz pozycje lewego gornego rogu duszka postaci postaci. Ale trzeba to przeliczyc na wspolrzedne ekranu, bo punkt 0,0 dla PMG lezy gdzies daleko poza ekranem.
      Jesli masz ekran 40 znakow - standardowa szerokosc, to od pozycji X playera musisz odjac 48 a potem podzielic przez 8 (2 znaki po 4 pixele kazdy). I juz masz pozycje X postaci wyrazoną w kaflach (czyli w ktorej kolumnie kaflowej jest postac - jej lewy brzeg). Nazwijmy to XK.

      Z pozycją Y jest podobnie, ale to ile linii trzeba odjac zalezy od Twojego DL. Ja mam na poczatku 3 rozkazy $70, i od pozycji pionowej duszka musze odjac 32.
      Jak juz odejmiesz tę stałą, to uzyskaną liczbę dzielisz przez 16 (ilosc pixeli dla 1 kafla) i masz nr linii kaflowej w ktorej lezy gorna krawedz Twojej postaci. Nazwijmy to YK.

      Jesli Twoja maska bajtowa dla kafli lezy od adresu ADR_MASKI, to pierwszy bajt maski, ktory musisz sprawdzic lezy pod adresem:
      ADR_MASKI + 20xYK + XK.

      To kafel na ktorym lezy gorny lewy rog Twojej postaci.
      Musisz jeszcze sprawdzic kilka sasiednich.
      Tu jest maly dzinks: jesli Twoja postac ma 8 pixeli szerokosci i rusza sie plynnie co pixel, to moze lezec na jedym kaflu (ktory ma 8 pixeli szerokosci) albo na 2 kaflach. Wiec nieraz musisz testowac 1 bajt maski, a nieraz 2 sąsiednie.
      Podobnie jest w pionie: 20 pixseli postaci moze lezen na 2 lub 3 kaflach (kazdy ma 16 pixeli szerokosci).
      To ile bajtow maski testowac mozesz wywnioskowac z reszty z dzielenia przez 8 (poziom) lub 16 (pion), o ktorym pisalem wczesniej.

      I to by bylo na tyle... Wykrycie kolizji choc z 1 bajtem maski powoduje ze ruch jest niemozliwy, wiec mozesz przerwac dlsze testowanie.

      U mnie tak to dziala.

      Ale ta metoda ma spore ograniczenie: musisz tak zaprojektowac grafike kafli na ktore nie mozna wejsc zeby byly wypelnione w miare w calosci. Czyli np. bedzie to mur. Bo jak masz kafel 8x16 pixeli, a narysujesz np cienki na 2 pixele słup, to postac zatrzyma sie kilka pixeli przed nim na niewidzialnej granicy kafla, co bedzie glupio i nielogicznie wygladac...

      Powodzenia!
      • 7: CommentAuthor_pepis
      • CommentTime14 Feb 2011 21:02
       
      Dziękuje Nosty. U mnie dokładnie tak samo to wygląda, też baaardzo podobnie ustalam pozycje gracza w mojej mapie kolizji. Nie umiałbym tego równie sprytnie jak ty ospisać:)

      ** Z drugiej strony jak to testujesz jak masz tablice 960 bajtów? Ja mam specjalnie właśnie 240 bajtów aby się pozbyć zabawy z warościami 16 bitowymi **

      Inną metodą, która wpadła mi do głowy, to aby otoczyć każdy "twardy" obiekt pikselami o określonym kolorze, np.colpf2. I wtedy po wykryciu takiej kolizji z obiektem pmg testować jaka dokładnie to kolizja.. Cholerka, trudno znaleźć jakieś podpowiedzi w tym temacie... W mojej grze obiekty latają, są wielokolorowe (multikolorowe sprity opisane w jednym z numerów antica, super to działa - dynamicznie zmieniane pozycje w przerwaniu dli), wchodzą w kolizję z bohaterem i mam masę innych bajerów. A z tymi kolizjami nie mogę sobie sensownie poradzić. Działają, owszem. Ale bardziej jak w BruceLee... Bohater lepi się do platform... Ja bym obecnie potrzebował taki model jak jest np. w Kangaroo, gdzie bohater bardzo precyzyjnie ląduję na końcu podestu, a nie klei się do niego niczym brucelee... ;)
      Dzięki za cenne rady! Pozdrówki
      • 8: CommentAuthornosty
      • CommentTime15 Feb 2011 00:02
       
      No dodawanie liczb 2-bajtowych to koniecznosc i chyba tego nie ominiesz piszac gre :) Musisz chocby jakos wypelniac pamiec ekranu znakami...

      Jak zrobic wyjecie bajtu z maski:

      Przepisujesz gdzies adres ADR_MASKI

      lda #<ADR_MASKI
      sta gdzies
      lda #>ADY_MASKI
      sta gdzies+1

      potem dodajesz do (gdzies,gdzies+1) wartosc 16-bitową przesuniecia,

      a potem mozesz czytac takim trybem:

      ldy #0
      lda (gdzies),y


      Naprawde glupio mi cokolwiek Ci pisac... Bo pewnie co bym nie napisal to bedzie jesli nie zle, to na 99% nieoptymalnie. Lepiej sie uczyc od dobrych niz od innego poczatkujacego.

      Ja korzystam z opisow na Atariki, ze spisu rozkazow 6502, kursu TeBe'go i jakis pojedynczych artkow w Tajemnicach Atari.
      Okazjonalnie jak czegos nie rozumiem to zawracam dupe dobrym programistom jak XXL czy Tebe, ale wstyd mi troche zajmowac im czas.
      • 9:
         
        CommentAuthorjhusak
      • CommentTime15 Feb 2011 00:02 zmieniony
       
      Dokładniej, to dodaje się bajt bardziej znaczący, a mniej wrzuca się do y.

      No i "gdzieś" musi być na stronie zerowej.
      To cóś takiego.

      lda#<adr_maski
      sta 128
      lda@>adr maski
      clc
      adc offset+1;
      sta 129
      ldy offset
      lda (128),Y


      Oczywiście whardkodowany adres 128 tylko dla zobrazowania sytuacji, w rzeczywistości jest to etykieta do adresu na stronie zerowej.
      • 10: CommentAuthorEagle
      • CommentTime15 Feb 2011 19:02
       
      Są jeszcze dwie szybkie metody. ;)
      Możesz zamiast mapy maski użyć inwersu znaków.
      Wtedy mapa sceny jest automatycznie mapą maski.
      Znaki z inwersem używasz do oznaczenia ścian itp.
      Jeden problem jest taki że tracisz piąty kolor. No chyba że go umiejętnie w znakach użyjesz.
      Druga metoda to sprzętowa kolizja z sprita z piątym kolorem.
      Nie trzeba wtedy obliczać x,y znaku ale to się bardziej przydaje do kolizji z obiektami animowanymi na znakach.
      Nie pytaj mnie jak dokładnie to się odczytuje bo zapomniałem ;)
      Ale powoli sobie odświeżam wszystko.
      • 11: CommentAuthornosty
      • CommentTime16 Feb 2011 10:02
       
      A ja w koncu w sprawdzaniu mozliwosci ruchu poszedlem na kompromis:

      Dla znakow na ktorych bedzie leazala postac po planowanym ruchu najpierw w masce mapy sprawdzam czy znak jest oznaczony jako 0 - "mozna przjsc" czy jako 1 - "nie calkiem mozna przejsc".
      Jesli jest 1 to nie bawie sie w maski bitowe znakow tylko pobieram definicje znaku z zestawu i sprawdzam bitowo: przyjmuje ze jak jest tlo (00) to mozna wejsc na ten pixel, a jak kolor (01,10,11) to nie.
      Oczywiscie sprawdzam tylko te pixele definicji znaku, na ktorych "ma zamiar" lezec postac po planowanym ruchu.

      Działa miodnie, choc procedura wyszla mi sążnista i musze pooptymalizowac.
      • 12:
         
        CommentAuthorKaz
      • CommentTime18 Mar 2011 18:03
       
      Rany, co to sie porobilo. Kazdy pisze sobie gry i to jeszcze w asemblerze...! :)