[4.5.6] Grab Hook Tile Mechanic (Platformers)

Jonny

Well-known member
I wanted to replicate the grab hook and hang mechanic as used by those two famous ducks. The purple one and the rich one. Say no more.

It's not exactly the same yet but its fairly close. The only part I need to work on (apart from the grab animation for my player) is the dropping. If down is just tapped and not held, the player will try to fall then the tile script, for want of a better term, 'takes over' and snaps him back to the hook. I've tried a few things to no avail so for now this is as good as my grab tile is going to get...

grabhooks.gif

Tile Code:

Code:
;;; CHECK IS PLAYER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
    CPX player1_object
    BEQ isThePlayer
    JMP dontGrab


;;; CHECK GAMEPAD FOR L OR R PRESS ;;;;;;;;;;;;;;;;;;;;;;;;;

isThePlayer:
    LDA gamepad         
    CMP #%00100000      ;; DOWN, LEFT, OR RIGHT ;;
    BCS dontGrab
 
 
;;; DONT GRAB WHILE JUMPING UP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LDA Object_v_speed_hi,x        ;; VERT SPEED CHECK        ;;
    BMI dontGrab        


;;; SNAP TO CORRECT PLAYER PLACEMENT ;;;;;;;;;;;;;;;;;;;;;;;

    LDA tileX
    AND #%11110000
    SBC #$00
    STA Object_x_hi,x
    STA xHold_hi
 
    LDA tileY
    AND #%11110000
    SBC #$0F
    STA Object_y_lo,y
    STA yHold_hi


;;; CHANGE ACTION TO GRABBING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
    ChangeActionStep player1_object, #$06

dontGrab:

This is fairly simple but there's a few bits you might want to change to suit your hook grabbing needs. The Y and X offset are unlikely to be the same for your player object, especially if its a different size. Also, my action step for player 'hanging' is #$06 and you might want to use a different one. I should also mention that my action #$06 has ignore gravity ON.

The only other parts are small changes to 2 other input scripts and you can also make a 'drop down' input for down press if you don't want to have to jump off to get down.

For MoveLeft / MoveRight i added another check almost identical to the check for player hurt (directly under the player hurt check for #$07 ...

Code:
CMP #$06     ;; DUDE, I'M HANGING HERE ;;
BNE +notHurt
RTS

The 'drop down' script for press down when on hook is just a simple action change to a state with ignore gravity off...

Code:
;;; DROP FROM HOOK ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    TXA
    STA temp
    ChangeActionStep temp, #$00 ;; CHANGE TO IDLE         ;;
 
    RTS

The last and maybe most crutial part is that the grabtile needs to be the tile UNDER the actual hook graphic.

That's it. Enjoy.

EDIT: Code updated as per AllDarnDavey suggestion. Please read his comments regarding inputs also if you want your player to change facing while hanging.
 
Last edited:

5kids2feed

Well-known member
Looks AWESOME! Great little mechanic you cooked up. Now to fit it into my next game 🙌🏻

Also.. Are you using mesen to create gifs or another program?
 

AllDarnDavey

Active member
This is awesome!!

Your code is great, but because the gamepad checks are the three highest bits, instead of using 3 different checks, you could just do a single greater or equal check.

Code:
;;; CHECK GAMEPAD FOR L OR R PRESS ;;;;;;;;;;;;;;;;;;;;;;;;;

isThePlayer:
    LDA gamepad         
    CMP #%00100000                    ;; DOWN, LEFT, OR RIGHT PRESSED?       ;;
    BCS dontGrab                          ;; GREATER OR EQUAL BRANCH             ;;
 

Jonny

Well-known member
This is awesome!!

Your code is great, but because the gamepad checks are the three highest bits, instead of using 3 different checks, you could just do a single greater or equal check.

Code:
;;; CHECK GAMEPAD FOR L OR R PRESS ;;;;;;;;;;;;;;;;;;;;;;;;;

isThePlayer:
    LDA gamepad      
    CMP #%00100000                    ;; DOWN, LEFT, OR RIGHT PRESSED?       ;;
    BCS dontGrab                          ;; GREATER OR EQUAL BRANCH             ;;
Thank you. I'll change that.
I was trying to put something in to allow player to change direction when hanging (but not move). That would be the only reason to have them separate but I couldn't get it to work so might as well use your shorter version.
I could actually remove some of the 'snap' code too as I'm not changing X but left it in because when graphics are done I'll probably need to tweek it so hang looks like it's actually grabbing the hook.
The character has such short arms it's hard to get anything to look like hanging.
 
Last edited:

AllDarnDavey

Active member
I was trying to put something in to allow player to change direction when hanging (but not move). That would be the only reason to have them separate but I couldn't get it to work so might as well use your shorter version.
Ahh, that would probably mean adding something in your moveLeft & moveRight inputs to change facing direction if in action06, but not move. Already looking awesome though!

Code:
CMP #$06     ;; DUDE, I'M HANGING HERE ;;
BNE +notHurt
ChangeFacingDirection temp, #FACE_LEFT    ;;USE #FACE_RIGHT ON MOVERIGHT SCRIPT OBVIOUSLY ;;
RTS
 

Jonny

Well-known member
I tried that but something was causing the player to glide in that direction. I think I'll try it again. I was messing about with so much stuff it could have been another part of the code causing problems that's now changed. It should work in theory. I'll change both suggestions and see what happens.
 

Jonny

Well-known member
Ahh, that would probably mean adding something in your moveLeft & moveRight inputs to change facing direction if in action06, but not move. Already looking awesome though!

Code:
CMP #$06     ;; DUDE, I'M HANGING HERE ;;
BNE +notHurt
ChangeFacingDirection temp, #FACE_LEFT    ;;USE #FACE_RIGHT ON MOVERIGHT SCRIPT OBVIOUSLY ;;
RTS

Thanks again. I made these two changes and it's perfect now.
When I tried it I think I may have missed the RTS by accident meaning the code would continue.

Quite happy with this now. I need to make a decent hanging animation...
 

crazygrouptrio

Active member
Hey I know I'm several months behind on this awesome scripting, but I'm trying to implement this code and I'm encountering 2 issues, both are shown in the gif.
1. Did you do anything regarding your jump script? Your character is jumping from hook to hook, while in mine when he's hanging pressing jump does literally nothing. This could an issue with the player's size being different, but even when I force the player to jump (bypassing the check for solid under feet stuff) it still sticks to the grab tile.
2. Dropping down doesn't actually change to the idle action step, for some reason? I mean, it's a pretty simple script to change to action step 0, so not sure where that could go wrong, but it's not doing it. This I can probably work around, just thought I'd bring it up.
Still awesome! Hopefully I can actually use it soon 😅
dudeissue1.gif
 

Jonny

Well-known member
I'll have a gander after my holiday and let you know. I need to revisit this and improve for my own project too. I will post the scripts I'm using and the tile collisions. Back next week.
 

9Panzer

Well-known member
@Jonny Sweet, I've been looking at this one for a while. I think I have an idea of how to implement it. If you are improving on it I'm all ears! :)
 

Jonny

Well-known member
@Jonny Sweet, I've been looking at this one for a while. I think I have an idea of how to implement it. If you are improving on it I'm all ears! :)
I was discussing this with Mugi in the discord server recently. If you can find that he posted some code too and it seemed like a better way to do it. Try both I guess to find what works best for you. You've reminded me I still need to look at jump script to double check any differences for CGT.
 

9Panzer

Well-known member
@Jonny I've been playing around with the idea of doing a sequel to Panzer. Being able to switch characters and have them have a unique moveset is something I REALLY want to implement. This kind of stuff is GOLD for that :)
 

TolerantX

