weird collision issues.

dale_coop

Moderator
Staff member
Glad we fixed your issue ;)
Your object_movement might have other bit set, so if you just want to test if facing right or left, you have to "filter" the variable to only the bits you want to test.
 

Mugi

Member
i tried with just AND #%00000110 and i tried
AND #%00000110
CMP #%00000110

but it's still doing it apparently, it just picks the facing direction of the monster...
man im really starting to lose my shit over this.


i even tried to make my inputs set a new var based on my moving direction, and use that instead of the object_movement, and it STILL does it.
 

Mugi

Member
okay now it's really solved for good.

had to use
AND #%00001111
CMP #%00000110
for the compare with the direction, because the upper bits are sometimes set (inertia is stored there i believe.)

the actual problem what that the code was doing the collision compare incorrectly.
i was comparing the collision point to a wall tile (tile type 00) instead of wall grab tile (type 03) which basically caused the monsters touching the normal walls count as collision.

i was thinking that since the tile code only runs during collisions, that doing a collision check there would only compare the collision point with that tile, but in reality it is doing a global collision compare against tiletype 00 everywhere.

so doing

LDA collisionPoint0,x
CMP #$03 ; tiletype of wall grab tile


returns a collision against a wall grab tile instead, and now unless a monster collides with a wall grab tile at the exact same moment than the player attempts to grab a wall, it will work.
the chance of that is sorta like meeting an unicorn so im ready to call it a day at this point.
 

Mugi

Member
yeah, it was just an infuriating logic error on my end at the end of the day.
i thought the collision works a little differently than it actually does.
 

mongolianmisfit

New member
Hey Mugi, originally I posted on the facebook group while the forum was down recently, but Dale directed me here.

Originally I was trying to recreate a Megaman style ladder, but since I am making an intentionally fast platformer, the traditional ladder functionality slowed down the pace of the game.
I then had a thought after toying around with some of Dale's code from the forums that cancelled the jump when the player is on the ladder, unless left or right are held and jump is pressed:
- "What if the ladder tile were instead a hanging/grab point for the player?"
56483210_10157162003313839_7077713264624271360_o.jpg


Now, after seeing you and Dale troubleshoot this here, I've tried replacing the ladder tile with the following code:

Code:
    LDA gamepad
    AND #%00010000              ; is up pressed ?
    BEQ dontMessWithGravity

    ; LDA Object_physics_byte,x
    ; AND #%00000001              ; Are we in the air ?
    ; BNE dontMessWithGravity

    LDA Object_v_speed_hi,x
    BMI dontMessWithGravity

    LDA Object_movement,x
	AND #%00001111
    CMP #%00000110
    BEQ checkLeftCollisionOnly
    
    LDA collisionPoint1,x
    BEQ dontMessWithGravity
    JMP doGrab
    
checkLeftCollisionOnly:
    LDA collisionPoint0,x
	CMP #$07 ; tiletype of wall grab tile
    BEQ dontMessWithGravity
doGrab:
    ChangeObjectState #$07, #$08

dontMessWithGravity:

...but it's had no effect on the a placed ladder tile in my game while testing. I assume I'm doing something very wrong, or just going about this the wrong way?
I would seriously be sooooo thankful for any help with this. I've spent about 2 months banging my head against this to no avail.
 

Mugi

Member
might as well share the whole thing i guess...

