It looks like the problem is that the gravity is only applied if no buttons are being pressed. Try applying the gravity every frame like this:
if not is_on_floor():
speed.y += gravity
The issue then is that speed.y will retain its value after landing, and will keep trying to fall. I would use moveandslide() instead of moveandcollide, because it returns the distance moved as a Vector2. set
speed = move_and_slide(speed, Vector2.UP)
(Vector2.UP
is included to tell the physics engine which direction is up so it can check if it's on the floor)
Just make sure that when changing speed.x, you use "=" not "-=" or "+=" to make sure that your character moves at a constant speed.
I would do it like this.
if Input.is_action_pressed("ui_right"):
speed.x = 6
$AnimatedSprite.play("Walk")
$AnimatedSprite.flip_h = false
elif Input.is_action_pressed("ui_left"):
speed.x = -6
$AnimatedSprite.play("Walk")
$AnimatedSprite.flip_h = true
if Input.is_action_just_pressed("ui_up"):
speed.y -= 20
Then outside of the if,
speed.y += Gravity
Then finally
if speed.x == 0:
$AnimatedSprite.play("Idle")
and
speed = move_and_slide(speed, Vector2.UP)
I didn't include speed.normalized()
because 1, it returns the normalized value without actually setting speed
equal to it, and 2, because that would only allow the player to move one unit per frame in whatever direction it's going.