Tajemnice ATARI

PISZEMY GRĘ


    W dzisiejszym odcinku przedstawię jeden ze sposobów animacji obiektów na ekranie.

    Niektórych Czytelników napewno nie raz zadziwiła duża ilość ruchomych obiektów na ekranie gry. Wbrew pozorom wcale nie jest to trudne do uzyskania, a dzięki specjalnym technikom program animacyjny nie jest skomplikowany, nie potrzebuje dużej ilości pamięci, a mimo to jest skuteczny i bardzo uniwersalny. Technikę, którą opiszę, nazwałem "animacją znakową przez przeszukiwanie ekranu". Może komuś nazwa już zasugerowała, na czym to polega, lecz mimo, iż wierzę w domyślność i inteligencję Czytelników, to jednak postaram się dokładnie wyjaśnić, na czym rzecz polega.

    Jak nazwa wskazuje, program animacyjny przeszukuje ekran (który wyświetlany jest w trybie tekstowym) od lewego, górnego do prawego, dolnego rogu ekranu i w wypadku odnalezienia obiektu do animacji wywołuje procedurę obsługi tegoż obiektu. Program korzysta z dwóch tablic. W pierwszej wpisujemy kody znaków do animacji, natomiast w drugiej, w takiej samej kolejności, adresy procedur obsługi. Proszę zauważyć w naszym przykładzie, że procedury ANI_NEXT i ANI_SPD1 powtarzają się wielokrotnie. Dlaczego? Po prostu do animacji helikopterów i eksplozji użyłem kilku faz animacji (obracające się śmigła i efekt wybuchu), a po co do każdej fazy pisać oddzielną procedurę? Wystarczy, że będzie jedna ,która nie zrobi nic poza wyświetleniem następnej fazy animacji (ANI_NEXT w każdym, ANI_SPD1 w co drugim cyklu animacji). Animacja helikoptera wykonana jest na sześciu fazach, więc po sześciu cyklach animacji powinna być wyświetlona pierwsza faza. Dlatego po ciągu pięciu ANI_NEXT w tablicy skoków wpisany jest adres procedury, która wyświetla pierwszą fazę helikoptera. Procedura ANI_EXPL działa podobnie, lecz wyświetla ona spację, w celu skasowania ostatniej fazy wybuchu. Najbardziej skomplikowana jest procedura obsługi pocisków, gdyż musi ona poza przesuwaniem pocisku w prawo sprawdzać zderzenia z innymi obiektami. Obsługą pocisków zajmuje się procedura ANI_MISS i proszę się przyjrzeć, w jaki sposób sprawdzam, czy pocisk osiągnął prawą krawędź ekranu. Po prostu stworzyłem tablicę MAXY, która zawiera krańcowe pozycje. Wystarczy teraz porównać pozycję pocisku, która jest umieszczona w rejestrze Y i w wypadku, gdy będzie ona równa którejś z określonych pozycji, należy pocisk skasować, a właściwie nie wyświetlać na nowej pozycji, gdyż kasowany jest zaraz na początku procedury.

    Taki rodzaj animacji, który dziś opisałem, zastosowałem też w grze "The Jet Action", lecz podprogram animacyjny jest tam troszeczkę rozbudowany ze względu na to, że obiekty poruszają się praktycznie we wszystkich kierunkach. W takim przypadku występują pewne problemy przy ruchu w prawo lub w dół (a zwłaszcza w dół). Wyjaśnieniem tego zajmę się w bliższej lub dalszej przyszłości, a na razie może Czytelnicy zastanowią się, co się stanie, gdy animowany obiekt przesunie się zgodnie z kierunkiem przeszukiwania ekranu i jak poradziłem z tym sobie w naszym przykładzie, przy animacji pocisku. Czekam na listy!

    P.S. Piszcie, czego chcielibyście się dowiedzieć na temat pisania gier, na czym Was "przystawia". Postaram się pomóc.

    Łączę pozdrowienia dla wszystkich piszących i grających.
scwidth  equ 36

bonus    equ $04
ammo     equ $06
heli     equ $08
explo    equ $14
missile  equ $20

rej_y    equ $b7

* obsluga strzalu

fire     equ *

* sprawdzenie, czy
* mozna strzelac

 lda strig0
 bne no_fire
 lda lstr
 beq no_fire
 lda ammo_cou
 beq no_fire

* obliczenie pozycji
* startowej pocisku

 lda screen+3
 sta adr1+1
 lda y_plr
 clc
 adc #6
 lsr @
 lsr @
 lsr @
 lsr @
 tax

fire_1   equ *

 dex
 bmi fire_2
 ldy #adr1
 lda #scwidth
 jsr inad 
 jmp fire_1

