Re: [stella] My best collision detection

Subject: Re: [stella] My best collision detection
From: Christopher Tumber <christophertumber@xxxxxxxxxx>
Date: Fri, 25 Oct 2002 10:24:39 -0400
>Not knowing how the collision detection works in Space 
>Instigators, 

Collision detection in Space Instigators is a little complex because it needs to determine the row/column number of what (if anything's) been hit. (This is player's shot/Instigators collision. Insitigator's shot/Player's ship collision detection is quite simple while Shot/House collision detection is a little complicated again):

To set this up. Alive/Dead data for Instigators are contained 9 bytes, the variables are named Column1, Column2, etc (Though usually reference is indexed so Column1 is generally the only one referred to in code). The lower 5 bits are bitflags indicating Alive/dead status of the corresponding Instigator. Bit0 of Column1 is the top left hand corner Instigator.

Aliens_Position is the horizontal position of the formation (value 0-9)
Aliens_Top_Row is the number of scanlines from the top of the playfield to the top of the formation
Player_Shot_Pos_Y_top is the scanline of the top of the player's shot
Player_Shot_Pos_X is horizontal position of the player's shot


      lda #1
      sta temp2
      lda Player_Shot_Pos_Y_top
      beq no_alien_hit
      sec
      sbc #10
      bmi no_alien_hit
      sec
      sbc Aliens_Top_Row
      bmi no_alien_hit
      ldy #0   ;Find row
next_find_row:
      cmp #12
      bmi found_row      
      asl temp2
      iny
      sec
      sbc #18 ;#15 ;#12 Height in scanlines of a row
      jmp next_find_row
found_row:   ;X now contains row, temp2 contains bitmask for row
      cpy #5
      bpl no_alien_hit ;Shot too low

      lda #16
      ldx Aliens_Position
      beq no_add_pos
next_add_pos:
      clc
      adc #3
      dex
      bne next_add_pos
no_add_pos:
      sta temp            ;Postion of left edge of Aliens

      lda Player_Shot_Pos_X
      sec
      sbc temp
      bmi no_alien_hit ;Shot is too far left
      ldx #0
find_next_column:
      cmp #12
      bmi found_column
      inx
      sec
      sbc #12
      jmp find_next_column
found_column:  ;Y now contains the column number
      cmp #8
      bpl no_alien_hit ;Weed out shot in column but not hiting alien
      cpx #9
      bpl no_alien_hit ;Shot is too far right
      
      lda temp2
      and Column1,x
      beq no_alien_hit

      lda temp2
      eor #255
      and Column1,x
      sta Column1,x
      ldx #0
      stx Player_Shot_Pos_Y_top
      jsr start_explosion_sound
      dec Aliens_Speed    ;Make 'em go faster!

      jsr Add_10_To_Score
      cpy #3
      bpl no_alien_hit
      jsr Add_10_To_Score
      cpy #1
      bpl no_alien_hit
      jsr Add_10_To_Score
no_alien_hit:
;      jmp done_alien_hit
done_alien_hit:




>I thought to present mine. I once spent 
>almost a whole day for finding the optimal technique to 
>determine wether a particle hit a square and I think it 
>possibly might be adopted to detect a collision with 
>variable width invaders:

It looks like a good routine, however a game like Space Instigators adds the complexity of having to do 55 collision detections (Your routine would probably need nested loops or at least a big 55 iteration loop which would add a lot of unneeded overhead...) as well as maintaining the status data - Like I use bitflags because you don't really want to use 1 byte each if you can avoid it...

Looking over my code, I could actually adapt my routine fairly easily by changing:

      jmp find_next_column
found_column:  ;Y now contains the column number
      cmp #8
      bpl no_alien_hit ;Weed out shot in column but not hiting alien
to:
      jmp find_next_column
found_column:  ;Y now contains the column number
      cmp AlienLeftEdge ;A Variable
      bmi no_alien_hit ;Weed out shot in column but not hiting alien
      cmp AlienRightEdge ;A Variable
      bpl no_alien_hit ;Weed out shot in column but not hiting alien

Uses 2 extra bytes RAM but they're really temporary values that would be setup only for that routine (probably pulled off a ROM table) but the only way around that would be more bitmasks (since it's only going to be a small value we could share a byte) or rewrite the code slightly to use a Width variable (Right now it's finding which column the shot is in based on the left edge of each Instigator and then checking that the shot isn't too far right within that column. Instead it could be finding the column based on the center of the Instigator and then it would determine if the shot is within the width of the Instigator. Yeah, that would probably be the way to go...)

No, no, no, speaking of tables it would be something like this:

      jmp find_next_column
found_column:  ;Y now contains the column number
      ldx ROW ;Because we're not able to preserve X so we'd have to save the ROW to a temp variable
      cmp AlienLeftEdge,x
      bmi no_alien_hit ;Weed out shot in column but not hiting alien
      cmp AlienRightEdge,x
      bpl no_alien_hit ;Weed out shot in column but not hiting alien

Where AlienLeftEdge and AlienRightEdge are ROM tables containing the left/right thresholds for collison...

Yeah, that'd probably work...

Chris...


----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/


Current Thread