0 votes

The idea is to create a "squash and stretch" animation.
I already did the jump animation with

$tween_squash.interpolate_property(sprite, "scale", Vector2(2.5, 3.5), Vector2(3, 3), .4, Tween.TRANS_SINE, Tween.EASE_IN_OUT)

And now, i want to know how to make the "collision with the ground" animation, that will be:

 $tween_squash.interpolate_property(sprite, "scale", Vector2(3.5, 2.5), Vector2(3, 3), .4, Tween.TRANS_SINE, Tween.EASE_IN_OUT)

I want to do something like "the player touched the ground and will do this animation, only once."

This is the result i want.

asked Jan 7 in Engine by CaueHenrique (25 points)

1 Answer

+1 vote
Best answer

I created a variable called _was_airborne and used AnimationPlayer for the squashing while stretching based on the body velocity.y

Imgur

Assuming you're using a KinematicBody2D:

var _was_airborne = true

func _physics_process(delta):
    if _was_airborne:
        $AnimationPlayer.play('Squash')
        _was_airborne = false
    if not is_on_floor():
        _was_airborne = true

This is my tree

 ┖╴KinematicBody
    ┠╴Sprite
    ┠╴Shape
    ┠╴JumpTimer
    ┖╴AnimationPlayer

and full script:

extends KinematicBody2D

var gravity = 1000
var speed = 100
var damping = 0.1
var jump_speed = 2000
var gravity_scale = 1

var velocity = Vector2()

var _was_airborne = true

func _physics_process(delta):
    if Input.is_action_pressed('left'):
        _move_left()
    elif Input.is_action_pressed('right'):
        _move_right()

    if is_on_floor():
        if velocity.y > 0:
            velocity.y = 1
        gravity_scale = 1
        if Input.is_action_just_pressed('up'):
            _jump()
            $JumpTimer.start() # to increase gravity_scale
        if _was_airborne:
            _squash()
            _was_airborne = false
    else:
        _apply_gravity(delta)
        _stretch_based_on_velocity()

    _apply_damping()
    move_and_slide(velocity, Vector2(0, -1))

    if not is_on_floor():
        _was_airborne = true

func _move_left():
    velocity.x -= speed

func _move_right():
    velocity.x += speed

func _jump():
    velocity.y = -jump_speed

func _squash():
    $AnimationPlayer.get_animation('Squash').track_set_key_value(0, 0, $Sprite.scale)
    $AnimationPlayer.play('Squash')

func _apply_gravity(delta):
    velocity.y += gravity * delta * gravity_scale

func _stretch_based_on_velocity():
    $Sprite.scale.y = range_lerp(abs(velocity.y), 0, 2000, 1, 1.5)
    $Sprite.position.y = range_lerp(abs(velocity.y), 0, 2000, 0, -25)
    $Sprite.scale.x = 1 / $Sprite.scale.y

func _apply_damping():
    velocity.x *= 1 - damping

func _on_JumpTimer_timeout():
    gravity_scale = 5
answered Jan 8 by Dlean Jeans (3,615 points)
selected Jan 10 by CaueHenrique
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.