Ladders not working?

Dirk

Member
Hi!

I tried to add ladders for the first time (at least I think) and they don't work. When I press up my character wiggles around a bit but won't climb the ladder.
I vaguely remember that ladders got removed one time, but I can add them in this version (4.1.5).
Are they broken or am I doing something wrong?
 

dale_coop

Moderator
Staff member
To use the ladder tiles, you need to set up correctly your Player's Action Step 4 (climbing state)

2020-03-17-23-53-06-Monster-Animation-Info.png
 

Dirk

Member
Thank you Dale! You are a savior! :)

I have some questions, I hope you or someone can answer them :)

  • Do you know if there is documentation somewhere which action step corresponds to which action?
  • How can I stop the player from immediately falling down, when I press left or right? Maybe have the player only leave the ladder when he jumps.
  • How can I stop the animation so the climbing animation is only playing when I press up or down?

Thank you!
 

dale_coop

Moderator
Staff member
- In fact, the action steps... depends of the module used.
But for the platformer, buy default, it's :
0: idle
1: walk
2: jump
3: shoots
4: ladder
5: ducking (?)
6: not used
7: not used


- for left / right on ladder, it's coded in the "Extra Controll Script" script (from the "project settings > script settings"). but I am not sure it would be very easy to get another behavior...
what you want would happen when the user press left or right?


- for the climbing animation stopped when your not Up or Down, modify the script assigned to the "Physics" (from your "project settings > script settings"), around line 186, you will find:

Code:
notPressingDownOnLadder:
skipLadderStuff:

Just add a "ChangeObjectState #$04, #$04" line between the two labels... like that:

Code:
notPressingDownOnLadder:
	ChangeObjectState #$04, #$04
skipLadderStuff:
 

Dirk

Member
Super, thank you! I'll adjust my code :)


dale_coop said:
what you want would happen when the user press left or right?

