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
     
    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
     
    A w jakim języku jest program?
    • 3: CommentAuthor_pepis
    • CommentTime13 Feb 2011
     
    W assebmlerze
    • 4: CommentAuthornosty
    • CommentTime13 Feb 2011 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
     
    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
     
    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
     
    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
     
    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 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
     
    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
     
    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
     
    Rany, co to sie porobilo. Kazdy pisze sobie gry i to jeszcze w asemblerze...! :)