mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-06 16:00:08 +01:00
This leads to code that is easier to understand and runs faster thanks to GDScript's typed instructions. The untyped declaration warning is now enabled on all projects where type hints were added. All projects currently run without any untyped declration warnings. Dodge the Creeps and Squash the Creeps demos intentionally don't use type hints to match the documentation, where type hints haven't been adopted yet (given its beginner focus).
206 lines
6.0 KiB
GDScript
206 lines
6.0 KiB
GDScript
extends Node
|
|
|
|
var tween: Tween
|
|
var sub_tween: Tween
|
|
|
|
@onready var icon: Sprite2D = %Icon
|
|
@onready var icon_start_position := icon.position
|
|
|
|
@onready var countdown_label: Label = %CountdownLabel
|
|
@onready var path: Path2D = $Path2D
|
|
@onready var progress: TextureProgressBar = %Progress
|
|
|
|
func _process(_delta: float) -> void:
|
|
if not tween or not tween.is_running():
|
|
return
|
|
|
|
progress.value = tween.get_total_elapsed_time()
|
|
|
|
|
|
func start_animation() -> void:
|
|
# Reset the icon to original state.
|
|
reset()
|
|
# Create the Tween. Also sets the initial animation speed.
|
|
# All methods that modify Tween will return the Tween, so you can chain them.
|
|
tween = create_tween().set_speed_scale(%SpeedSlider.value)
|
|
|
|
# Sets the amount of loops. 1 loop = 1 animation cycle, so e.g. 2 loops will play animation twice.
|
|
if %Infinite.button_pressed:
|
|
tween.set_loops() # Called without arguments, the Tween will loop infinitely.
|
|
else:
|
|
tween.set_loops(%Loops.value)
|
|
|
|
# Step 1
|
|
|
|
if is_step_enabled("MoveTo", 1.0):
|
|
# tween_*() methods return a Tweener object. Its methods can also be chained, but
|
|
# it's stored in a variable here for readability (chained lines tend to be long).
|
|
# Note the usage of ^"NodePath". A regular "String" is accepted too, but it's very slightly slower.
|
|
var tweener := tween.tween_property(icon, ^"position", Vector2(400, 250), 1.0)
|
|
tweener.set_ease(%Ease1.selected)
|
|
tweener.set_trans(%Trans1.selected)
|
|
|
|
# Step 2
|
|
|
|
if is_step_enabled("ColorRed", 1.0):
|
|
tween.tween_property(icon, ^"self_modulate", Color.RED, 1.0)
|
|
|
|
# Step 3
|
|
|
|
if is_step_enabled("MoveRight", 1.0):
|
|
# as_relative() makes the value relative, so in this case it moves the icon
|
|
# 200 pixels from the previous position.
|
|
var tweener := tween.tween_property(icon, ^"position:x", 200.0, 1.0).as_relative()
|
|
tweener.set_ease(%Ease3.selected)
|
|
tweener.set_trans(%Trans3.selected)
|
|
if is_step_enabled("Roll", 0.0):
|
|
# parallel() makes the Tweener run in parallel to the previous one.
|
|
var tweener := tween.parallel().tween_property(icon, ^"rotation", TAU, 1.0)
|
|
tweener.set_ease(%Ease3.selected)
|
|
tweener.set_trans(%Trans3.selected)
|
|
|
|
# Step 4
|
|
|
|
if is_step_enabled("MoveLeft", 1.0):
|
|
tween.tween_property(icon, ^"position", Vector2.LEFT * 200, 1.0).as_relative()
|
|
if is_step_enabled("Jump", 0.0):
|
|
# Jump has 2 substeps, so to make it properly parallel, it can be done in a sub-Tween.
|
|
# Here we are calling a lambda method that creates a sub-Tween.
|
|
# Any number of Tweens can animate a single object in the same time.
|
|
tween.parallel().tween_callback(func():
|
|
# Note that transition is set on Tween, but ease is set on Tweener.
|
|
# Values set on Tween will affect all Tweeners (as defaults) and values
|
|
# on Tweeners can override them.
|
|
sub_tween = create_tween().set_speed_scale(%SpeedSlider.value).set_trans(Tween.TRANS_SINE)
|
|
sub_tween.tween_property(icon, ^"position:y", -150.0, 0.5).as_relative().set_ease(Tween.EASE_OUT)
|
|
sub_tween.tween_property(icon, ^"position:y", 150.0, 0.5).as_relative().set_ease(Tween.EASE_IN)
|
|
)
|
|
|
|
# Step 5
|
|
|
|
if is_step_enabled("Blink", 2.0):
|
|
# Loops are handy when creating some animations.
|
|
for i in 10:
|
|
tween.tween_callback(icon.hide).set_delay(0.1)
|
|
tween.tween_callback(icon.show).set_delay(0.1)
|
|
|
|
# Step 6
|
|
|
|
if is_step_enabled("Teleport", 0.5):
|
|
# Tweening a value with 0 duration makes it change instantly.
|
|
tween.tween_property(icon, ^"position", Vector2(325, 325), 0)
|
|
tween.tween_interval(0.5)
|
|
# Binds can be used for advanced callbacks.
|
|
tween.tween_callback(icon.set_position.bind(Vector2(680, 215)))
|
|
|
|
# Step 7
|
|
|
|
if is_step_enabled("Curve", 3.5):
|
|
# Method tweening is useful for animating values that can't be directly interpolated.
|
|
# It can be used for remapping and some very advanced animations.
|
|
# Here it's used for moving sprite along a path, using inline lambda function.
|
|
var tweener := tween.tween_method(
|
|
func(v: float) -> void:
|
|
icon.position = path.position + path.curve.sample_baked(v), 0.0, path.curve.get_baked_length(), 3.0
|
|
).set_delay(0.5)
|
|
tweener.set_ease(%Ease7.selected)
|
|
tweener.set_trans(%Trans7.selected)
|
|
|
|
# Step 8
|
|
|
|
if is_step_enabled("Wait", 2.0):
|
|
# ...
|
|
tween.tween_interval(2)
|
|
|
|
# Step 9
|
|
|
|
if is_step_enabled("Countdown", 3.0):
|
|
tween.tween_callback(countdown_label.show)
|
|
tween.tween_method(do_countdown, 4, 1, 3)
|
|
tween.tween_callback(countdown_label.hide)
|
|
|
|
# Step 10
|
|
|
|
if is_step_enabled("Enlarge", 0.0):
|
|
tween.tween_property(icon, ^"scale", Vector2.ONE * 5, 0.5).set_trans(Tween.TRANS_ELASTIC).set_ease(Tween.EASE_OUT)
|
|
if is_step_enabled("Vanish", 1.0):
|
|
tween.parallel().tween_property(icon, ^"self_modulate:a", 0.0, 1.0)
|
|
|
|
if %Loops.value > 1 or %Infinite.button_pressed:
|
|
tween.tween_callback(icon.show)
|
|
tween.tween_callback(icon.set_self_modulate.bind(Color.WHITE))
|
|
|
|
# RESET step
|
|
|
|
if %Reset.button_pressed:
|
|
tween.tween_callback(reset.bind(true))
|
|
|
|
|
|
func do_countdown(number: int) -> void:
|
|
countdown_label.text = str(number)
|
|
|
|
|
|
func reset(soft: bool = false) -> void:
|
|
icon.position = icon_start_position
|
|
icon.self_modulate = Color.WHITE
|
|
icon.rotation = 0
|
|
icon.scale = Vector2.ONE
|
|
icon.show()
|
|
countdown_label.hide()
|
|
|
|
if soft:
|
|
# Only reset properties.
|
|
return
|
|
|
|
if tween:
|
|
tween.kill()
|
|
tween = null
|
|
|
|
if sub_tween:
|
|
sub_tween.kill()
|
|
sub_tween = null
|
|
|
|
progress.max_value = 0
|
|
|
|
|
|
func is_step_enabled(step: String, expected_time: float) -> bool:
|
|
var enabled: bool = get_node("%" + step).button_pressed
|
|
if enabled:
|
|
progress.max_value += expected_time
|
|
|
|
return enabled
|
|
|
|
|
|
func pause_resume() -> void:
|
|
if tween and tween.is_valid():
|
|
if tween.is_running():
|
|
tween.pause()
|
|
else:
|
|
tween.play()
|
|
|
|
if sub_tween and sub_tween.is_valid():
|
|
if sub_tween.is_running():
|
|
sub_tween.pause()
|
|
else:
|
|
sub_tween.play()
|
|
|
|
|
|
func kill_tween() -> void:
|
|
if tween:
|
|
tween.kill()
|
|
if sub_tween:
|
|
sub_tween.kill()
|
|
|
|
|
|
func speed_changed(value: float) -> void:
|
|
if tween:
|
|
tween.set_speed_scale(value)
|
|
if sub_tween:
|
|
sub_tween.set_speed_scale(value)
|
|
|
|
%SpeedLabel.text = str("x", value)
|
|
|
|
|
|
func infinite_toggled(button_pressed: bool) -> void:
|
|
%Loops.editable = not button_pressed
|