Need helping programming a jump in a 2D Zelda like

Godot Version

4.6.stable

Question

Need helping programming a jump in a 2D Zelda like

In my 2D Zelda like I’m trying to program a jump much like how it functions with the Roc’s feather in LA/Oracles/FSA/MC but I’m having some trouble trying to get it to work. Whenever I press the jump button it only goes off for for a second before the player character continues their walk cycle, thus making the action inert.

Please advise my tutorial mashed code below that uses a state machine to go from one state to the next, as part of it’s movement functionality. I’ll take any and all suggestions for what to try, even rewriting the entire script to make this happen.

class_name Player extends CharacterBody2D
@onready var animate = $AnimationTree
@onready var stAnimate = animate.get("parameters/playback")

var SPEED = 200
var moveSpeed = 200
var dashSpeed = 325
var rollVector = Vector2.ZERO

var canMove = true
var doubleJump = false
var stats = PlayerStats

signal playerPosition(playerPosition:Vector2)

enum {
	IDLE,
	MOVE,
	ATTACK,
	SWIPE,
	JUMP,
	ROLL,
	GUARD
}

var state = IDLE

func _ready():
	animate.active = true
	stats.no_health.connect(queue_free)

func changeState(newState):
	state = newState
	match state:
		IDLE:
			SPEED = moveSpeed
			stAnimate.travel("Idle")
		MOVE:
			SPEED = moveSpeed
			stAnimate.travel("Move")
		ATTACK:
			stAnimate.travel("Attack")			
		SWIPE:
			stAnimate.travel("Swipe")
		JUMP:
			stAnimate.travel("Jump")
		ROLL:
			SPEED = dashSpeed
			roll()
		GUARD:
			stAnimate.travel("Guard")

func getInput():
	var direction = Input.get_vector("Move Left", "Move Right", "Move Up", "Move Down")
	var dirNorm = direction.normalized()
	var isJump = Input.is_action_just_pressed("Jump")
	if dirNorm != Vector2.ZERO:
		rollVector = dirNorm
		animate.set("parameters/Idle/blend_position",dirNorm)
		animate.set("parameters/Move/blend_position", dirNorm)
		animate.set("parameters/Roll/blend_position", dirNorm) 
		animate.set("parameters/Attack/blend_position", dirNorm)
		animate.set("parameters/Jump/blend_position", dirNorm)
		animate.set("parameters/Guard/blend_position", dirNorm)
		animate.set("parameters/Swipe/blend_position", dirNorm)
		changeState(MOVE)
		velocity = dirNorm * SPEED	
			
	if isJump:
		#move_and_slide()
#		Jump still isn't working.
		if get_last_motion() == Vector2.ZERO:
			changeState(JUMP)
		changeState(JUMP)
	#if isJump and velocity == Vector2.ZERO:
		#changeState(JUMP)
	if Input.is_action_just_pressed("Roll"):
		changeState(ROLL)
		if get_last_motion() == Vector2.ZERO:
			velocity = Vector2.ZERO
			changeState(GUARD)
	elif Input.is_action_just_pressed("Sword"):
		changeState(ATTACK)
		playerPosition.emit(self.position)
		if get_last_motion() == Vector2.ZERO:
			changeState(SWIPE)
	elif  Input.is_action_just_pressed("Interact"):
		return
	elif dirNorm == Vector2.ZERO:
		stAnimate.travel("Idle") 
		velocity = Vector2.ZERO	
		changeState(IDLE)

func _physics_process(delta):
	if DialogueManager.is_dialog_active:
		return
	if canMove == false:
		return
	getInput()
	move_and_slide()

*Note, I did make a 2nd code where the jump worked but the player character stayed in place for this instance.

Thank you

You have to assume that we haven’t played any of these games and don’t know what you mean exactly.
Please describe in detail what you’re trying to achieve vs what happens.

I played the games, specifically Oracle of Ages and Link’s Awakening.
Roc’s Feather is basically just an item that allows you to jump over monsters and holes or jump in general.
*Should help with help.

1 Like

So just a regular jump then?

1 Like

Basically. (yes)

1 Like

@superhyperhedgey I suggest to try out the @dragonforge-dev’s state machine.

It includes examples of simple states, including the jump, so you don’t have to reinvent the wheel.

1 Like