home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti3 / lezione7w1.s < prev    next >
Text File  |  1995-09-29  |  8KB  |  269 lines

  1.  
  2. ; Lezione7w1.s    COLLISIONE TRA SPRITE
  3.  
  4.  
  5.     SECTION    CiriCop,CODE
  6.  
  7. Inizio:
  8.     move.l    4.w,a6        ; Execbase
  9.     jsr    -$78(a6)    ; Disable
  10.     lea    GfxName(PC),a1    ; Nome lib
  11.     jsr    -$198(a6)    ; OpenLibrary
  12.     move.l    d0,GfxBase
  13.     move.l    d0,a6
  14.     move.l    $26(a6),OldCop    ; salviamo la vecchia COP
  15.  
  16. ;    Puntiamo la PIC con il solito metodo
  17.  
  18.     MOVE.L    #PIC,d0
  19.     LEA    BPLPOINTERS,A1
  20.     MOVEQ    #2-1,D1
  21. POINTBP:
  22.     move.w    d0,6(a1)
  23.     swap    d0
  24.     move.w    d0,2(a1)
  25.     swap    d0
  26.     ADD.L    #40*256,d0
  27.     addq.w    #8,a1
  28.     dbra    d1,POINTBP
  29.  
  30. ;    Puntiamo lo sprite
  31.  
  32.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  33.     MOVE.L    #MIOSPRITE0,d0        ; indirizzo dello sprite in d0
  34.     move.w    d0,6(a1)
  35.     swap    d0
  36.     move.w    d0,2(a1)
  37.     add.l    #16,a1
  38.  
  39.     MOVE.L    #MIOSPRITE2,d0        ; indirizzo dello sprite in d0
  40.     move.w    d0,6(a1)
  41.     swap    d0
  42.     move.w    d0,2(a1)
  43.  
  44.     move.l    #COPPERLIST,$dff080    ; nostra COP
  45.     move.w    d0,$dff088        ; START COP
  46.     move.w    #0,$dff1fc        ; NO AGA!
  47.     move.w    #$c00,$dff106        ; NO AGA!
  48.  
  49. mouse:
  50.     cmpi.b    #$ff,$dff006    ; Linea 255?
  51.     bne.s    mouse
  52.  
  53.     bsr.s    MuoviSprite0    ; Muovi l'aereo
  54.     bsr.s    MuoviSprite1    ; Muovi il missile contro l'aereo
  55.     bsr.s    CheckColl    ; Controlla collisione e provvede
  56.  
  57. Aspetta:
  58.     cmpi.b    #$ff,$dff006    ; linea 255?
  59.     beq.s    Aspetta
  60.  
  61.     btst    #6,$bfe001    ; mouse premuto?
  62.     bne.s    mouse
  63.  
  64.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  65.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  66.  
  67.     move.l    4.w,a6
  68.     jsr    -$7e(a6)    ; Enable
  69.     move.l    gfxbase(PC),a1
  70.     jsr    -$19e(a6)    ; Closelibrary
  71.     rts
  72.  
  73. ;    Dati
  74.  
  75. GfxName:
  76.     dc.b    "graphics.library",0,0
  77.  
  78. GfxBase:
  79.     dc.l    0
  80.  
  81. OldCop:
  82.     dc.l    0
  83.  
  84. ; Questa routine muove lo sprite dell'aereo in linea retta a sinistra di
  85. ; 2 pixel per volta, agendo sul suo HSTART
  86.  
  87. MuoviSprite0:
  88.     subq.b    #1,HSTART0
  89.     rts
  90.  
  91. ;    -        -        -        -
  92.  
  93. ; Questa routine muove il missile. Lo fa solo se l'aereo e` abbastanza vicino
  94. ; da colpirlo. L'aereo e' a tiro quando il suo HSTART e' a $b0.
  95. ; Se volete salvare l'aereo provate a far partire il missile alla posizione
  96. ; $AA, cioe' troppo presto, oppure alla posizione $c1, ossia troppo tardi.
  97.  
  98. MuoviSprite1:
  99.     cmp.b    #$b0,HSTART0    ; L'aereo e' a tiro?
  100.     bhi.s    non_a_tiro    ; non partire se l'aereo e` troppo a destra
  101.     subq.b    #1,VSTART2    ; fai salire il missile agendo sia sul
  102.     subq.b    #1,VSTOP2    ; VSTART che sul VSTOP
  103. non_a_tiro:
  104.     rts
  105.  
  106. ;    -        -        -        -
  107.  
  108. ; Questa routine controlla se c'e` collisione. In caso affermativo, cancella
  109. ; i due sprites, azzerando i relativi puntatori nella copperlist
  110.  
  111. CheckColl:
  112.     move.w    $dff00e,d0    ; legge CLXDAT ($dff00e)
  113.                 ; una lettura di questo registro ne provoca
  114.                 ; anche la cancellazione, per cui conviene
  115.                 ; copiarselo in d0 e fare i test su d0
  116.     btst.l    #9,d0
  117.     beq.s    no_coll        ; se non c'e` collisione salta
  118.  
  119.     MOVEQ    #0,d0          ; altrimenti cancella gli sprites
  120.     LEA    SpritePointers,a1 ; puntatore sprite 0
  121.     move.w    d0,6(a1)      ; azzera puntatore sprite 0 in copperlist
  122.     move.w    d0,2(a1)
  123.     add.w    #16,a1        ; puntatore sprite 2
  124.     move.w    d0,6(a1)    ; azzera puntatore sprite 2 in copperlist
  125.     move.w    d0,2(a1)
  126. no_coll:
  127.     rts
  128.  
  129.  
  130.     SECTION    GRAPHIC,DATA_C
  131.  
  132. COPPERLIST:
  133. SpritePointers:
  134.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  135.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  136.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  137.     dc.w    $13e,0
  138.  
  139.     dc.w    $8E,$2c81    ; DiwStrt
  140.     dc.w    $90,$2cc1    ; DiwStop
  141.     dc.w    $92,$38        ; DdfStart
  142.     dc.w    $94,$d0        ; DdfStop
  143.     dc.w    $102,0        ; BplCon1
  144.     dc.w    $104,$0024    ; BplCon2 - Sprites davanti i bitplanes
  145.     dc.w    $108,0        ; Bpl1Mod
  146.     dc.w    $10a,0        ; Bpl2Mod
  147.  
  148.             ; 5432109876543210
  149.     dc.w    $100,%0010001000000000    ; bit 13 acceso!! 2 bitplane lowres
  150.  
  151. BPLPOINTERS:
  152.     dc.w $e0,0,$e2,0    ;primo     bitplane
  153.     dc.w $e4,0,$e6,0    ;primo     bitplane
  154.  
  155.     dc.w    $180,$000    ; color0    ; sfondo nero
  156.     dc.w    $182,$005    ; color1    ; colore 1 del bitplane
  157.     dc.w    $184,$a40    ; color1    ; colore 2 del bitplane
  158.     dc.w    $186,$f80    ; color1    ; colore 3 del bitplane
  159.  
  160.     dc.w    $1A2,$06f    ; color17, ossia COLOR1 dello sprite0
  161.     dc.w    $1A4,$0c0    ; color18, ossia COLOR2 dello sprite0
  162.     dc.w    $1A6,$0c0    ; color19, ossia COLOR3 dello sprite0
  163.  
  164.     dc.w    $1AA,$444    ; color21, ossia COLOR1 dello sprite2
  165.     dc.w    $1AC,$888    ; color22, ossia COLOR2 dello sprite2
  166.     dc.w    $1AE,$0c0    ; color23, ossia COLOR3 dello sprite2
  167.  
  168.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  169.  
  170.  
  171. ; ************ Ecco lo sprite: OVVIAMENTE deve essere in CHIP RAM! ************
  172.  
  173. MIOSPRITE0:        ; lunghezza 6 linee
  174. VSTART0:
  175.     dc.b 180    ; Posizione verticale di inizio sprite (da $2c a $f2)
  176. HSTART0:
  177.     dc.b $d8    ; Posizione orizzontale di inizio sprite (da $40 a $d8)
  178. VSTOP0:
  179.     dc.b 186    ; 180+6=186
  180. VHBITS:
  181.     dc.b $00
  182.     dc.w    $0008,$0000
  183.     dc.w    $1818,$0000
  184.     dc.w    $2C28,$1010
  185.     dc.w    $7FF8,$0000
  186.     dc.w    $3FC0,$0000
  187.     dc.w    $01F0,$0000
  188.     dc.w    $0000,$0000
  189.  
  190. MIOSPRITE2:        ; lunghezza 16 linee
  191. VSTART2:
  192.     dc.b 224    ; Posizione verticale di inizio sprite (da $2c a $f2)
  193. HSTART2:
  194.     dc.b $86    ; Posizione orizzontale di inizio sprite (da $40 a $d8)
  195. VSTOP2:
  196.     dc.b 240
  197.     dc.b 0
  198.     dc.w    $0200,$0000
  199.     dc.w    $0200,$0000
  200.     dc.w    $0200,$0000
  201.     dc.w    $0000,$0200
  202.     dc.w    $0000,$0700
  203.     dc.w    $0000,$0700
  204.     dc.w    $0500,$0200
  205.     dc.w    $0200,$0500
  206.     dc.w    $0500,$0200
  207.     dc.w    $0200,$0500
  208.     dc.w    $1540,$0200
  209.     dc.w    $0200,$1DC0
  210.     dc.w    $0000,$1FC0
  211.     dc.w    $0000,$1740
  212.     dc.w    $0500,$0200
  213.     dc.w    $0000,$0000
  214.     dc.w    $0000,$0000
  215.  
  216. ;    Figura della rampa di lancio
  217.  
  218. PIC:
  219.     incbin    "paesaggio.raw"
  220.  
  221.     end
  222.  
  223. In questo esempio vediamo come rilevare la collisione tra 2 sprite.
  224. Abbiamo 2 oggetti che si scontrano. Notate che per i 2 oggetti abbiamo usato
  225. gli sprite 0 e 2, cioe` 2 sprite che appartengono a 2 gruppi diversi.
  226. Questo fatto innanzitutto ci permette, come abbiamo gia` visto, di usare
  227. 2 palette diverse per i 2 oggetti, ma e` anche necessario per poter
  228. sfruttare la collisione tra sprite. Infatti e` possibile rilevare solo
  229. le collisioni tra sprite appartenenti a coppie diverse, e non fra sprite
  230. appartenenti alla stessa coppia. Per rilevare una collisione basta controllare
  231. lo stato di un bit nel registro CLXDAT, come abbiamo gia` visto nella lezione.
  232.  
  233. Quando il bit relativo alla collisione vale 1, allora la collisione si e` 
  234. effettivamente verificata. Il nostro esempio si limita a cancellare i 2
  235. sprite, azzerando i relativi puntatori nella copperlist. Potete migliorare
  236. l'esempio aggiungendo una bella esplosione. E` molto semplice. Innanzitutto
  237. disegnatevi uno sprite che rappresenta un'esplosione e aggiungetelo al
  238. sorgente (mi raccomando nella SECTION che va nella memoria CHIP).
  239. Poi modificate la routine ChekColl: quando viene rilevata la collisione
  240. sostituite alle istruzioni
  241.  
  242.     MOVEQ    #0,d0        ; altrimenti cancella gli sprites
  243.     LEA    SpritePointers,a1    ; puntatore sprite 0
  244.     move.w    d0,6(a1)    ; azzera puntatore sprite 0 in copperlist
  245.     move.w    d0,2(a1)
  246.  
  247. le istruzioni
  248.  
  249.     MOVE.L    #SPRITE_ESPLOSIONE,d0    ; indirizzo sprite esplosione
  250.     LEA    SpritePointers,a1    ; puntatore sprite 0
  251.     move.w    d0,6(a1)    ; modifica puntatore sprite 0 in copperlist
  252.     swap    d0
  253.     move.w    d0,2(a1)
  254.  
  255. in questo modo invece di cancellare lo sprite, sostituirete il disegno
  256. dell'aereo con quello dell'esplosione. Dovrete inoltre avere l'accortezza
  257. di copiare i byte che controllano la posizione dell'aereo (VSTART0,HSTART0)
  258. nei corrispondenti byte di controllo dello sprite dell'esplosione. Questo
  259. dovreste saperlo fare da soli, ormai. Dovete fare solo un po' di attenzione
  260. a VSTOP: se il disegno dell'esplosione ha un'altezza diversa da quello
  261. dell'aereo, non potete semplicemente copiare il VSTOP, ma dovrete aggiustarlo.
  262. Nulla di difficile, comunque.
  263.  
  264. In questo esempio abbiamo volutamente fatto percorrere delle traettorie molto
  265. semplici (delle rette) ai 2 sprite, per mostrare meglio il meccanismo della
  266. collisione. Potete provare a sostituire alle 2 routine che muovono gli sprite
  267. una delle routine che usano tabelle che abbiamo usato negli altri esempi.
  268.  
  269.