I'm thinking of two possible options:
  • snapping to the ladder (player in the middle of the ladder even when he wasn't at first when he started climbing) so left or right would result in player falling down
  • player walks left and right like on a solid tile and only drops down when he walks of the ladder's ledge
 

Dirk

Member
Thank you again dale_coop for your code! I have only one problem. When I walk past a ladder my player changes into his climbing animation. So when I walk past a ladder he suddenly shows his backside and then his front again.
Maybe I should add a check if he is on a solid tile and then have "ChangeObjectState #$04, #$04".
 

dale_coop

Moderator
Staff member
Snap to the ladder... left/right he falls, so it's the current behavior (sauf you need to make your player snap on the ladder, at first :p)

Walking L/R on the ladder, if your ladder is only a 1 tile large will not be very usable... because the tile collision detection engine is not very precise. As soon as your player will touch a null walkable tile (when moving to the right) he will fall (even if the majority of is body was still on the ladder)
 

Dirk

Member
With snap to ladder I mean that the player gets moved to the center of the ladder, even if he stand a bit off center when pressing up.
Okay, it's not that important ^^

Do you know how I can check if I'm standing on solid ground?
 

dale_coop

Moderator
Staff member
To check if you are on the ground:

Code:
    LDA Object_physics_byte,x
    AND #%00000001 
    BNE onTheGround
 

Dirk

Member
I didn't manage to get it to work like I wanted it to, but I'll ignore that for now.
At the moment I actually have a problem with the collision detection.
My player can climb the ladder as soon as the right bound of the bounding box collides with the ladder tile bounding box.
As soon as the right bound leaves the ladder tile again my player can't climb the ladder.

LadderBoundingBoxProblem.png

Standing on the left side of the ladder it looks like he can climb air, standing a bit off center to the right he can't although visually standing in front of a ladder.
 

dale_coop

Moderator
Staff member
The Check For Horizontal Collision macro, does just half of the work (checking only the left bounding when moving to the left... else the right bounding box when not moving or moving to the right).

Here's an alternate CheckForHorizontalCollision.asm script, I use it for my projects
(make a backup of your NESmaker folder or just the file, just in case... to restore if you have issues or not working well with your project)

CheckForHorizontalCollision.asm (to be placed in your "Routines\Basic\System\Macros" folder):
Code:
MACRO CheckForHorizontalCollision

;;;; RESET SOLID
	LDA #$00
    STA tile_solidity
	Sta collisionPoint0
	STA collisionPoint1
	STA collisionPoint2
	STA collisionPoint3
	STA collisionPoint4
	STA collisionPoint5
	
;;; RESET LADDER STATE	
	LDA Object_physics_byte,x
	AND #%11111101
	STA Object_physics_byte,x
	
	
	LDA Object_flags,x
	AND #%00000010
	BNE +
	JMP doLeftHorColCheck
	+

	LDA Object_h_speed_lo,x
	CLC
	ADC #$00
	LDA Object_h_speed_hi,x
	ADC #$00
	BMI + 
	JSR doRightHorColCheck
	JSR doLeftHorColCheck
	JMP ++
	+
	JSR doLeftHorColCheck
	JSR doRightHorColCheck
	++

	JMP doneWithHorColCheck
	
	
	
doLeftHorColCheck:

    LDA xHold_hi
    CLC
    ADC Object_left,x
    STA tileX

    LDA Object_y_hi,x
    CLC
    ADC Object_top,x
    STA tileY
	
    JSR GetTileAtPosition
    ;JSR DetermineCollisionTable
	;LDA #$00
	LDA Object_left,x
	STA temp
	DetermineCollisionTableOfPoints temp
	
    STA collisionPoint0
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    JMP HandleSolidCollision ;; hit a solid so won't update position. 
+   
	LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
	;;; check bottom left point

    LDA xHold_hi
    CLC
    ADC Object_left,x
    STA tileX

    LDA Object_y_hi,x
    CLC
    ADC Object_bottom,x
    STA tileY
    
    JSR GetTileAtPosition
   ; JSR DetermineCollisionTable
   	;LDA #$00
	LDA Object_left,x
	STA temp
	DetermineCollisionTableOfPoints temp

    STA collisionPoint3
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    ;LDA Object_physics_byte,x
    ;ORA #%01000000 ;; solid was at top.
    ;STA Object_physics_byte,x
    JMP HandleSolidCollision ;; hit a solid so won't update position.
+

    LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
;;;;; left middle
	LDA Object_bottom,x
    SEC
    SBC Object_top,x
    LSR 
    STA temp3 ;; temp 3 now equals half of the height of the object, so top+temp3 = mid point vertically.
  
	
    LDA xHold_hi
    CLC
    ADC Object_left,x
    STA tileX

    LDA Object_y_hi,x
    CLC
    ADC Object_top,x
    CLC
    ADC temp3
    STA tileY
    
    JSR GetTileAtPosition
    ;JSR DetermineCollisionTable
	;LDA #$00
	LDA Object_left,x
	STA temp
	DetermineCollisionTableOfPoints temp
    STA collisionPoint4
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    JMP HandleSolidCollision ;; hit a solid so won't update position.
+
    	LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
	;LDX currentObject
	LDA Object_flags,x
    AND #%00000010
	BNE +
	JMP doRightHorColCheck
	+
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
doRightHorColCheck:


    LDA xHold_hi
	CLC
    ADC Object_right,x
    STA tileX

    LDA Object_y_hi,x
    CLC
    ADC Object_top,x
    STA tileY
    
    JSR GetTileAtPosition
   ; JSR DetermineCollisionTable
   	LDA Object_right,x
	STA temp
	DetermineCollisionTableOfPoints temp
    STA collisionPoint1
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    JMP HandleSolidCollision ;; hit a solid so won't update position.
+
	LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	

    LDA xHold_hi
    CLC
    ADC Object_right,x
    STA tileX
   
    LDA Object_y_hi,x
    CLC
    ADC Object_bottom,x

    STA tileY
    
    JSR GetTileAtPosition
    ;JSR DetermineCollisionTable
	LDA Object_right,x
	STA temp
	DetermineCollisionTableOfPoints temp
    STA collisionPoint2
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    ;LDA Object_physics_byte,x
    ;ORA #%01000000 ;; solid was at top.
    ;STA Object_physics_byte,x
    JMP HandleSolidCollision ;; hit a solid so won't update position.
+
    	LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
    ;;; IF YOU NEED TO FIND OUT THE MID POINT HORIZONTALLY
    ;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 Object_bottom,x
    SEC
    SBC Object_top,x
    LSR 
    STA temp3 ;; temp 3 now equals half of the height of the object, so top+temp3 = mid point vertically.
    

    LDA Object_y_hi,x
    CLC
    ADC Object_top,x
    CLC
    ADC temp3
    STA tileY

	LDA xHold_hi
    CLC
    ADC Object_right,x
    STA tileX
     
    JSR GetTileAtPosition
    ;JSR DetermineCollisionTable
	LDA Object_right,x
	STA temp
	DetermineCollisionTableOfPoints temp
    STA collisionPoint5
    JSR CheckForCollision
    LDA tile_solidity
	AND #%00000001
    BEQ +
    JMP HandleSolidCollision ;; hit a solid so won't update position.
+
	LDA tile_solidity
	AND #%00000010
	BEQ +
	LDA Object_physics_byte,x
	AND #%00000010
	BNE +
	;;; DO LADDER STUFF
	JSR DoLadderStuff
+
	LDA Object_flags,x
    AND #%00000010
	BNE +
	JMP doneWithHorColCheck
	+
	RTS

doneWithHorColCheck:
	ENDM
 

dale_coop

Moderator
Staff member
I updated the script with a minor modification... (the previous code would cause invisible wall issues when the player bounding box was small)
 
Top Bottom