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?
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ę.
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!
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...
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
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.
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.
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.