Quer fazer animações sem precisar, de fato, implementar um zilhão de linhas de código pra fazer uma animação? Tweens estão aí pra te ajudar, meu caro.
Neste post irei mostrar, através de um básico projeto de plataforma, como Tweens são simples de se usar, e como você pode fazer animações básicas com ele.
Vamos considerar que temos a estrutura de um mapa e de um player movimentável já foi previamente implementado. E o player, para este exemplo, seguirá esta estrutura:
No script do player_CB (Que é um nó do tipo CharacterBody2D), iremos adicionar dois signals. Um para cuidar de quando o player pular, e outro para quando o player pisar no chão.
signal player_jumped
signal player_landed(speed)
A primeira parte é chamar a execução do signal quando estivermos pulando.
func _input(event):
if (event.is_action_pressed("jump")):
if (can_jump):
emit_signal("player_jumped")
A segunda parte é chamar a execução do signal quando for detectado que o player tocou no chão. Aqui iremos passar um valor para o signal que corresponde a aceleração do player naquele momento.
func _physics_process(delta):
current_acc += acc_force
[...]
move_direction = Vector2(0, gravity * delta * current_acc)
verify_collision(move_and_collide(move_direction))
func verify_collision(collision: KinematicCollision2D):
if (collision):
var collider_rid = collision.get_collider_rid()
if collider_rid and PhysicsServer2D.body_get_collision_layer(collider_rid) == 1:
if (not is_on_the_ground):
emit_signal("player_landed", current_acc)
[...]
Esta segunda etapa pode ser resumida da seguinte forma:
- Variável current_acc armazena a aceleração do player. Ela é atualizada dentro de _physics_process().
- Após definir a direção vetorial do player através do move_direction, chamamos uma função verify_collision() para cuidar da lógica de colisão, passando o resultado de move_and_collide().
- Dentro da função verify_collision(), validamos se collision possui um objeto atrelado a ele. A engine detecta se houve uma colisão quando move_and_collide() é chamado, retornando informações do corpo colisor quando houver.
- Com get_collider_rid() nós conseguimos pegar informações mais detalhadas do corpo com quem colidimos. Neste caso, vamos usá-lo para conferir se este corpo faz parte da camada 1 (Verificado na linha PhysicsServer2D.body_get_collision_layer(collider_rid) == 1)
- Se o objeto já não estiver no chão, chamamos o signal player_landed
Agora vamos conectar os signals com o nó sprite. Vamos realizar as animações diretamente nele. (Só se certifique que você já criou um script para ele também).
Para quando o player pular ou aterrissar, teremos o seguinte script:
extends Sprite2D
func _on_player_cb_player_jumped():
var tween = get_tree().create_tween()
tween.tween_property(self, "scale", Vector2(0.6, 1), 0.05)
tween.tween_property(self, "scale", Vector2(1, 1), 0.2)
return
func _on_player_cb_player_landed(speed):
var tween = get_tree().create_tween()
tween.tween_property(self, "scale", Vector2(1 + speed * 0.15, 1), 0.05)
tween.tween_property(self, "scale", Vector2(1, 1), 0.1)
return
- Vamos criar um novo tween. Precisamos neste caso chamar o get_tree() primeiro, para depois chamarmos create_tween().
- Com tween_property(), podemos definir quaisquer informações que sejam relevante para o objeto que está sendo manipulado. Estaremos passando qual o objeto manipulado (self), qual propriedade (scale), qual o novo valor desta propriedade (Vector2) e o tempo de duração da animação (0.05).
“Mas pera lá, eu não vou usar scale no meu game, como eu vou saber no que eu posso ou não mexer?“
Simples. Na aba inspector temos informações sobre o nó. O que está sendo apresentado nessa aba pode ser manipulado. E para saber qual o nome exato da propriedade, botão direito e só selecionar Copy Property Path.
3. Depois voltaremos a propriedade scale para seu valor inicial (Vector2(1, 1))
Apesar do exemplo só mexer com scale, aqui o céu é o limite. Muita coisa pode ser feita com Tweens