fire_2   equ *

* sprawdzenie, czy
* na pozycji startowej
* znajduje się spacja...

 ldy #0
 lda (adr1),y
 iny
 ora (adrl),y
 and #254
 cmp #space
 bne no_fire

* ...jezeli tak, to
* wyswietlenie pocisku

 ldy #0
 lda #missile
 jsr shw_adr
 sed
 lda ammo_cou
 sec
 sbc #$01
 sta ammo_cou
 cld
 lda #5
 sta sound2

no_fire  equ *

 lda strig0
 sta lstr
 rts

* procedura animacji
* znakowej (przez
* przeszukiwanie ekranu)

animator equ *

 ldy #0

anim_1  equ *

 sty rej_y
 lda screen,y

* sprawdzenie, czy
* nalezy dany znak
* animować...

 cmp #heli 
 bcc no_anim
 cmp #explo+14 
 bcs no_anim

* ...jezeli tak, to
* szukamy go w tablicy
* animacji

 ldx #0

anim_2   equ *

 cmp ani_tab,x
 beq fou_ani
 inx
 cpx <ani_len
 bcc anim_2
 bcs no_anim

fou_ani  equ *

* obliczenie pozycji
* w tablicy skokow

 txa 
 asl @
 tax
 lda anim_jmp,x
 sta jump_ani
 lda anim_jmp+l,x
 sta jump_ani+1

jump_ani equ *+1

 jsr ani_next

no_anim  equ *

 ldy rej_y
 iny
 cpy #$fc
 bcc anim_1
 rts

* podprogramy animacji
* poszczegolnych obiektow

* zwolniona predkosc (wybuch)

ani_spd1 equ *

 lda count 
 and #1
 beq *+3
 rts

* wyswietlenie nastepnej
* fazy animacji

ani_next equ *

 lda screen,y
 clc
 adc #2
 jmp shw_blck

* wyswietlenie pierwszej
* fazy helikoptera

ani_heli equ *

 lda #heli 
 jmp shw_blck

* animacja pocisku 

ani_miss equ *

* skasowanie na
* biezacej pozycji

 lda #space
 jsr shw_blck

* przesuniecie w prawo
* i sprawdzenie, czy
* osiagnal prawy brzeg
* ekranu...

 iny 
 iny 
 tya
 ldx #6

anmi_1   equ *

 cmp maxy,x
 beq end_ miss
 dex
 bpl anmi_1

* ...jezeli nie, to
* sprawdzenie, czy
* cos zestrzelono

 lda screen,y
 cmp #fuel
 beq clr_miss 
 cmp #bonus
 beq clr_miss
 cmp #ammo
 beq clr_miss
 cmp #explo
 beq clr_miss
 sec
 sbc #heli
 cmp #12
 bcc hit_heli
 dey
 lda #missile
 jsr shw_blck
 iny
 sty rej_y

end_miss equ *

 rts

hit_heli equ *

 lda #$01
 jsr inc_scor

* wyswietlenie
* pierwszej fazy
* wybuchu na pozycji
* zderzenia

clr_miss equ *
 
 lda #l5
 sta sound1
 lda #explo
 jmp shw_blck

* skasowanie ostatniej
* fazy wybuchu

ani_expl equ *

 lda count
 and #1
 beq *+3
 rts
 lda #space
 jmp shw_blck

* dodanie punktow

inc_scor equ *

 sed 
 clc
 adc score
 sta score
 lda #$00
 adc score+1 
 sta score+1
 cld 
 rts

* tablica krancowych pozycji ekranu

maxy     equ *

 dta b(34) 
 dta b(70)
 dta b(106)
 dta b(142)
 dta b(178)
 dta b(214)
 dta b(250)

* tablica animacji

ani_tab  equ *

 dta b(heli+00)
 dta b(heli+02)
 dta b(heli+04)
 dta b(heli+06)
 dta b(heli+08)
 dta b(heli+10)

 dta b(explo+00)
 dta b(explo+02)
 dta b(explo+04)
 dta b(explo+06)
 dta b(explo+08)
 dta b(explo+10)

 dta b(missile)

ani_len  equ *-ani_tab

* tablica skokow

anim_jmp equ *

 dta a(ani_next)
 dta a(ani_next)
 dta a(ani_next)
 dta a(ani_next)
 dta a(ani_next)
 dta a(ani_heli)

 dta a(ani_spd1)
 dta a(ani_spd1)
 dta a(ani_spd1)
 dta a(ani_spd1)
 dta a(ani_spd1)
 dta a(ani_expl)

 dta a(ani_miss)


Dariusz Żołna



Powrót na start | Powrót do spisu treści | Powrót na stronę główną

Pixel 2002