Fix collision with spike tiles

Dirk

Member
Hi!

My debug player has a size of 16x16 and a bounding box of 14x14.
When I approach a spike tile from left I can walk until the left bound overlaps the bounding box of the spikes, but if I approach it from the right the player gets immediately killed.
I had a look at CheckUnderObject.asm, because I believe the check for the spikes underneath the player happens there. I played around and added code to offset the left bound by half the player's width.

Code:
	LDA Object_right,x
	SEC
	SBC Object_left,x
	LSR
	STA temp2 ;; temp 2 now equals half the width of the object, so left+temp2 = mid point horizontally.


I added this to the left bound and it works. As you can see in the GIF the player can walk over spikes about a half of his width before he dies. I tried the same with the other side and it never worked.


NESmaker_SpikeCollisionPre.gif


I then simply deleted the check for right side and it still works like it did previously.
I would like the behavior to be the same though: walk half the player's width over spikes and then die.

This is the my current code:

Code:
MACRO CheckUnderObject arg0
	;; arg0: how far below feet to check

	LDA Object_right,x
	SEC
	SBC Object_left,x
	LSR
	STA temp2 ;; temp 2 now equals half the width of the object, so left+temp2 = mid point horizontally.
	
	LDA #$00
    STA tile_solidity
	LDA Object_physics_byte,x
	AND #%11111011
	STA Object_physics_byte,x
    LDA Object_x_hi,x
    CLC
    ADC Object_left,x
	CLC
	ADC temp2
    STA tileX
    LDA #$00
    BCC +
    LDA #$01
+
    STA tempCol
    LDA yHold_hi
    CLC
    ADC Object_bottom,x
    CLC
    ADC arg0
    STA tileY
    JSR GetTileAtPosition
    JSR DetermineCollisionTable
    ;STA collisionPoint0
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000111
    BEQ +
    LDA Object_physics_byte,x
    ORA #%00000001
    STA Object_physics_byte,x
	LDA tile_solidity
	AND #%00000001
	BEQ ++
	LDA Object_physics_byte,x
    ORA #%00000100
    STA Object_physics_byte,x
    JMP ++  
+   
	LDA Object_physics_byte,x
	AND #%11111110
	STA Object_physics_byte,x
++
;;;;;;;;;;;;;;;;;;;;; ABOVE CHECKS BOTTOM OF PLAYER
;;;;;;;;;;;;;;;;;;;;; IF bit 0 of object physics bite is 1
;;;;;;;;;;;;;;;;;;;;; that means the object saw a solid collision
;;;;;;;;;;;;;;;;;;;;; and is 'on ground'.
	ENDM


The problem seems similar/the same I had with ladders. Dale Coop solved this problem. I tried to implement his changes into this code, but couldn't really figure it out.


EDIT:

I've just noticed that my approach introduces an error. If the tile to the right is air the player can't jump anymore.



NESmaker_JumpNotWorking.gif
 

dale_coop

Moderator
Staff member
Yeah, modifying the base engine is kinda dangerous (for other tile type collisions)
A (better?) approach is to modify the way the DEATH tile would react, depending of where the player touches it... like adding a safe zone, inside the tile, before it executes the death code, something like

2020-03-30-11-43-39-NES-MAKER-4-1-5-Version-0x159-Plat-MST.png


Here is the code I use... in the HandlePlayerDeath.asm tile script, adding a check of 4 pixels safe-zone around the edges... if the player is in the safe zone, we skip the death code:
Code:
	CPX player1_object
	BNE +
	
	;; horizontally:
	LDA tileX
	AND #%11110000
	CLC
	ADC #$04
	CMP tileX
	BCS +
	
	LDA tileX
	AND #%11110000
	CLC
	ADC #$0C
	CMP tileX
	BCC +
	
++
	
	;; vertically:
	LDA tileY
	AND #%11110000
	CLC
	ADC #$04
	CMP tileY
	BCS +
	
	LDA tileY
	AND #%11110000
	CLC
	ADC #$0C
	CMP tileY
	BCC +

	PlaySound #SND_HURT_PLAYER
	JSR HandlePlayerDeath
+

You can change the values for your needs.
 

Dirk

Member
Thank you Dale!

Collisions are so finicky -.-"


NESMaker_SpikeCollision2.gif


Buf after this I changed the tile bounding box and now I think the tile behaves satisfying :)

Thank you again Dale :)
 
Does this work in 4.5.9? I want to do something similar, but I couldn't find the HandlePlayerDeath.asm tile script, and I've haven't come across the variables tileX and tileY.
 

dale_coop

Moderator
Staff member
In any tile script (even in the 4.5.9) you can use the tileX and tileY variable, yes.
(it's in the hurt payer tile script... the script assigned to your "hurt" tile).
 
Top Bottom