Active member
Yeah, I was thinking of adding this to my arcade platformer in some later levels as a cool mechanic. nice work!
 

Levty87

New member
Hi, I implemented the scripts. My player snaps to the tile, but how do I get him to jump from ring to ring?
 

Jonny

Well-known member
Hi, I implemented the scripts. My player snaps to the tile, but how do I get him to jump from ring to ring?

This was such a long time ago. Honestly, can't remember if I added something to jump script. What happens when you jump now? Nothing?
 

Levty87

New member
I was discussing this with Mugi in the discord server recently. If you can find that he posted some code too and it seemed like a better way to do it. Try both I guess to find what works best for you. You've reminded me I still need to look at jump script to double check any differences for CGT.
Do you know where I can find the alternative code? And what's with the discord server? Is that a place where you can find more resources?
 

DocNES

Member
the player falls to the grond. :unsure:


View attachment 6983
I just got it working in my game. You need to change your Player Action Step 6 to ignore gravity.
I only used the code by @Jonny here, and didn't take the time to look at conversation on Discord.

I could use a hand. When are jumping though platforms when I run the, Drop through OneWay Tile code. I must have a wire crossed where both player and monsters are using the same temp or value?
Also, I can snap to it, and drop. Just can't jump like in the gif






Discord Server information can be found here my dude:
 
Last edited:

Jonny

Well-known member
@Levty87 @DocNES Apologies for the delayed reply to this. I don't think I ever shared the modified jump through tile input script because it was broken (caused game to crash intermittently). I'll paste it below incase you want to have a go at fixing it before I get chance to. The commented out parts are what makes player able to jump off the hook. This was a long time ago and I haven't really looked at it yet properly, but will do eventually (Soon™)
Code:
;;; BELOW FEET IS FREE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    SwitchBank #$1C
    LDY Object_type,x
    LDA ObjectBboxTop,y
    CLC
    ADC ObjectHeight,y
    STA temp2
   
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    STA temp
    JSR getPointColTable
   
    LDA Object_y_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp1

 
;;; IF HANGING JUMP REGARDLESS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;    GetActionStep temp3  ;;  **** CAUSES CRASH !!!!! **** ;;
;    CMP #$06             ;;  **** CAUSES CRASH !!!!! **** ;;
;    BNE +carryonchecks   ;;  **** CAUSES CRASH !!!!! **** ;;
;    JMP +doJump          ;;  **** CAUSES CRASH !!!!! **** ;;


;;; TILE CHECKS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+carryonchecks
 
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkMore                         ;; SOLID CHECK ;;
    JMP +doJump
    +checkMore
   
    CheckCollisionPoint temp, temp1, #$07, tempA
    BNE +checkMore                         ;;JUMP THROUGH ;;
    JMP +doJump
    +checkMore
   
    CheckCollisionPoint temp, temp1, #$0C, tempA
   BNE +dontDoJump                        ;; GRAB TILE 06  ;;
    JMP  +doJump
   +dontDoJump

   
;;; CHECK SECOND POINT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDY Object_type,x
    LDA ObjectWidth,y
    CLC
    ADC temp
    STA temp
    JSR getPointColTable
   
    CheckCollisionPoint temp, temp1, #$01, tempA
    BEQ +doJump
   
    CheckCollisionPoint temp, temp1, #$07, tempA
    BEQ +doJump
   
    CheckCollisionPoint temp, temp1, #$0C, tempA ;;;06
      BEQ +doJump
   
    JMP +skipJumping

+doJump:
   
;   PlaySound #sfx_bonk

    TXA
    STA temp
   
    LDY Object_type,x
    LDA ObjectJumpSpeedLo,y
    EOR #$FF
    STA Object_v_speed_lo,x
    LDA ObjectJumpSpeedHi,y
    EOR #$FF
    STA Object_v_speed_hi,x
       
    TXA
    STA temp

    +skipJumping
    ReturnBank
    RTS
 
Top Bottom