SciNEStist
Well-known member
So this has been asked a few times, so here is a simple and effective way to have grid-based walking in your adventure game. There may be extra steps you will need to do, like removing the knockback code in playerhurt, but this should get you started at least. If someone can make this more efficient, please post with your edits.
CLICK HERE FOR AN UPDATED VERSION THAT ALLOWS FOR PLAYER SPEED CONTROL
HOW TO USE:
Step 1: remove all input controls for up left down and right, including hold, press, and release
Step 2: add in a user variable in Project settings> User variable called "walkcount" with a default of 0
step 3: in around line 15 of doHandlePhysics_AdventureBase you will see
replace it with this:
EXTRAS:
change what you can walk over:
the script above is set to check if a tile is walkable before allowing you to move, so anything other than a walkable type 0 tile will block you. If you want to change this so you can walk over any tile type other than solids, change all 4 instances of theses lines:
into these:
offset player spawn:
Now, if you are one of those people who like an odd sized height on your player object (3 tiles tall for example), you will notice that you can only spawn a player on a 16X16 grid, so your feet will start half way between 2 tiles. Since we can't have that, a good option is to either
A: put an extra blank row of tiles above your players head to make it an even count. if you do this, i strongly recommend you read this thread: https://www.nesmakers.com/index.php...ng-blank-sprites-to-not-draw.5938/#post-29744
B: add a bit of code that pushes your player down a bit to get it on the tile properly
To do option B, you can add this bit to the end of your post screen load script:
that will leave the even tiled player objects alone (2, 4, 6, 8) and move the odd tiled player objects down 8 pixels to put them where they should be (1,3,5,7)
CLICK HERE FOR AN UPDATED VERSION THAT ALLOWS FOR PLAYER SPEED CONTROL
HOW TO USE:
Step 1: remove all input controls for up left down and right, including hold, press, and release
Step 2: add in a user variable in Project settings> User variable called "walkcount" with a default of 0
step 3: in around line 15 of doHandlePhysics_AdventureBase you will see
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;; FOR ADVENTURE PHYSICS
;;;;;;;;;;;;;;;;;;;;;;;;;;; DON'T UPDATE POSITIONING IF ATTACKING
CPX player1_object
BEQ +
JMP +notPlayer
+
;; it was the player.
;; if this object is in attack action, currently set to 2,
;; he should not move, and should skip physics check
TXA
STA temp
GetActionStep temp
CMP #$02
BNE +notPlayer ;; skip, because was not 2.
JMP skipPhysics
+notPlayer
replace it with this:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;; FOR ADVENTURE PHYSICS
;;;;;;;;;;;;;;;;;;;;;;;;;;; DON'T UPDATE POSITIONING IF ATTACKING
CPX player1_object
BEQ +
JMP +notPlayer
+
;START OF CUSTOM STUFF
LDY Object_type,x
LDA ObjectBboxLeft,y
STA self_left
CLC
ADC ObjectWidth,y
STA self_right
CLC
LDA ObjectBboxTop,y
STA self_top
CLC
ADC ObjectHeight,y
STA self_bottom
LDA walkcount
CMP #$00
BEQ +notwalking
DEC walkcount
LDA Object_direction,x
AND #%00000111
CMP #$02; right
BNE +
INC Object_x_hi,x
LDA Object_x_hi,x
ADC self_right
CMP #BOUNDS_RIGHT
BCC ++
LDA #$01
STA screenUpdateByte
JSR doHandleBounds
JMP skipPhysics
++
JMP +donewalk
+
CMP #$06; left
BNE +
DEC Object_x_hi,x
LDA Object_x_hi,x
CMP #BOUNDS_LEFT
BCS ++
LDA #$03
STA screenUpdateByte
JSR doHandleBounds
JMP skipPhysics
++
JMP +donewalk
+
CMP #$04; up
BNE +
DEC Object_y_hi,x
JMP +donewalk
+
CMP #$00; down
BNE +
INC Object_y_hi,x
LDA Object_y_hi,x
ADC self_bottom
CMP #BOUNDS_BOTTOM
BCC ++
LDA #$00
STA screenUpdateByte
JSR doHandleBounds
JMP skipPhysics
++
JMP +donewalk
+
JMP +donewalk
+notwalking
STX temp ;; assumes the object we want to move is in x.
LDA currentNametable ; there are 2 collision tables, one for odd screens, and one for even.
AND #%00000001 ; this gets the right one for the current screen
STA tempA ; and saves it to tempA
LDA gamepad ; read the gamepad
AND #%10000000 ; is it right?
BEQ +
ChangeFacingDirection temp, #FACE_RIGHT ; face right nop matter what
LDA Object_x_hi,x ; all this is for checking out the new coords to test
ADC ObjectWidth,y
ADC #$08
STA temp
LDA Object_y_hi,x
ADC self_top
STA temp1
;DrawSprite temp, temp1, #$0A, #%00000000, #$00
CheckCollisionPoint temp, temp1, #$00, tempA ; is the next tile walkable?
BEQ +walk
ChangeActionStep player1_object, #$00
JMP +donewalk ; if not, dont walk. we could also add a sound before this line if you want
+walk
ChangeActionStep player1_object, #$01 ; set player to walking action step
LDA #$10 ; set the countdown to 16 (#$10 is 16), change this if you want a bigger grid
STA walkcount
JMP +donewalk
+
LDA gamepad
AND #%01000000 ; left
BEQ +
ChangeFacingDirection temp, #FACE_LEFT
LDA Object_x_hi,x
ADC self_left
SBC #$08
STA temp
LDA Object_y_hi,x
ADC self_top
STA temp1
;DrawSprite temp, temp1, #$0A, #%00000000, #$00
CheckCollisionPoint temp, temp1, #$00, tempA
BEQ +walk
ChangeActionStep player1_object, #$00
JMP +donewalk
+walk
ChangeActionStep player1_object, #$01
LDA #$10
STA walkcount
JMP +donewalk
+
LDA gamepad
AND #%00010000 ; up
BEQ +
ChangeFacingDirection temp, #FACE_UP
LDA Object_x_hi,x
ADC self_left
STA temp
LDA Object_y_hi,x
ADC self_top
SBC #$08
STA temp1
;DrawSprite temp, temp1, #$0A, #%00000000, #$00
CheckCollisionPoint temp, temp1, #$00, tempA
BEQ +walk
ChangeActionStep player1_object, #$00
JMP +donewalk
+walk
ChangeActionStep player1_object, #$01
LDA #$10
STA walkcount
JMP +donewalk
+
LDA gamepad
AND #%00100000 ;down
BEQ +
ChangeFacingDirection temp, #FACE_DOWN
LDA Object_x_hi,x
ADC self_left
STA temp
LDA Object_y_hi,x
ADC self_bottom
ADC #$08
STA temp1
;DrawSprite temp, temp1, #$0A, #%00000000, #$00
CheckCollisionPoint temp, temp1, #$00, tempA
BEQ +walk
ChangeActionStep player1_object, #$00
JMP +donewalk
+walk
ChangeActionStep player1_object, #$01
LDA #$10
STA walkcount
JMP +donewalk
+
ChangeActionStep player1_object, #$00
+donewalk
;;END OF CUSTOM STUFF
;; it was the player.
;; if this object is in attack action, currently set to 2,
;; he should not move, and should skip physics check
TXA
STA temp
GetActionStep temp
CMP #$02
BNE +notPlayer ;; skip, because was not 2.
JMP skipPhysics
+notPlayer
EXTRAS:
change what you can walk over:
the script above is set to check if a tile is walkable before allowing you to move, so anything other than a walkable type 0 tile will block you. If you want to change this so you can walk over any tile type other than solids, change all 4 instances of theses lines:
Rich (BB code):
CheckCollisionPoint temp, temp1, #$00, tempA
BEQ +walk
Code:
CheckCollisionPoint temp, temp1, #$01, tempA
BNE +walk
offset player spawn:
Now, if you are one of those people who like an odd sized height on your player object (3 tiles tall for example), you will notice that you can only spawn a player on a 16X16 grid, so your feet will start half way between 2 tiles. Since we can't have that, a good option is to either
A: put an extra blank row of tiles above your players head to make it an even count. if you do this, i strongly recommend you read this thread: https://www.nesmakers.com/index.php...ng-blank-sprites-to-not-draw.5938/#post-29744
B: add a bit of code that pushes your player down a bit to get it on the tile properly
To do option B, you can add this bit to the end of your post screen load script:
Code:
SwitchBank #$1C
LDX player1_object
LDY Object_type,x
LDA ObjectSize,y
LSR
BCC +
LDA Object_y_hi,x
ADC #$07
STA Object_y_hi,x
+
ReturnBank
that will leave the even tiled player objects alone (2, 4, 6, 8) and move the odd tiled player objects down 8 pixels to put them where they should be (1,3,5,7)
Last edited: