So I followed HeartBeast's tutorial on YouTube for making a 2D platformer. I've been able to implement a double jump feature to the player. But I'm struggling to work on the dash feature. I can do it using a separate dash button but what I'm trying to do is make the player dash only when double-tapping the arrow keys.

EDIT - Also, for some reason, my acceleration is not working. I'm new to Godot so sorry if I've made some stupid mistakes in the code.

I've pasted the code for reference -

extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20
var MAX_SPEED = 250
const JUMP_HEIGHT = -500
const ACC = 50

var motion = Vector2()
var friction = false
var djump = -1
var rtap = 0
var dash = -1



func _ready():
	pass



func _physics_process(delta):
	
	motion.y += GRAVITY
	dash = -1

	if Input.is_action_pressed("ui_right"):

		motion.x = min(motion.x + ACC, MAX_SPEED)
		$Sprite.flip_h = false
		$Sprite.play("Run")
		if dash!=0:
			#double_tap_dash()
			if Input.is_action_just_released("ui_right"):
				rtap = 1
				$DashStart.start()
			if Input.is_action_just_pressed("ui_right") && rtap!=2:
				#motion.x=2000
				MAX_SPEED == 2000
				print(motion.x)
				#$Sprite.flip_h = false
				#$Sprite.play("Fall") #"Dash"
				rtap = 2
			$DashMid.start()
			$DashEnd.start()

	elif Input.is_action_pressed("ui_left"):
		
		motion.x = max(motion.x - ACC, -MAX_SPEED)
		$Sprite.flip_h = true
		$Sprite.play("Run")
		if dash!=0:
			#double_tap_dash()
			if Input.is_action_just_released("ui_left"):
				rtap = 1
				$DashStart.start()
			if Input.is_action_just_pressed("ui_left") && rtap!=2:
				#motion.x=-2000
				MAX_SPEED == -2000
				print(motion.x)
				#$Sprite.flip_h = true
				#$Sprite.play("Fall") #"Dash"
				rtap = 2
			$DashMid.start()
			$DashEnd.start()

	else:
		friction = true;
		$Sprite.play("Idle")
		
	if is_on_floor():
		djump = -1
		if Input.is_action_just_pressed("ui_up"):
			motion.y = JUMP_HEIGHT
			djump = 1
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.15)
	else:
		if Input.is_action_just_pressed("ui_down"):
			motion.y = max(motion.y + ACC, MAX_SPEED)
		#if Input.is_action_just_pressed("ui_up"):
		#	motion.y = JUMP_HEIGHT
		$Sprite.play("Jump")
		if(motion.y < 0):
			$Sprite.play("Jump")
		else:
			$Sprite.play("Fall")
			if djump != 0:
				if Input.is_action_just_pressed("ui_up") && djump == 1:
					motion.y = JUMP_HEIGHT # + 150
					djump = 0
				
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.15)
		if Input.is_action_just_pressed("ui_up") && djump != 0:
			motion.y = JUMP_HEIGHT # + 150
			djump = 0
		
	motion = move_and_slide(motion, UP)
	pass



func double_tap_dash():
	if Input.is_action_just_released("ui_right"):
		rtap = 1
		$DashStart.start()
		if Input.is_action_just_pressed("ui_right") && rtap!=2:
			#motion.x=2000
			MAX_SPEED == 2000
			#$Sprite.flip_h = false
			#$Sprite.play("Fall") #"Dash"
			rtap = 2
	if Input.is_action_just_released("ui_left"):
		rtap = 1
		$DashStart.start()
		if Input.is_action_just_pressed("ui_left") && rtap!=2:
			#motion.x=-2000
			MAX_SPEED == 2000
			#$Sprite.flip_h = true
			#$Sprite.play("Fall") #"Dash"
			rtap = 2
	#return motion.x



func _on_DashStart_timeout():
	pass # Replace with function body.



func _on_DashEnd_timeout():
	dash=1
	rtap=2
	pass # Replace with function body.


func _on_DashMid_timeout():
	dash=0
	rtap=0
	MAX_SPEED == 250
	pass # Replace with function body.
a month later

Looks like you got an extra = in there which only compares the values, one = would set the new MAX_SPEED. If you mean that ACC is not changing, it is set as a constant instead of variable. It would be handy with nested events but that is not built in, is_action_just_released is only true for one frame, and any is_action_just_pressed inside that that frame should never be detected. An alternative is to count up rtap on every action press (trigger dash when 2 is reached) and reset rtap after x number of process loops later.

8 months later

Using flurick's suggestion, I figured it out. Here's the Dash portion of my code:

var Acceleration = 1000.0
var MaxSpeed = 200.0
var TapCountRight = 0
var TapCountLeft = 0
var Dashing = false
var motion = Vector2.ZERO

func _physics_process(delta: float) -> void:

#To the Right
	if Input.is_action_just_pressed("ui_right") and Dashing == false:
		TapCountRight += 1
		yield(get_tree().create_timer(.2),"timeout")
		TapCountRight = 0
	if Input.is_action_pressed("ui_right") and Dashing == false and TapCountRight == 2:
		Dashing = true
		MaxSpeed = 600
		Acceleration = 4000
		yield(get_tree().create_timer(.5),"timeout")
		MaxSpeed = 200
		Acceleration = 1000
		Dashing = false
#To the Left
	if Input.is_action_just_pressed("ui_left") and Dashing == false:
		TapCountLeft += 1
		yield(get_tree().create_timer(.2),"timeout")
		TapCountLeft = 0
	if Input.is_action_pressed("ui_left") and Dashing == false and TapCountLeft == 2:
		Dashing = true
		MaxSpeed = 600
		Acceleration = 4000
		yield(get_tree().create_timer(.5),"timeout")
		MaxSpeed = 200
		Acceleration = 1000
		Dashing = false

As you can see, I used variables instead of constants so they can be modified. I know it's sloppy and I'm sure there are better ways to do this. If you wanted to keep the constants for MaxSpeed and Acceleration you could just create Dash specific variables and plug it into your physics process. I just found this easier. This code produces a short burst dash. I also made a version that is a sprint that lasts until an "Input.is_action_released()" happens that returns the MaxSpeed and Acceleration variables back to normal and makes "Dashing" false. I'm sure there's also a way to combine the left and right versions of this to get it done in fewer lines, but was having enough trouble getting this working, but it does work. I included a couple dox of the full basic player code I made to show how this relates to the rest of the code. Hope this helps!

		
		
3 years later