User Tools

Site Tools


base:sprite_projectiles

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:sprite_projectiles [2016-06-26 17:47] (current)
achim created
Line 1: Line 1:
 +====== Sprite projectiles ======
 +by Achim
  
 +Here's a small piece of code to make one sprite fly directly to another one.
 +If the player is aiming at an enemy (or vice versa), this routine will make
 +sure the projectile hits the target.
 +
 +It's using the bresenham line algorithm for all four quadrants. ​
 +It only works with deltaX < $ff. 
 +
 +  * Call "​projecileslope"​ to prepare the line algorithm.
 +  * Call "​projectileflying"​ to move the projectile.
 +
 +
 +
 +  ; calculate slope
 +  ; projectileY,​ -X and -MSB = sprite coordinates
 +  ; targetY, -X  and -MSB = sprite coordinates
 +  ; error, deltay, deltax, deltaxhi, tmp0, tmp1 =  variables, locate them wherever you want
 +  :
 +  projectileslope lda projectileY
 + sec
 + sbc targetY
 + sta deltay
 + lda projectileX ;​ figure out x-position
 + sec
 + sbc targetX
 + sta deltax
 + lda projectileMSB
 + sbc targetMSB
 + bcc skip3
 + sta deltaxhi
 + lda #0
 + sta xdirectionflag+1
 + jmp setupslope
 +  skip3  ​       lda targetX
 + sec
 + sbc projectileX
 + sta deltax
 + lda targetMSB
 + sbc projectileMSB
 + sta deltaxhi
 + lda #1
 + sta xdirectionflag+1
 +  setupslope ​     lda deltaxhi ; quit if deltaX>​$ff
 + beq skip4
 + rts
 +  skip4           ldx #$fc ; y=y-4
 + lda projectileY ;​ figure out y-position
 + cmp targetY
 + bcc skip5
 + ldx #$04 ; y=y+4
 +  skip5           stx mirrory1+1 ;​ set y direction (up or down)
 + stx mirrory2+1
 + bpl skip6
 + lda deltay ; invert deltaY if moving up
 + eor #$ff
 + clc
 + adc #1
 + sta deltay
 +  skip6           lda deltay
 + cmp deltax
 +         bcs setyfast ; prepare y as fast direction if deltaY>​deltaX
 + lda #1 ; set flag for x=fast
 + sta fastxoryflag+1
 + lda deltax ; x=fast -> error=deltaX/​2
 + lsr
 + sta error
 + lda projectileMSB ;​ fly the the left or to the right?
 + lsr ; projectile(x+msb)/​2 = tmp0
 + lda projectileX
 + ror
 + sta tmp0
 + lda targetMSB ;​ target(x+msb)/​2 =  tmp1
 + lsr
 + lda targetX
 + ror
 + sta tmp1
 + lda tmp0 ; tmp0<​tmp1 -> projectile on the left -> fly to the right
 + cmp tmp1
 + bcc fastx2right1
 + lda #$fc ; -> x=x-4
 + sta xsteps2+1
 + lda #$e9 ; '​sbc'​ msb value
 + sta msbcorr2
 + rts
 +  fastx2right1 ​   lda #$04 ; -> x=x+4
 + sta xsteps2+1
 + lda #$69 ; '​adc'​ msb value
 + sta msbcorr2
 + rts
 +  setyfast ​       lda #0 ; set flag for y=fast
 + sta fastxoryflag+1
 + lda deltay ; y=fast -> error=deltaY/​2
 + lsr
 + sta error
 +  xdirectionflag ​ lda #0 ; 0=fly to the left, 1=fly to the right
 + bne fastx2right2
 + lda #$fc ; -> x=x-4
 + sta xsteps1+1
 + lda #$e9 ; '​sbc'​ msb value
 + sta msbcorr1
 + rts
 +  fastx2right2 ​   lda #$04 ; -> x=x+4
 + sta xsteps1+1
 + lda #$69 ; '​adc'​ msb value
 + sta msbcorr1
 + rts
 +  ;
 +  ; 1) move projectile
 +  ; 2) check if projectile hits or leaves the screen
 +  ;
 +  projectileflying ​ lda $d01e ; hardware hit detection
 + bne projectiledecomm ;​ target hit
 +  nocollision ​    lda projectileY
 + cmp #$32 ; if y<$32 -> decommission
 + bcc projectiledecom
 + cmp #$f8 ; if y>$f8 -> decommission
 + bcs projectiledecom
 + lda projectileMSB
 + beq skip0
 + lda projectileX
 + cmp #$60 ; if x>$0160 -> decommission
 + bcc fastxoryflag ;​ keep on moving projectile
 + bcs projectiledecom
 +  skip0  ​       lda projectileX
 + cmp #$10 ; if x<$0010 -> decommission
 + bcs fastxoryflag ;​ keep on moving sprite
 +  projectiledecom ​ lda #$00 ; x=$0000
 + sta projectileX
 + sta projectileMSB
 + lda #$ff ; y=$ff or do whatever is necessary here 
 +                  sta projectileY ​        ; to switch off sprite/​projectile for your main program
 + rts
 +  fastxoryflag ​   lda #0           ; selfmod: 0 -> y is fast, 1 -> x is fast
 + bne xfast
 + lda projectileY
 + sec
 +  mirrory1 ​       sbc #4 ; = px/frame, +$04 or +$fc (selfmodifying code)
 + sta projectileY
 + lda error
 + sec
 + sbc deltax
 + sta error
 + bcs skip1
 + lda projectileX
 + clc
 +  xsteps1 ​        adc #4 ; =px/frame, +$04 or +$fc (selfmodifying code)
 + sta projectileX
 + lda projectileMSB
 +  msbcorr1 ​       adc #0
 + sta projectileMSB
 + lda error
 + clc
 + adc deltay
 + sta error
 +  skip1           ​rts
 +  xfast           lda projectileX
 + clc
 +  xsteps2 ​        adc #4 ; =px/frame, +$04 or +$fc (selfmodifying code)
 + sta projectileX
 + lda projectileMSB
 +  msbcorr2 ​       adc #0
 + sta projectileMSB
 + lda error
 + sec
 + sbc deltay
 + sta error
 + bcs skip2
 + lda projectileY
 + sec
 +  mirrory2 ​       sbc #4 ; =px/frame, +$04 or +$fc (selfmodifying code)
 + sta projectileY
 + lda error
 + clc
 + adc deltax
 + sta error
 +  skip2           rts
base/sprite_projectiles.txt ยท Last modified: 2016-06-26 17:47 by achim