the script you've got there is more or less the complete wall grab. it's not a really complicated code.
but it requires some extra set up to work (atleast in the way it's set up in dimension Shift)

here's the current version of the wallgrab tile:

Code:
    CPX player1_object
    BNE dontMessWithGravity

    LDA gamepad
    AND #%00010000              ; is up pressed ?
    BEQ dontMessWithGravity
    
    LDA Object_v_speed_hi,x     ; are we falling downwards ?
    BMI dontMessWithGravity
    CLC
    ADC Object_y_hi,x           ; are we in map bounds ?
    CMP #$10
    BCC dontMessWithGravity
    CMP #$D6
    BCS dontMessWithGravity
    
    LDX player1_object          ; fetch facing direction of player 
    LDA Object_movement,x
    AND #%00001111
    CMP #%00000110
    BEQ doLeftCollisionCheck

    LDA collisionPoint1         ; compare top right collision point
    CMP #$03                    ; compare against "wallgrab tile"
    BNE dontMessWithGravity
    JMP doGrab
    
doLeftCollisionCheck:
    LDA collisionPoint0         ; compare top left collision point
    CMP #$03                    ; compare against "wallgrab tile"
    BNE dontMessWithGravity

doGrab:                         ; enable grabbing the wall
    ChangeObjectState #$07, #$03

dontMessWithGravity:

first of all, your object state for "wall grab" has to have gravity turned off (this makes the player stick to the wall)
and secondly, you will need a custom jump for this action state, because when gravity is turned off, you cant move.

to attain a "no gravity jump" you'll have to add the following to your jump input script.
Code:
   GetCurrentActionType player1_object
   CMP #$07
   BEQ doWallClimbJumpThing
   RTS
doWallClimbJumpThing:
    ChangeObjectState #$02, #$03
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    RTS

obviously placed into the script in a manner that it doesnt break other parts of the jump script.
however, it should be one of the first checks in the script since the wall grab will have to take priority over other actions if you want it to work reliably.

in addition to that, disabling player's movement (left and right) when the player is on the wall, can eb achieved by adding the following to extra controller script

Code:
    LDX player1_object
    GetCurrentActionType player1_object
    STA temp
    CMP #$07
    BNE +
    LDA gamepad
    AND #%00111111
    STA gamepad
    RTS  
+

game-1.png
 

mongolianmisfit

New member
Thanks for your help, Mugi! But I'm hitting some snags due to my own ASM ignorance I'm sure.

1. I've just copy/pasted my ladder tile script with the wall grab tile (I don't think this should cause an issue).
2. My player's number 4 action step (climb) is set to ignore gravity.
3. I've included the modification to the jump script, but receive the following error:
Routines\Basic\ModuleScripts\InputScripts\SimplePlatformer\a_simple_jump.asm(9): Branch out of range.
Code:
; a jumps
 
   LDX player1_object
   ;;; let's check for if we are standing on a jumpthrough platform,
   ;;; for which "down and jump" will jump downwards through
   ;;; comment this out if you do not want that functionality
    LDA screenFlags
    AND #%00100000 ;; does it use gravity?
    BEQ dontJump
	
GetCurrentActionType player1_object
   CMP #$07
   BEQ doWallClimbJumpThing
   RTS
doWallClimbJumpThing:
    ChangeObjectState #$02, #$03
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    RTS
    
   LDA Object_physics_byte,x
   AND #%00001000
   BEQ notStandingOnJumpThroughPlatform
   LDA gamepad
   AND #%00100000
   BEQ notStandingOnJumpThroughPlatform
   LDA Object_y_hi,x
   CLC
   ADC #$09
   STA Object_y_hi,x
   JMP dontJump
notStandingOnJumpThroughPlatform:
   
   LDA Object_physics_byte,x
   AND #%00000001
   BNE canJump
   LDA Object_physics_byte,x
   AND #%00000100
   BEQ dontJump
    
canJump:
    ;;; TURN OFF "STANDING ON JUMPTHROUGH PLATFORM" if it is on
    LDA Object_physics_byte,x
    AND #%11110111
    STA Object_physics_byte,x
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    GetCurrentActionType player1_object
    CMP #$03 ;; attack
    BEQ +
    ChangeObjectState #$02, #$04
   +
    PlaySound #SND_JUMP
dontJump:
    RTS

4. And lastly, I've tried including the "disable player movement when on wall" snippet to ExtraControllReadCode.asm, but I'm fairly certain that how I'm placing it at the very end is wrong?:
Code:
ExtraInputControl:

    ;;; occasionally, there is input code that may be very specific, and it may be 
    ;;; difficult to implement via the visual interface and accompanying scripts.
    ;;; this is a code that runs after all input checks, and allows for custom ASM.
    LDA gameState
    CMP #GS_MainGame
    BEQ doMainGameUpdates
    JMP skipMainGameExtraInputControl
doMainGameUpdates:  
    LDX player1_object

	GetCurrentActionType player1_object
	STA temp
	LDA Object_physics_byte,x
	AND #%00000010
	BEQ isNotClimbing
    LDA temp
    CMP #$04
    BNE isNotClimbing
	LDA gamepad
	AND #%11000000
	BEQ noDirWhileClimbing
	ChangeObjectState #$02, #$04
noDirWhileClimbing:
    ;;; is climbing.
    ;;; which means don't check to change to idle.
   JMP skipMainGameExtraInputControl
isNotClimbing:
    LDA temp
    CMP #$03 ;; is it shooting (shooting is same anim in air and on ground)
    BNE isNotAttackingAction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    JMP skipMainGameExtraInputControl
isNotAttackingAction:   
    
    LDA gamepad
    AND #%11000000 ;;; left and right
    BEQ dontskipMainGameExtraInputControl
	JMP skipMainGameExtraInputControl
