SciNEStist
Well-known member
If you want your player character to cast a shadow on the ground, this is how I was able to do it. It's a great way to add some polish to your game, but it also has the functionality of helping players in platform games calculate their jumps easier. It was written to be compatible with the sloped tiles tutorial found HERE. If anyone has suggestions on making it more efficient, I would love to hear it.
STEP 1: in your gameobjects tiles, draw a small shadow and a large shadow. like so:
Remember where you put them, cause you will need to edit some code later to point to the right tile.
step 2: in Nesmaker. navigate to Scripts > defined Scripts, then go Game >post sprite draw. it should open up DoPostSpriteDraw.asm. Paste the following code:
STEP 3: edit the 3rd arguments on the DrawSprite lines near the end of the previous code so they are pointing to your big and small shadow sprites that you drew in the gameobject spritesheet.
now whenever you play, the shadow will be drawn large when the ground is close to the player, small when they are farther, and not at all when they are too far.
STEP 1: in your gameobjects tiles, draw a small shadow and a large shadow. like so:
Remember where you put them, cause you will need to edit some code later to point to the right tile.
step 2: in Nesmaker. navigate to Scripts > defined Scripts, then go Game >post sprite draw. it should open up DoPostSpriteDraw.asm. Paste the following code:
Code:
;THIS PART CHECKS IF YOU ARE IN THE RIGHT GAME STATE
LDA gameState
CMP #$00
BEQ +
JMP +nohit
+
THIS PART GETS THE X AND Y POSITIONS OF THE PLAYER
LDX player1_object
LDA Object_x_hi,x ; get player x coord
ADC #$08
STA tempx
LDA Object_y_hi,x; get player y coord
ADC #$04
STA tempy
; THIS PART FIGURES OUT WHAT SCREEN YOU ARE ON AND GETS THE COLLISION TABLE FOR THE ONE YOU ARE ON
LDA Object_screen, x
AND #%00000001
BNE +othertable
LDA #$00
JMP +
+othertable
LDA #$01
+
STA tempA ;;this saves the collision table for later use
;THIS SECTION STARTS AT THE THE PLAYER POSITION AND MOVES DOWNWARD 8 PIXELS AT A TIME IN A LOOP UNTIL IT FINDS A SOLID TILE
LDX #$00 ;; x will be our counter for how many checks we have done.
floorcheckloop: ; this loop checks under the player for tiles we want to cast a shod on, if it doesnt see it, it check lower and tries again
CPX #$0F ;;this is the check counter, to keep track of how many times we went through this loop
BNE +
JMP +nohit ;; if the check counter gets too high, we give up and theres no shadow.
+
LDA tempy
ADC #$08 ;; go down 8 more pixels
STA tempy
CheckCollisionPoint tempx, tempy, #$01, tempA ; check for a solid tile
BNE +
LDA #$01
STA tempB
JMP +hitsolid
+
CheckCollisionPoint tempx, tempy, #$07, tempA ; check for a jumpthrough tile
BNE +
LDA #$07
STA tempB
JMP +hitsolid
+
CheckCollisionPoint tempx, tempy, #$0B, tempA ; check for left slope
BNE +
LDA #$0B
STA tempB
JMP +hitsolid
+
CheckCollisionPoint tempx, tempy, #$0C, tempA ;; check for right slope
BNE +
LDA #$0C
STA tempB
JMP +hitsolid
+
;nothing got hit, so we move down more and try again
INX ; increase out check count, which will come in handy later to tell us how far down the tile is
JMP floorcheckloop ;;no hit yet, go back and try again
;THIS PART IS TRIGGERED WHEN A SOLID TILE IS DETECTED
+hitsolid
floorcheckloop2: ;;in this loop, we go back up 1 pixel at a time until we are no longer hitting the tile. this will give us the very top of the tile.
LDA tempy
SBC #$01
STA tempy
CheckCollisionPoint tempx, tempy, tempB, tempA
BNE +
JMP floorcheckloop2
+
LDA tempB
CMP #$0B
BEQ IsSlope_L
CMP #$0C
BEQ IsSlope_R
JMP +solidblockhit
SlopeTileTable_L: ;;left slope table that lists our offsets, taken from Knietfeld's MUST HAVE script!
.db #$0f, #$0e, #$0d, #$0c, #$0b, #$0a, #$09, #$08, #$07, #$06, #$05, #$04, #$03, #$02, #$01, #$00
SlopeTileTable_R: ;;right slope table that lists our offsets, taken from Knietfeld's MUST HAVE script!
.db #$00, #$01, #$02, #$03, #$04, #$05, #$06, #$07, #$08, #$09, #$0a, #$0b, #$0c, #$0d, #$0e, #$0f
IsSlope_L: ;;pulls the offset from the left slope table
lda tempx
and #%00001111
tay
lda SlopeTileTable_L,y
jmp SlopeshadopwOffsetFound
IsSlope_R: ;;pulls the offset from the right slope table
lda tempx
and #%00001111
tay
lda SlopeTileTable_R,y
SlopeshadopwOffsetFound: ; this section combines the top of the tile and the offset from the table, creating the slope
sta temp
LDA tempy
AND #%11110000
clc
adc temp
SEC
ADC #$10
sta tempy
+solidblockhit ; now that we have the x and y coord along with how many blocks down it is, we can draw the shadow
LDA tempx
SBC camX ;;adjust for camera offset (important if scrolling)
SBC #$04 ;; center it a bit by moving right 4 pixels
STA tempx
CPX #$04 ;x is our counter for how manyu times we went through the loop
BCS +drawsmall ;; is the height more or less than 4 checks
DrawSprite tempx, tempy, #$08, #%00000010, #$00 ;;draws a big shadow
JMP +nohit
+drawsmall
DrawSprite tempx, tempy, #$28, #%00000010, #$00 ;; draws a small shadow
+nohit
STEP 3: edit the 3rd arguments on the DrawSprite lines near the end of the previous code so they are pointing to your big and small shadow sprites that you drew in the gameobject spritesheet.
now whenever you play, the shadow will be drawn large when the ground is close to the player, small when they are farther, and not at all when they are too far.