Fling into a direction

Question

hi I’m new to Godot coding and I want to make my character leap in the direction I’m facing when I press space (I’m using the default caracterbody2D movement code) I cant get it to change the x position (it needs to leap forward and upwards at the same time)

Can you show the code you have tried so far?

CharacterBody2D is a physics object so it is better to try using velocity and it’s move_and_slide or move_and_collide function. If you are using the characterbody template you’ll see similar functions and altering velocity.

extends CharacterBody2D

@onready var animated_sprite = $AnimatedSprite2D #flips player

const SPEED = 150.0
const JUMP_VELOCITY = -250.0
const JUMP_VELOCITY2 = -350.0
const Fling = 200.0
var dashing = false

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):# gives gravity 
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta

	# Handle jump.
	if Input.is_action_just_pressed("jump") and is_on_floor() and Input.is_action_pressed("right"): #jump
		velocity.y = JUMP_VELOCITY
	
	if Input.is_action_just_pressed("jump") and is_on_floor() and Input.is_action_pressed("left"): 
		velocity.y = JUMP_VELOCITY
	
	
	if Input.is_action_just_pressed("jump2") and is_on_floor() and Input.is_action_pressed("right"):#leap
		velocity.y = JUMP_VELOCITY2 
	
	
	
	if Input.is_action_just_pressed("jump2") and is_on_floor() and Input.is_action_pressed("left"):
		velocity.y = JUMP_VELOCITY2 
		
	
	if Input.is_action_just_pressed("jump2") and is_on_floor():#Dash
		dashing = true
		$dashtimer.start()
	
	
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("left", "right")
	if direction > 0:
		animated_sprite.flip_h = false
	if direction < 0:
		animated_sprite.flip_h = true
	#play animation
	if is_on_floor():
		if direction == 0:
			animated_sprite.play("idle")
		else:
			animated_sprite.play("run")
	else:
		animated_sprite.play("jump")
	
	
	
	if direction:
		if dashing:
			velocity.x = direction * Fling 
		else:
			velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
	
	
	move_and_slide()
	
	
	
	
# fling cooldown
func _on_dashtimer_timeout():
	dashing = false

sorry I’m fairly new so I don’t know hat to show

2 Likes

This seems great, can you go into further detail about what isn’t working? What do you expect to happen vs what really happens?

2 Likes

so I’m making a game about a cat getting revenge on another cat (its like my dream game{bit silly})but when I press space I need the cat to lunge in the direction I’m running. I want to make the cat lunge in the direction I’m running to stop me from just stopping mid air but as I said I’m new and I can’t get the cat to lunge on its own without me holding A or D to change my X position . so it needs to change the Y position (which it already does) and change the X position on its own.

Someone else could probably answer this better than me but I think you nailed the issue in the last line.

Your jump is only adding to your Y vector so try adding to X at the same time. Try something like this:

Handle jump.
if Input.is_action_just_pressed(“jump”) and is_on_floor() and Input.is_action_pressed(“right”): #jump
velocity.y = JUMP_VELOCITY
Velocity.x += JUMP_VELOCITY * 2 #positive for right movement

if Input.is_action_just_pressed("jump") and is_on_floor() and Input.is_action_pressed("left"): 
	velocity.y = JUMP_VELOCITY

velocity.x += JUMP_VELOCITY * -2 #negative for left movement. You might need to write it (-2) if you get an error

I’m using the += operator because it should add to your current moment and maybe feel a bit better than just =

So this problem is relevant to these lines of code

if direction:
	if dashing:
		velocity.x = direction * Fling 
	else:
		velocity.x = direction * SPEED
else:
	velocity.x = move_toward(velocity.x, 0, SPEED)

If they aren’t holding any keys down the direction moves toward zero. I propose one way to change this would be swapping the if around a little

if dashing:
	velocity.x = direction * Fling 
else:
	if direction:
		velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)

This could still change direction when flinging, but at max speed. @BrutalDevon has a great recommendation for setting the X speed when the dash starts, but it doesn’t take into account direction.

I feel like dashing shouldn’t be able to change direction, so I will post code for that as well. With comments pointing out changes

extends CharacterBody2D

@onready var animated_sprite = $AnimatedSprite2D

const SPEED = 150.0
const JUMP_VELOCITY = -250.0
const JUMP_VELOCITY2 = -350.0
const Fling = 200.0
var dashing = false

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):
	if not is_on_floor():
		velocity.y += gravity * delta

	if Input.is_action_just_pressed("jump") and is_on_floor(): #jump
		# reduced jump conditions
		velocity.y = JUMP_VELOCITY

	# direction must be earlier for leap
	var direction = Input.get_axis("left", "right")

	if Input.is_action_just_pressed("jump2") and is_on_floor():#leap
		# handle *all* leap velocities in one place
		velocity.y = JUMP_VELOCITY2
		velocity.x = direction * Fling
		dashing = true
		$dashtimer.start()

	if direction > 0:
		animated_sprite.flip_h = false
	elif direction < 0:
		animated_sprite.flip_h = true

	if is_on_floor():
		if direction == 0:
			animated_sprite.play("idle")
		else:
			animated_sprite.play("run")
	else:
		animated_sprite.play("jump")

	# only change X when not dashing
	if not dashing:
		if direction:
			velocity.x = direction * SPEED
		else:
			velocity.x = move_toward(velocity.x, 0, SPEED)

	move_and_slide()


# fling cooldown
func _on_dashtimer_timeout():
	dashing = false
1 Like

sorry for replying so late. It works great but the only problem is now when the cat lands it keeps sliding in the direction I jumped (the dash timer is used to stop the player from dashing constantly so it acts like an cooldown for dashing