• entries
    104
  • comments
    101
  • views
    254236

A C64 Game - Step 6

Sign in to follow this  
Endurion

3811 views

And onwards we go: Obviously we don't want the player to move through walls. In this step we check the chars in the players way to see if they are blocking.

step6.png.13d9bda3ea3ec8381f113520981383dc.png


To make this easier we store the character pos and the character delta pos (0 to 7) for x and y for every sprite (SPRITE_CHAR_POS_X, SPRITE_CHAR_POS_X_DELTA). If the sprite is not at a character brink the move is allowed, if it hits the brink, check the characters at the target.

For this step any character equal or above index 128 is considered blocking, any below is free to move.

The collision code assumes that the collision box of a sprite is one char wide and two chars high.

This step shows:
-calculating character positions while moving about
-checking the position for blocking chars
-calculating the required sprite position from character pos (for starting a sprite at a specific place)

Since the code is basically the same for all four directions I'll only go into details on one of them:
 

;------------------------------------------------------------
;PlayerMoveLeft
;------------------------------------------------------------
!zone PlayerMoveLeft
PlayerMoveLeft
          ldx #0
          
          ;check if we are on the brink of a character
          lda SPRITE_CHAR_POS_X_DELTA
          beq .CheckCanMoveLeft
          
          ;no, we are not
          
.CanMoveLeft
          dec SPRITE_CHAR_POS_X_DELTA
          jsr MoveSpriteLeft
          rts
          
.CheckCanMoveLeft
          lda SPRITE_CHAR_POS_Y_DELTA
          beq .NoThirdCharCheckNeeded
          
          ;find the character in the screen buffer
          ldy SPRITE_CHAR_POS_Y
          lda SCREEN_LINE_OFFSET_TABLE_LO,y
          sta ZEROPAGE_POINTER_1
          lda SCREEN_LINE_OFFSET_TABLE_HI,y
          sta ZEROPAGE_POINTER_1 + 1
          lda SPRITE_CHAR_POS_X
          clc
          adc #39 ;39 equals one line down (40 chars) and one to the left (-1)
          tay
          lda (ZEROPAGE_POINTER_1),y
          jsr IsCharBlocking
          bne .BlockedLeft

.NoThirdCharCheckNeeded
          ldy SPRITE_CHAR_POS_Y
          dey
          lda SCREEN_LINE_OFFSET_TABLE_LO,y
          sta ZEROPAGE_POINTER_1
          lda SCREEN_LINE_OFFSET_TABLE_HI,y
          sta ZEROPAGE_POINTER_1 + 1
          ldy SPRITE_CHAR_POS_X
          dey
          lda (ZEROPAGE_POINTER_1),y
          jsr IsCharBlocking
          bne .BlockedLeft
          
          tya
          clc
          adc #40
          tay
          lda (ZEROPAGE_POINTER_1),y
          jsr IsCharBlocking
          bne .BlockedLeft
          
          lda #8
          sta SPRITE_CHAR_POS_X_DELTA
          dec SPRITE_CHAR_POS_X
          jmp .CanMoveLeft
          
.BlockedLeft
          rts

 

The subroutine IsCharBlocking is rather primitive, as described it only checks if the character is smaller than 128:
 

;------------------------------------------------------------
;IsCharBlocking
;checks if a char is blocking
;A contains the character
;returns 1 for blocking, 0 for not blocking
;------------------------------------------------------------
!zone IsCharBlocking
IsCharBlocking
          cmp #128
          bpl .Blocking
          
          lda #0
          rts
          
.Blocking
          lda #1
          rts


step6.zip

Previous Step 5 Next Step 7

Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now