Squash and Stretch.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By CaueHenrique

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.

:bust_in_silhouette: Reply From: Dlean Jeans

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

hello can i see your project cus i cant seems to get the same effects as you did probably have to do with the way u animate it in animation player
thanks