dontskipMainGameExtraInputControl:
    ;;; if left and right are not pressed
	
	LDA screenFlags
	AND #%00100000 ;; does it use gravity?
					;; if it does not, it would not have jumping or ducking, so
					;; skip state updates for jumping and ducking.
	BEQ notDucking ;; just will change to idle.

    LDA Object_physics_byte,x
    AND #%00000001 ;; if is in air
    BNE notInAir
    GetCurrentActionType player1_object
    CMP #$02 ;; is it already state 2?
    BEQ skipMainGameExtraInputControl

    ChangeObjectState #$02, #$04
    JMP skipMainGameExtraInputControl
notInAir:
    LDA Object_h_speed_lo,x
    ORA Object_h_speed_hi,x
    BNE skipMainGameExtraInputControl
    ;;;; controller is not pressed
    ;;;; horizontal speed is zero.
    ;; check to see if in air, shooting, etc.
	 LDA gamepad
	AND #%00100000 ; if down is pressed
	BEQ notDucking
	 ChangeObjectState #$5, #$04
	 JMP skipMainGameExtraInputControl
skipMainGameExtraInputControl:
	RTS

notDucking:
	LDA gamepad
	AND #%11110000
	BNE skipMainGameExtraInputControl2
	GetCurrentActionType player1_object  ; check curren state
	BEQ skipMainGameExtraInputControl2   ; if already 0, don't change it again.
	ChangeObjectState #$00, #$04
skipMainGameExtraInputControl2:

    LDX player1_object
    GetCurrentActionType player1_object
    STA temp
    CMP #$07
    BNE +
    LDA gamepad
    AND #%00111111
    STA gamepad
    RTS  
+   
	RTS

Thank you, again for looking. If I can put a bow on this feature, I'd love to represent you and Dale in the game's credits. :)
 

Mugi

Member
It's better to make a new tiletype to the wall climb than to replace the ladder one with it, because if my memory serves me right, the ladders have some hardcoded functionality that might mess things up.

anyway, here's a jump script and extra control script set up in a way that should do the job, give them a go.

jump:
Code:
; a jumps
 
   LDX player1_object
   ;;; let's check for if we are standing on a jumpthrough platform,
   ;;; for which "down and jump" will jump downwards through
   ;;; comment this out if you do not want that functionality
GetCurrentActionType player1_object
   CMP #$04		; set this to your climb action state 
   BEQ doWallClimbJumpThing

    LDA screenFlags
    AND #%00100000 ;; does it use gravity?
    BNE dontDoWallClimbJumpThing
    JMP dontJump
	
doWallClimbJumpThing:
   ChangeObjectState #$02, #$03
   LDA #$00
   SEC
   SBC #JUMP_SPEED_LO
   STA Object_v_speed_lo,x
   LDA #$00
   SEC
   SBC #JUMP_SPEED_HI
   STA Object_v_speed_hi,x
   RTS

dontDoWallClimbJumpThing:    
   LDA Object_physics_byte,x
   AND #%00001000
   BEQ notStandingOnJumpThroughPlatform
   LDA gamepad
   AND #%00100000
   BEQ notStandingOnJumpThroughPlatform
   LDA Object_y_hi,x
   CLC
   ADC #$09
   STA Object_y_hi,x
   JMP dontJump
notStandingOnJumpThroughPlatform:
   
   LDA Object_physics_byte,x
   AND #%00000001
   BNE canJump
   LDA Object_physics_byte,x
   AND #%00000100
   BEQ dontJump
    
canJump:
    ;;; TURN OFF "STANDING ON JUMPTHROUGH PLATFORM" if it is on
    LDA Object_physics_byte,x
    AND #%11110111
    STA Object_physics_byte,x
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    GetCurrentActionType player1_object
    CMP #$03 ;; attack
    BEQ +
    ChangeObjectState #$02, #$04
   +
    PlaySound #SND_JUMP
dontJump:
    RTS

extrainputcontrol:
Code:
ExtraInputControl:

    ;;; occasionally, there is input code that may be very specific, and it may be 
    ;;; difficult to implement via the visual interface and accompanying scripts.
    ;;; this is a code that runs after all input checks, and allows for custom ASM.
    LDA gameState
    CMP #GS_MainGame
    BEQ doMainGameUpdates
    JMP skipMainGameExtraInputControl
doMainGameUpdates:  
    LDX player1_object
    GetCurrentActionType player1_object
    STA temp
    CMP #$04		; set this to your climb action state
    BNE +
    LDA gamepad
    AND #%00111111
    STA gamepad
    RTS  
