Atari Wirus Invaders 2020 Warsztaty online 2020 Do zrobienia: - ------------------- Pliki: Atari_Virus_Invaders_Warsztat_wer00.ATR Atari_Virus_Invaders_Warsztat_wer01.ATR Atari_Virus_Invaders_Warsztat_wer02.ATR Atari_Virus_Invaders_Warsztat_wer03.ATR Atari_Virus_Invaders_Warsztat_wer04.ATR Pliki Atari: TEST ACT 001 S ACT 007 - główny plik gry CWICZ1 ACT 005 CWICZ2 ACT 005 - przykład animacji na przykładzie setblock() i moveblock() CWICZ3 ACT 006 - przykład animowania setblock - przesuwanie obrazu za pomocą CWICZ4 ACT 010 - przykład cięcia duszków jak w grze Warhawk CWICZ5 ACT 014 - wstępna praca nad czołówką gry i podkolorowanie księżyca (od wer. 1,0) TITLE FNT 009 TITLE SCR 004 VIRUS FNT 005 VIRUS SCR 005 T3 FNT 009 - Title w wersji 03 T3 SCR 004 CWICZ6 ACT - dwie procedury do wyświetlania danych losowych i odtwarzania RANDOMIZE() i SZUM() CWICZ7 ACT 005 - player FX CWICZ8 ACT 002 - test wydajności Print() oraz TX() [wer. 2,2] CWICZ9A ACT 008 - demo gry typu TOMCAT/ZYBEX [od wer. 2,5] CWICZ9B ACT 010 - demo gry typu TOMCAT/ZYBEX z wirtualnym ekranem [od wer. 2,5] CWICZ9C.ACT 012 - -"- inny sposób rysowania przeciwników [ od wer. 2,6] CWICZ9D.ACT 014 - test wydajności kolizji 41 przeciwników z 20 pociskami gracza [od wer. 2,9] ten^ plik tylko w "Atari_Virus_Invaders_Warsztat_wer29 w2.ATR" CWICZ9E.ACT - szalona wersja algorytmu kolizji (z CWICZ9C.ACT) [od wer. 3,1] CWICZ9F.ACT - nowa wersja kolizji - dobrze działa, choć tylko dla 1 pocisku [od wer. 3,2] CWICZ9K.ACT - zmiana kolorów ramki obrazu w czasie kompilacji programu [od wer. 3,2] -------------------- Wersje: Wer. 0,1: - Wer. 0,2: - Wer. 0,3: - Wer. 0,4: - Wer. 0,5: - Wer. 0,6: - losowe dwa rodzaje gwiazd w tle, co ziwiększa ich gęstość w tle rozgrywki - losowe przesunięcie danych tła rozgrywki, które są wczytywane z pliku + różne drobne Wer. 0,7: - dostosowanie parametrów przesuwania wczytywanego pliku - pętla dorysowująca gwiazdy do grafiki tła - do pętli dodany został dodatkowy kod, który dodaje z inną częstotliwością gwiazdy bardzo ciemne - zabawy w rozmnażanie duszków - plik CWICZ4.ACT Wer. 0,8: - Rysowanie pojazdu gracza - wstępne animowanie go - sposób wypełniania duszków zawartością systemowego zestawu znaków czyli alternatywa do tego co było rysowane za pomoca procedury SETBLOCK - w ramach ćwiczeń (CWICZ4.ACT): - powieliliśmy ilość animowanych obiektów - metodą "Copy+paste" - wyjaśniłem rolę systemowych przerwań VBLK dla rej. kolorów cieni dla duszków - zwiększyliśmy ilość wyświetlanych duszków sprzętowych do 6 w linii;) ^ tego nie zapisałem w ATRze więc to było zaprezentowane jedynie na warsztacie Wer. 0,9: - dodajemy zmienną SY - przepisaliśmy DL pod adres $9B00 - warunki animacji pojazdu gracza - wstępna wersja warunków: IF X>50 THEN IF JO=11 THEN X==-2 FI FI IF X<200 THEN IF JO=7 THEN X==+2 FI FI - wstępną animację pocisku gracza Wer. 1,0: - Dokończyliśmy animowanie pocisku gracza - dodanie pliku CWICZ5 ACT 014 - tworzenie wstępnej wersji czołówki gry - podkolorowanie księżyca - aby osiągnąć efekt bryły za pomocą odcieni - procedura MOON() - podkolorowanie tła - przykładowe - procedura BARY() - w proc BARY() mamy dwie alternatywne wersje barów w tle obrazka: należy sobie aktywować dwie wersje rysowania barów: 1: GG=Q1 Q1==+2 2: GG=Q1+9 Q1==+16 W miejscu "+9" można zmieniać odcień kolorów na całym ekranie (od 0-14) - klawiszem SELECT lub OPTION można wyłączyć efekt podkolorowania (proc MOON() ) Wer. 1,1: - Alternatywna wersja obsługi wystrzeliwania pocisku gracza i jego animacji z wykorzystaniem zmiennej sterującej PG (Pocisk Gracza) - bo w obecnej wersji gry udało się to zrobić bez tej zmiennej sterującej: IF PG=1 THEN SY==-2 ZERO(DD(4)+SY,8) IF SY>5 THEN SETBLOCK(DD(4)+SY,4,48) FI IF SY<5 THEN PG=0 FI FI IF FIRE=0 AND PG=0 THEN ZERO(DD(4)+SY,4) SX=X+3 SY=Y-8 PG=1 FI - to^ dla zmiennej BYTE PG=[0] - Przykład tego jak można robić efekty specjalne za pomocą poruszania obrazem podczas eksplozji - zmiany pierwszego rozkazu DL jako elementu poruszającego obrazem - oraz zmiana DL tak aby były tam 2 rozkazy i zmiana ich obydwu ...oraz zajawki na inne efkety specjalne - plik CWICZ5.ACT: - dodaliśmy kolejny odcień na księżycu (26 kolorów) - prawidłowe wyświetlenie napisu "Virus" - dodaliśmy obsługę duszków w czołówce gry - dodaliśmy migający punkt, animowanych przez całą długość obrazu - zmienia kolor losowo - zaproponowałem wiele przykładów ćwiczeń na długi weekend - tak aby każdy mógł zrobić to co go najbardziej zainteresowało;) Wer. 1,2: (oglądaliśmy programy i efekty zrobione przez uczestników) - plik CWICZ5.ACT: - przesunęliśmy latający piksel nieco niżej (o 32 piksele) - na prośbę Kaza - znalazłem buga w monitorze Action! ;))) - dodaliśmy efekt miotającego się wirusa - który jest jednocześnie kropką nad "I" - kilka alternatywnych wersji jego animowania oraz zmian kolorów (...) P(704)=$B8 D1=88 Q2=0 WHILE K<>28 DO Q2==+8;IF Q2>100 THEN Q2=0 FI MOVEBLOCK(DD(0)+58,$E000+264+Q2,8) ;MOVEBLOCK(DD(0)+58,$F000+264+Q2,8) FOR Q3=0 TO 7 DO ;P(DD(0)+58+Q3)=R OD FOR Q3=3 TO 4 DO P(DD(0)+58+Q3)=R OD (...) Wer. 1,3: - plik CWICZ5.ACT: - zmiany kolorów logotypu "Virus": BYTE ,Q,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8 BYTE ARRAY ,TC=[ 6 8 10 10 12 12 12 14 14 12 10 12 14 14 14 12 10 12 14 14 14 12 12 12 10 10 8 6 4 2 0 2 4 255 ] kod: (wkleić po RSYNC(66)G08=$8F P($D409)=$94 G10=$88 ) Q7=Q8 ;Q8==+1 IF TC(Q8)=255 THEN Q8=0 Q7=0 FI FOR Q5=1 TO 40 DO Q7==+1 Q6=TC(Q7) IF Q6=255 THEN Q7=0 Q6=TC(0) FI G10=$80 + Q6 D4A=1 OD G10=0 - wczytaliśmy nową wersję plików graficznych z G2F - wprowadziliśmy niezbędne zmiany do programu - usunęliśmy dolną linię w trybie 2 (0 w terminologii systemu operacyjnego) poprzez zmianę rejestrów kolorów Wer. 1,4: - dodajemy tablicę BYTE PS która ma dwie funkcje: 1. Status przeciwników w rozgrywce 2. Różne dane i paramtery w czołówce gry Ideksy tablicy PS -- DLA CZOŁÓWKI GRY -- 0-9 to pary współrzędnych x i y dla animacji wirusa x są to indeksy parzyste y są to indeksy nieparzyste 10 - wskazuje aktualną współrzędną dla animacji wirusa 11 - licznik czasu (ramek obrazu generowanego przez procesor ANTIC) - sterowanie zmianami współrzędnych - wprowadziłem pojęcie: ramka - jako jednostka odliczania czasu;) - liczby Mersenne'a: 1,3,7,15,31,63,127 - losowanie wartości z zakresu pomiędzy liczbami Mersenne'a: PS(11)=(R&31)+(R&15) tu z zakresu między "&31" a "&63" itp. Wer. 1,5: - Cwiczyliśmy sobie liczby pseudolosowe w pliku CWICZ6 ACT - Uwaga: kod napisany pod cartridge Action! w wer. atari_action_rom_v3_6 - procedury do wyboru: RANDOMIZE() i SZUM() RANDOMIZE() ma możliwość pracy w dwóch trybach graficznych (do wyboru), tablica DISS: 76 0 0 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 65 0 0 i 77 0 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 - oraz oddzielne palety kolorów, każda dla każdego z tych^ dwóch trybów: ;15 TR. GR. PALETA: P(708)=$04 P(709)=$08 P(710)=$0C i ;8 TR. GR. PALETA: P(709)=$0F P(710)=$00 Wer. 1,6: - Title screen: - zmodyfikowaliśmy wcześniejszy kod animowania pojazdu kosmicznego wcześniejsza uproszczona, cykliczna wersja to: Q1==-1 S1=Q1 P(711)=(R&15) oparta o zmienną Q1. - teraz usuwamy ten kod i zwalniamy zmienną Q1 - teraz wszystko będzie na tablicach animowane (tablica PS(12-19) ), będzie parametryzowane (prędkość, współrzędne, czas itp.) - Animowane punkty (statki kosmiczne) - PS(12) - współrzedna x 1 obiektu (statek kosmiczny) to jest współrzędna sprzętowego pocisku S1 w pierwszej połowie obrazu (przed logotypem) - PS(13) - współrzędna x 2 obiektu (po grafice księżyca i przed logotypem) - PS(14) - prędkość poruszania się 1 ob. - PS(15) - prędkość poruszania się 2 ob. - PS(16) - kierunek poruszania 1 ob. =0 - nie istnieje =1 w prawo =2 w lewo - PS(17) - kierunek poruszania 2 ob. =0 - nie istnieje =1 w prawo =2 w lewo - PS(18) - współrzędna y 1 obiektu (statek koszmiczny) - PS(19) - współrzędna y 2 obiektu (-"-) Duży obiekt 3D (statek kosmiczny): - PS(20) - status obiektu 3D (statek kosmiczny) =0 - nie istnieje =1 - istnieje - PS(21) - licznik - PS(22) - poruszanie się I - PS(23) - poruszanie się II - PS(24) - współrzędne x obiektu 3D - PS(25) - współrzędne y obiektu 3D - PS(26) - kolor - PS(27) - prędkość Wer. 1,7: - Dzielimy tryb wyświetlania duszków w połowie wysokości obrazu i ustawiamy: 623 - 53275 ($D01B) = 36 - urposzczony przykład generowania efektu błyskawicy - niezapisany do pliku obrazu ATR - wstęp do bitów, systemu binarnego oraz przesunięć bitów w Action! Wer. 1,8: - dodaliśmy w głównej pętli czołówki gry zerowanie rej. 77 co wyłącza systemowy wygaszacz ekranu - dodajemy $D01B =17 przed napisem "invaders" co powoduje, że na poziomie linii z tym napisem (w trybie 0 lub 2) duszki będą wyświetlane nad tą linią (ale wyżej tam gdzie jest napis "Virus" będą pod) - Dodajemy animowanie 3 duszka - jako drugi wirus - dane wirusa są kopiowane z pierwszego. PS(30) - stan wirusa 2. na duszku 3 =0 - nie istnieje =1 - istnieje - porusza się w lewo =2 - istnieje - porusza sie w prawo PS(31) - wsp. X duszka PS(32) - wsp. Y duszka PS(33) - predkosc poruszania sie - anomowanie obiektu 3D (statek kosmiczny) - PS(20) - status obiektu 3D (statek kosmiczny) =0 - nie istnieje =1 - istnieje =2 - przyspiesza LSH - modyfikujemy opis: - PS(22) - zapamiętujemy wartość max (modyfikowaną) dla PS(21) - czyli licznik dzięki temu licznik odlicza za każdym razem różne ilości ramek: PS(21)==-1 IF PS(21)=0 THEN PS(26)==+2 PS(22)=PS(22) RSH 1 PS(21)=PS(22) FI - PS(23) - rysowanie kolejnych wielkości obiektu 3D w drugim trybie - tym największym i najszybszym (dla PS(20)=2) Wer. 1,9: - dodaliśmy zmianę koloru obiektu 3D - zamieniliśmy mnożenie *16 w losowaniu koloru na LSH 4 czyli przesunięcie bitowe o 4 bity. - skróciliśmy animowanie obiektu 3D pod koniec fazy animowania poprawiło to efekt głębi 3D czyli zamiast: IF PS(24)>200 THEN PS(20)=0 FI jest IF PS(23)=5 THEN PS(20)=0 FI - wstęp do: - wykresów wydajności rastra - dzwięków, ze zmianą obwiedni, częstotliwości i brzemiania POKEYa Wer. 2,0: - Optymalizacja wyznaczania losowwego koloru obiektu 3D PS(26)=(R&15)LSH 4;$B0;+(R&7)+6 (R&15): %11110000 PS(26)=(R&(16+32+64+128)) PS(26)=(R&(240)) %00001111 %0 0 0 0 1 1 1 1 0 0 0 0 16 32 64 128 - obiekt 3D: - 3 ostatnie (największe) klatki animacji są teraz zbudowane z wartości losowych ELSEIF PS(23)=2 THEN ; SETBLOCK(QQ,8,255) FOR Q4=0 TO 7 DO P(QQ+Q4)=R OD ELSEIF PS(23)=3 THEN P(53257)=1 ; SETBLOCK(QQ,16,255) FOR Q4=0 TO 7 DO SETBLOCK(QQ,2,R) QQ==+2 OD ELSEIF PS(23)=4 THEN P(53257)=3 ; SETBLOCK(QQ,32,255) FOR Q4=0 TO 7 DO SETBLOCK(QQ,4,R) QQ==+4 OD FI Wer. 2,1: - Cwiczenie7 plik: CWICZ7 ACT 005 - player FX - instrukcja Sound + efekty Wer. 2,2: - Cwiczenie8 plik: CWICZ8 ACT 002 - szybki odpowiednik print(): PROC TX(BYTE X,Y BYTE ARRAY T) - Uwaga! Wartości tablicy FY() są niezgodne z tymi które są używane w grze. aby wykorzystać tę procedurę w grze i czołówce, należy zmienić procedurę na: PROC TX(BYTE X,Y BYTE ARRAY T) BYTE X1,Y1,D CARD AD1,AD2 D=T(0) AD1=EKR+X+(FY(Y)) AD2=PEEKC(@T)+1 MOVEBLOCK(AD1,AD2,D) [96] - test wydajności obu - wykresy wydajności rastra - przeglądaliśmy programy uczestników - omówienie procedur Zbytiego: PROC TerPoke=*(BYTE v) PROC ElmPoke=*(BYTE v) PROC ElmPokeC=*(CARD v) - oszczędność 12 cykli względem POKE() z biblioteki Action! Wer. 2,3: - CWICZ8.ACT - kolejne testy wydajności - szczególowe testy wydajności systemowych procedur PRINT() - test procedur: BYTE FUNC ASCtoINT =* (BYTE ascii) PROC Write=* (BYTE x,y,BYTE ARRAY string) PROC CWrite (BYTE y,BYTE ARRAY string) PROC WriteC (BYTE x,y,CARD val) PROC WriteI (BYTE x,y,INT val) PROC WriteB (BYTE x,y,BYTE val) ^ podlinkował nam to Barman biblioteka jest autorstwa: Carsten Strotmann ("Fast Screen IO") first Version: 21.02.90 last change: 20.11.91 - wstępna wersja superszybkiego rysowania i naliczania SCORE do gry Wer. 2,4: - CWICZ8.ACT - kolejne testy i optymalizacje - nowe dwie metody score - jedna super wydajna - będzie do gry Virus Invaders zajmuje ~1 linię rastra - na linii z obrazem jest to ponad 1 linia rastra Wer. 2,5: - CWICZ8.ACT - Dodałem kolejne testy, które pokazują dwie najbardziej wydajne metody w realnym wykorzystaniu (na ramkę) oraz przy max wydajności jaką zabiera dany algorytm - kolejne pratyczne uwagi odnośnie wykresów wydajności rastra - pokazałem różnice w wydajności z generowaniem obrazu przez ANTIC oraz bez - dodałem test, który pokazuje wykres rastra bez obrazu, czyli na dole, gdy obraz już nie jest generowany przez ANTIC. - dodałem dwa nowe ćwiczenia: CWICZ9A,ACT CWICZ9B.ACT Jest to demo strzelanki, stworzone w ~35 minut. Ma to być dynamiczna strzelanka typu TOMCAT/Zybex. Można dzięki temu przetestować wykresami wydajnosci rastra, jak wygląda rysownie wielu, dzużych obiektów za pomocą procedury TX(...) wersja "A" nie kasuje przeciwników wersja "B" też nie kasuje, ale buduje sobie na DL wirtualny obraz, który w sposób sprzętowy rozwiązuje problem wyłaniania sie obiektów (przeciwników) oraz chowania się z drugiej strony, gdy wylecą za ekran. Wer. 2,6: - dalsze prace nad Cwiczeniem9x - optymalizacja animowania pocisków gracza - zwiększenie ilości pocisków 2 razy - przy tej samej zajętości CPU;) - dodanie pliku: CWICZ9C.ACT - wersja, która nie rysuje wszystkich przeciwników co ramkę, ale wtedy gdy są przesuwani - czyli jedni co 4 ramki drudzy co 2 ramki - program stracił stabilność... trzeba uważać, jeśli został uruchomiony (najlepiej nie zapisywać nic do ATR) Wer. 2,7: - poprawienie błędu w programie. - zmiany wprowadzone w plikach: CWICZ9B.ACT CWICZ9C.ACT teraz program jest stabilny - rozwijamy pomysły w pliku CWICZ9C.ACT - dodanie zmiennej RA1 - odliczającej ramki parzyste i nieparzyste - zm. RA1 jest używana dla animowania przeciwników małych - szybkich - po konsultacjach z uczestnikami, zmieniliśmy, że dużych przeciwników animuję co 4 ramki a nie co 3 jak wcześniej miałem RA==+1 IF RA=4 THEN RA=0 FI - przepisuję cały system animowania do nowszej wersji (w poprzedniej jest tylko wstępna wersja) - zamiana kodu na dwie pętle, każda dla każdego typu przeciwnika - zmiana metody wyznaczania czasu i pozycji pojawiających się przeciwników - obecnie wydajność jest bardzo dobra;) wszystko wyrabia się w ramce;) Pętla dużych przeciwników: FOR Q=RA TO 14 STEP 4 DO Pętla małych przeciwników: Q1=20+RA1 FOR Q=Q1 TO 28 STEP 2 DO 24 przeciwników max - wyjaśnienie działania XOR - jest obecnie używane: RA1==XOR 1 - skopiowana aktualna praca do pliku Atari_Virus_Invaders_Warsztat_wer27 w1 w podstawowym pliku kolejne zmiany, testy itp. - CWICZ9C.ACT: - w kolejnej wersji zmieniam sposób pojawiania się dużych przeciwników - tak aby pojawiali się w pionowych seriach - teraz pojawia się ich dużo oraz nie wchodzą na siebie - powieliłem kod, aby zwielokrotnić (na szybko) Wer. 2,8: - tworzę dodatkowy plik: Atari_Virus_Invaders_Warsztat_wer28 w1.ATR - tu^ jest modyfikacja pliku CWICZ9C.ACT - jest tutaj zwiększona ilość przeciwników na ekranie: 29 przeciwników dużych oraz 9 przeciwników małych to^ daje naprawdę ogromny tłok na ekranie;)) - w pliku podstawowym: Atari_Virus_Invaders_Warsztat_wer28.atr - dodałem nowy, animowany obiekt, i uczestnicy mieli odgadnąć co to;) - nikt nie zgadł;) - zaprezentowałem nowy, bardziej kontrastujący wygląd pocisków gracza. Nie zapisałem tego do ATRa Wer. 2,9: - sporo informacji dla początkujących + dodatkowe plany na następny dzień;) - w pliku: Atari_Virus_Invaders_Warsztat_wer29.ATR CWICZ9C.ACT - skończyłem dodawanie ognia - poprawiłem animację - dodałem efekt migania 25 Hz, jako złudzenie przezroczystości lub dodatkowego koloru;) - w pliku: Atari_Virus_Invaders_Warsztat_wer29 w2.ATR - zwiększyłem ilość przeciwników dużych z 29 do 32. (czyli jest w sumie 41 przeciwników ;) - chyba sprawdzić;) ) cały czas wyrabia się w ramce - założyłem nowy plik: CWICZ9D.ACT 014 - wstępna wersja kolizji wszystkich przeciwników z pociskami gracza pocisków gracza jest 20, a przeciwników jest 41 - wyłączyłem animowanie większości obiektów, ale pozostały wszelkie inne operacje na nich - nadal istnieją, poruszają się itp. - zyskałem ogrom wydajności - wyłączyłem sporo wykresów rastra oraz RSYNC() - ostatnie RSYNC() przesunąłem - wstępna wersja sprawdzania kolizji na razie odpala wszystkie iteracje 3 pętli, ale sprawdza jedynie istnienie danego typu obiektu, czyli pocisków gracza oraz przeciwników - działa to baaardzo, baaardzo wolno;)) czas: chyba 1,5 ramki... - jeśli zmniejszy się ilość pocisków do np. 5 to wtedy całość się bez problemu wyrabia w ramce (mniej niż pół ramki) ...co i tak jest bardzo, bardzo złym wynikiem, bo gdzie reszta kodu, która ma animować przeciwników itp.? - dodałem wyświetlanie wykresów rastra do tych (wstępnych) kolizji + dodałem zmianę również koloru tła obrazu, dzięki czemu lepiej widać wykresy wydajności rastra Wer. 3,0: - w pliku: Atari_Virus_Invaders_Warsztat_wer30 w3 CWICZ9D.ACT: - dokończyłem kolizje dla przeciwników dużych i małych. tu wersja z małą ilością pocisków gracza i małą ilością przeciwników, ale wyrabia się wszystko w ramce (włącznie z rysowaniem obiektów itp.) (tu jest cała pętla główna, ale tylko jako wzór wszystkich parametrów pętli, kolizji itp. - gdyby ktoś chciał osiągnąć podobny rezultat) WHILE K<>28 DO ;RSYNC(100);D4A=1 RA==+1 IF RA=8 THEN RA=0 FI ;RA1==+1 IF RA1=2 THEN RA1=0 FI RA1==XOR 1 ;GG=8 ;PRZECIWNICY: IF PO>0 THEN PO==-1 FI FOR Q=RA TO 3 STEP 8 DO GG=$BC IF PX(Q)=0 THEN IF R<129 THEN ;IF PO=0 THEN PX(Q)=50 ; PY(Q)=(R&15)+(R&3) ; PR(Q)=R&1 ; PR(Q)=0 PO=40 PY(Q)=(R&15)+6 Q1=Q+3 IF Q1<14 AND PX(Q1)=0 THEN PX(Q1)=50 PY(Q1)=PY(Q)+3 IF PY(Q1)>20 THEN PX(Q1)=0 FI FI Q1=Q+6 IF Q1<14 AND PX(Q1)=0 THEN PX(Q1)=50 PY(Q1)=PY(Q)+6 IF PY(Q1)>20 THEN PX(Q1)=0 FI FI Q1=Q+9 IF Q1<14 AND PX(Q1)=0 THEN PX(Q1)=50 PY(Q1)=PY(Q)+9 IF PY(Q1)>20 THEN PX(Q1)=0 FI FI FI ELSE ;IF RA=0 THEN ;IF PR(Q)=0 THEN PX(Q)==-1 TX(PX(Q),PY(Q)," FMMGNNNF ") TX(PX(Q),PY(Q)+1,"TA D S RY ") TX(PX(Q),PY(Q)+2," GNUUM NF ") ;FI ;FI FI OD ;MALI: Q1=40+RA1 FOR Q=Q1 TO 45 STEP 2 DO GG=$B4 IF PX(Q)=0 THEN IF R<50 THEN ;IF PO=0 THEN PX(Q)=50 ; PY(Q)=(R&15)+(R&3) ; PR(Q)=R&1 ; PO=40 ; PO=4 PY(Q)=(R&15) FI ELSE ;IF PR(Q)=1 AND (RA=0 OR RA=2)THEN PX(Q)==-1 ;ELSE TX(PX(Q),PY(Q), "H J ") TX(PX(Q),PY(Q)+1,"RT ") TX(PX(Q),PY(Q)+2,"J H ") IF PX(Q)<7 THEN PX(Q)=0 FI ;FI FI OD GG=0 ;RSYNC(12);D4A=1 D4A=1 GG=$86 G10=4 D4A=1 FOR Q=0 TO 4 DO IF PGX(Q)>0 THEN ;TX(PGX(Q),PGY(Q)," T") FOR Q1=0 TO 2 DO GG=$86 IF PGX(Q)PX(Q1) AND PGY(Q)>=PY(Q1) AND PGY(Q)<=PY(Q1)+2 THEN PU1==+2;TPU() PGX(Q)=0 FI FI OD FOR Q1=40 TO 45 DO GG=$B4 IF PGX(Q)PX(Q1) AND PGY(Q)>=PY(Q1) AND PGY(Q)<=PY(Q1)+2 THEN PU1==+2;TPU() PGX(Q)=0 FI FI OD FI OD GG=0 G10=0 ;GRACZ: ;RSYNC(44) RSYNC(0) GG=$72 IF JO=14 AND Y>1 THEN ZERO(EKR+X+FY(Y+1),5) Y==-1 FI IF JO=13 AND Y<21 THEN ZERO(EKR+X+FY(Y),5) Y==+1 FI TX(X,Y ," LUG ") TX(X,Y+1," OUF ") GG=0 GG=14 IF FIRE=1 THEN IF PGX(PG1)=0 AND R<150 THEN ;IF PGX(PG1)=0 THEN PGX(PG1)=X+4 PGY(PG1)=Y+(R&1) PGA(PG1)=EKR+X+4+FY(Y+(R&1)) PG1==+1 IF PG1>4 THEN PG1=0 FI FI GG=$B6 FI FOR Q=0 TO 4 DO IF PGX(Q)>0 THEN ;TX(PGX(Q),PGY(Q)," T") ;P(PGA(Q)-1)=0 P(PGA(Q))=84 POKEC(PGA(Q),$5400) PGA(Q)==+1 PGX(Q)==+1 IF PGX(Q)>50 THEN ;TX(PGX(Q),PGY(Q)," ") PGX(Q)=0 FI FI OD GG=0 ;;;;; ;PU1==+6 TPU() OD K=42 GRAPHICS(0) [96] - zastosowana została optymalizacja, czyli w jednym IF zawarte sprawdzanie czy przeciwnik istnieje, wraz z wstępnym sprawdzaniem kolizji: IF PGX(Q)PX(Q1) wykorzystałem, że PX(Q1) jest większe od 0 gdy przeciwnik istnieje. dlatego pierwszy warunek IF będzie spełniony, gdy przeciwnik istnieje, a jednocześnie sprawdzona zostanie pierwsza część kolizji. To sporo przyspiesza sprawdzanie kolizji Wer. 3,1: - w pliku: CWICZ9D.ACT - zrobiliśmy mocną optymalizację kolizji, ale bez rysowania obiektów na ekranie - kolizje z dużymi przeciwnikami udało się przyspieszyć 5 krotnie!;) - potem włączałem różne elementy aby się rysowały i się mieściło w ramce;) - tworzę CWICZ9E.ACT (z CWICZ9C.ACT) czyli robię szaloną wersję algorytmu kolizji;) - test dla CWICZ9E.ACT - wyrabia się w ramce dla: - 41 przeciwników (32 duże i 9 małych) - 5 pocisków gracza Czyli: zamiast 19, zamieniamy na 4 PG1==+1 IF PG1> 4 THEN PG1=0 FI i w pętli rysującej pociski gracza: zamiast 19, wpisujemy 4: FOR Q=0 TO 4 DO i w kolizjach zamiast 19, wpisujemy 4: FOR Q=0 TO 4 DO IF PGX(Q)>0 THEN Wer. 3,2: - sprawdzaliśmy grę The Jet Action (z Avalonu), bo Tatqoo ostatanio pytał się czy ta gra miała więcej wystrzeliwanych pocisków, niż przeciętne na Atari;) okazało się że 4 pociski są w tej grze;) - dość szczegółowo testowaliśmy opcje Overscan Mode: Full (With Blanking) emulatora Altirra w wer. 3,20 - testowaliśmy na przykładzie kodu z pliku CWICZ9D.ACT - wyszło na to że obecna wersja ma jeszcze nieco zapasu czasu, więc można dodać np. rysowanie pojazdu gracza itp.;) - okazało się że jest spory rozmiar niewidocznej części "czasu rastra" którego nie widać nawet w opcji "full (With Blanking)" - podobnie jest z wyświetlaniem duszków - wychwalałem tę opcję w Altirze;) - odkryliśmy, że po zakończeniu kompilacji - Action! zmienia (zeruje) zawartość rej. 712 (??) ;))) - dla zabawy zrobiliśmy plik CWICZ9K.ACT w którym zmieniane są wartości rej. koloru 712 podczas kompilacji;) - okazało się, że dyrektywa SET działa wyłącznie ze stałymi wykorzystanie zmiennej znajdujacej się pod adresem, jest weryfikowane przez kompilator, ale nie ma potem efektów takich jak podstawienie w samym Action! - też ciekawa wiedza praktyczna;) - w pliku CWICZ9E.ACT - poprawiłem dwa bugi w pociskach - gdy dochodzi do trafienia (wklejałem kod z innego programu i tu pisał za obszarem tablicy (adresy pocisków na ekranie)) - wprowadzam zmiany w kolizjach, tworzę plik: CWICZ9F.ACT - teraz kolizje całkiem ładnie tną, mimo że kolizja jest sprawdzana jedynie dla jednego pocisku (wystrzeliwuje 20 sztuk) - zwiększyłem zakresy kolizji po współrzędnej x dla przeciwników dużych i małych - nie niszczę pocisku, gdy ten trafi w przeciwnika to najmocniej zm - zwiększyłem też częstotliwość pojawiania się przeciwników, bo gdy zaczął je zestrzeliwać, to można ich teraz pokazywać więcej (i szybciej) Wer. 3,3: - brak ATRów - nie zapisałem tego co zakodowaliśmy bo to nie było nic istotnego;) - podsumowanie różnych tematów warsztatu elegancję programowania na Atari porównałem do elegancji króla czy księcia;) - "Atari Fan" - prezentował odrobiną pracę domową;) Jako jedny - fantazyjnie zrobił odtwarzanie muzyki podczas kompilacji kodu ;)) - chyba jest w tym pierwszy na świecie;) - test wydajności POKE w ATARI BASIC oraz TURBO BASIC XL TURBO BASIC XL okazał się dla tego samego kodu szybszy prawie 3 razy!;) - wróciliśmy do kwesti trybu Overscan w emulatorze Altirra w wer. 3,20 - okazało się że włączając jeszcze dodatkowo opcję "Extended PAL Height" udało się w końcu wyświetlić całość czasu CPU jaki upływa w czasie blanking. - potem Mono przeprowadził test dla Altirry w wer. 3,9x - i inne tematy i prezentacje kodu i jego omówienia itp. Wer. 3,4: - polecenie CPU NOP [234] - Atari_Virus_Invaders_Warsztat_wer34.atr w pliku: CWICZ8.ACT - Testy i ćwiczenia warsztatowe z optymalizacji kodu na przykładzie procedury TX() która modyfikuje znaki za pomocą OR $20 lub XOR $20. - przykład substytucji wyrażenia (Michał Kołodziejski), która mocno przyspieszyła działanie pętli: PROC M_TX(BYTE X,Y BYTE ARRAY T) BYTE LICZ;,DANA ;CARD ADR FOR LICZ=1 TO T(0) DO P(EKR+X+FY(Y)+LICZ)=T(LICZ) XOR $20 OD [96] na: ADR=EKR+X+FY(Y) FOR LICZ=1 TO T(0) DO P(ADR)=T(LICZ) XOR $20 ADR==+1 OD - po optymalizacji kod wykonuje się 50% szybciej;) PROC M_TX_S(BYTE X,Y BYTE ARRAY T) BYTE LICZ=84;,IL=80 CARD ADR=85 ADR=EKR+X+FY(Y) FOR LICZ=1 TO T(0) DO P(ADR)=T(LICZ) XOR $20 ADR==+1 OD [96] Wer. 3,5: - ------------ Zmienne: BYTE A,B, BYTE X,Y - współrzędne pojazdu gracza BYTE GOVER - tryb końca gry =0 trwa rozgrywka =1 lub większe od 0 koniec rozgrywki BYTE ZYC - ilość ŻYĆ BYTE LEV - numer aktualnego LEVelu BYTE UFO - sterowanie ufem =0 ufo nie istnieje =1 ufo leci BYTE SX - współrzędna X pocisku gracza BYTE SY - współrzędna Y pocisku gracza BYTE Q,Q1,Q2,Q3,Q4,Q5 - zmienne pomocnicze (lokalne w pętlach głównego programu - reusing) BYTE Q9,QA,QB - zmienne pomocnicze (lokalne w procedurach - reusing) Rejestry - cienie: BYTE K=764 - obsługa klawiatury BYTE JO=$278 - obsługa joysticka BYTE FIRE=$284 - przycisk fire CARD DL=560 - adres Display Listy CARD QQ - zmienna pomocnicza - do przechowywania adresów (lokalnie - reusing) CARD Z - adres duszków sprzętowych CARD TI - licznik ramek w trakcie rozgrywki (na razie nieużywane) CARD EKR=[$9B50] - adres pamięci obrazu rozgrywki Rejestry sprzętowe: D4B=$D40B - numer bieżącej linii rastra ANTIC D4A=$D40A - synchronizacja rastra R=$D20A - sprzętowy generator liczb losowych G10=53272;$D018 - rej. koloru (710) ,GG=53274 - rej. kolory tła lub ramki obrazu ;DUSZKI: ,D1=53248;$D000 - współrzędna duszka 1 ,D2=53249 ,D3=53250 ,D4=53251 ,S1=53252 - współrzędną pocisku 1 ,S2=53253 ,S3=53254 ,S4=53255 ,C1=53266 - color duszka 1 ,C2=53267 ,C3=53268 ,C4=53269 ------------ Tablice: BYTE ARRAY P=0 - tablica szybkich operacji typu POKE() i PEEK() np. POKE(710,10) w Action! lub P(710)=10 BYTE ARRAY DIS - Display Lista - pole gry w trybie 2 BYTE ARRAY DIS4 - Display Lista - pole gry w trybie 4 BYTE ARRAY DIST - Display Lista - Title Screen CARD ARRAY FY(36) - FastY - szybkie operacje na numerach linii CARD ARRAY DD(7) - adresy pamięci kolejnych duszków sprzętowych - Animowane punkty (statki kosmiczne) w czołówce gry [od wer. 1,6] BYTE ARRAY - PS(12) - współrzedna x 1 obiektu (statek kosmiczny) [od wer. 1,6] to jest współrzędna sprzętowego pocisku S1 w pierwszej połowie obrazu (przed logotypem) - PS(13) - współrzędna x 2 obiektu (po grafice księżyca i przed logotypem) - PS(14) - prędkość poruszania się 1 ob. - PS(15) - prędkość poruszania się 2 ob. - PS(16) - kierunek poruszania 1 ob. =0 - nie istnieje =1 w prawo =2 w lewo - PS(17) - kierunek poruszania 2 ob. =0 - nie istnieje =1 w prawo =2 w lewo - PS(18) - współrzędna y 1 obiektu (statek koszmiczny) - PS(19) - współrzędna y 2 obiektu (-"-) - Duży obiekt 3D (statek kosmiczny): - PS(20) - status obiektu 3D (statek kosmiczny) =0 - nie istnieje =1 - istnieje - PS(21) - licznik - PS(22) - zapamiętujemy wartość max (modyfikowaną) dla PS(21) - czyli licznik [od wer. 1,8] dzięki temu licznik odlicza za każdym razem różne ilości ramek: PS(21)==-1 IF PS(21)=0 THEN PS(26)==+2 PS(22)=PS(22) RSH 1 PS(21)=PS(22) FI - PS(23) - rysowanie kolejnych wielkości obiektu 3D [od wer. 1,8] w drugim trybie - tym największym i najszybszym (dla PS(20)=2) - PS(24) - współrzędne x obiektu 3D - PS(25) - współrzędne y obiektu 3D - PS(26) - kolor PS(26)=(R&15)LSH 4 Losowany kolor jest przesuwany (*16) - PS(27) - prędkość [od wer. 1,6] - animowanie 3 duszka - jako drugi wirus [od wer. 1,8] - dane wirusa są kopiowane z pierwszego. PS(30) - stan wirusa 2. na duszku 3 =0 - nie istnieje =1 - istnieje - porusza się w lewo =2 - istnieje - porusza sie w prawo PS(31) - wsp. X duszka PS(32) - wsp. Y duszka PS(33) - predkosc poruszania sie ----------- Procedury: PROC WG(CHAR ARRAY TX CARD G,I BYTE A) - procedura wczytująca lub zapisująca plik pod/z adresu TX - urządzenie + nazwa pliku G - adres I - rozmiar A - typ operacji =4 wczytanie, =8 zapis PROC DU() - Inicjowanie sprzętowych duszków (adres $8800) RSYNC(BYTE L) - RasterSYNC. Synchronizowanie się z konkretną linią rastra (l - numer linii obrazu) PROC START() - startowe operacje przed uruchomieniem gry PROC WIRUS() - rozgrywka (główna pętla gry) PROC INI() - wszelkie operacje inicjujące program, wczytywanie danych, zerowanie tablic itp. ----------------- Pamięć: $8000 - Title screen - znaki (długość 1000, do $83E8) D:TITLE.SCR $83E9 - wolne miejsce $83F0 - dane tła grafiki w rozgrywce. plik VIRUS.SCR - rozgrywka $8851 wolne miejsce... do $897F (dł. $12E=302) $8800 - sprzętowe duszki $8C00 - wolne miejsce... (dł. $400) $9000 - 2 zestawy znaków (długość $800) D:TITLE.FNT D:VIRUS.FNT",$9000,$400 $9800 - $9AFF - wolna pamięć $9B00 - kopia display listy - to jest ta kopia DL, która jest obecnie używana w rozgrywce $9B50 - adres pamięci obrazu rozgrywki (długość 1120 bajtów = $460) FY(26) to ostatnia linia pola rozgrywki FY(27) to linia score = 40840=$9F88 Tu wczytywany jest plik D:VIRUS.SCR (dokładnie $9B50+80) $9FB0 - $9FFF - wolne miejsce -------------- Znaki: $9000 - pierwszy zestaw znaków - VIRUS.FNT 005 114 znaków grafiki zanki 114-123 - cyfry 0-9 124 - pojazd gracza - w 0 trybie graficznym 125 - pojazd gracza - w 12 trybie graficznym