+   
    LDX player1_object

	GetCurrentActionType player1_object
	STA temp
;	LDA Object_physics_byte,x
;	AND #%00000010
;	BEQ isNotClimbing
;    LDA temp
 ;   CMP #$04
 ;   BNE isNotClimbing
;	LDA gamepad
;	AND #%11000000
;	BEQ noDirWhileClimbing
;	ChangeObjectState #$02, #$04
;noDirWhileClimbing:
    ;;; is climbing.
    ;;; which means don't check to change to idle.
 ;  JMP skipMainGameExtraInputControl
isNotClimbing:
    LDA temp
    CMP #$03 ;; is it shooting (shooting is same anim in air and on ground)
    BNE isNotAttackingAction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    JMP skipMainGameExtraInputControl
isNotAttackingAction:   
    
    LDA gamepad
    AND #%11000000 ;;; left and right
    BEQ dontskipMainGameExtraInputControl
	JMP skipMainGameExtraInputControl
dontskipMainGameExtraInputControl:
    ;;; if left and right are not pressed
	
	LDA screenFlags
	AND #%00100000 ;; does it use gravity?
					;; if it does not, it would not have jumping or ducking, so
					;; skip state updates for jumping and ducking.
	BEQ notDucking ;; just will change to idle.

    LDA Object_physics_byte,x
    AND #%00000001 ;; if is in air
    BNE notInAir
    GetCurrentActionType player1_object
    CMP #$02 ;; is it already state 2?
    BEQ skipMainGameExtraInputControl

    ChangeObjectState #$02, #$04
    JMP skipMainGameExtraInputControl
notInAir:
    LDA Object_h_speed_lo,x
    ORA Object_h_speed_hi,x
    BNE skipMainGameExtraInputControl
    ;;;; controller is not pressed
    ;;;; horizontal speed is zero.
    ;; check to see if in air, shooting, etc.
	 LDA gamepad
	AND #%00100000 ; if down is pressed
	BEQ notDucking
	 ChangeObjectState #$5, #$04
	 JMP skipMainGameExtraInputControl
skipMainGameExtraInputControl:
	RTS

notDucking:
	LDA gamepad
	AND #%11110000
	BNE skipMainGameExtraInputControl2
	GetCurrentActionType player1_object  ; check curren state
	BEQ skipMainGameExtraInputControl2   ; if already 0, don't change it again.
	ChangeObjectState #$00, #$04
skipMainGameExtraInputControl2:

	RTS

not quite sure if the extrainput control will work or not, it's quite different from mine so cant really test it out.
i commented out the part that has to do with ladders since that will obviously mess things up
 

dale_coop

Moderator
Staff member
You know what, Mugi, you should copy paste those insttructions and code snippets in a new "Grab Wall tile type" thing topic...
Your script is very interesting (sure, a lot of members would like to implement that for their game too) and should be saved in the "Scripts" section of the forum.
 

Mugi

Member
i suppose.
I wasnt going to just dump it on the forum to begin with since i kinda like the idea that not every game ever has an identical mechanic to mine, which is why i made it to replace ladders to begin with, but oh well.

here you go: http://nesmakers.com/viewtopic.php?f=35&t=2608
 

mongolianmisfit

New member
It's working!!!
Seriously, thank you so much, Mugi. I can stop losing sleep over this now. Honestly, if you or Dale ever put up a donation/tip-jar, you'll both have to let me know.

Additionally, I would like to acknowledge you in the credits of my game once it is complete, would "Mugi" suffice, or do you have another name you'd like to be credited as?

Again, thank you. :D
 

Mugi

Member
Mugi is fine if you insist on tarnishing your game with my name :p

also, i forgot to mention it but the tile code assumes that the tile ID of the wall climb tile is 03
if you set it to any other tile ID than 03, it will still work, but the collision checks it has will not properly work, making the "grab" not as accurate as it can be.
there are 2 "CMP #$03" codes in the tile script, change those to match the tile ID you are using it on.
 

mongolianmisfit

New member
It's actually super funny you say that. Right after seeing the updated code you provided, I found myself curious why it wasn't working, because the 3 scripts looked solid.
I like having a go at troubleshooting things for myself before seeking help, and I was able to narrowed down it being an incorrect tile ID. After the correction, it worked like a charm, and that's when I sent my "It's working!!!" reply.

ASM is real tough compared to modern development languages, especially for someone who is an artist/designer first, apprentice developer at best, script kiddy at worst. lol
Thankfully, kind people like you, Dale, and Jotoroid (among others) take pity on us plebeians by sharing your knowledge, time, and hard work.
 
Top Bottom