main.gd 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. extends Node
  2. @onready var icon: Sprite2D = %Icon
  3. @onready var icon_start_position = icon.position
  4. @onready var countdown_label = %CountdownLabel
  5. @onready var path: Path2D = $Path2D
  6. @onready var progress = %Progress
  7. var tween: Tween
  8. var sub_tween: Tween
  9. func start_animation():
  10. # Reset the icon to original state.
  11. reset()
  12. # Create the Tween. Also sets the initial animation speed.
  13. # All methods that modify Tween will return the Tween, so you can chain them.
  14. tween = create_tween().set_speed_scale(%SpeedSlider.value)
  15. # Sets the amount of loops. 1 loop = 1 animation cycle, so e.g. 2 loops will play animation twice.
  16. if %Infinite.button_pressed:
  17. tween.set_loops() # Called without arguments, the Tween will loop infinitely.
  18. else:
  19. tween.set_loops(%Loops.value)
  20. # Step 1
  21. if is_step_enabled("MoveTo", 1.0):
  22. # tween_*() methods return a Tweener object. Its methods can also be chained, but
  23. # it's stored in a variable here for readability (chained lines tend to be long).
  24. # Note the usage of ^"NodePath". A regular "String" is accepted too, but it's very slightly slower.
  25. var tweener = tween.tween_property(icon, ^"position", Vector2(400, 250), 1.0)
  26. tweener.set_ease(%Ease1.selected)
  27. tweener.set_trans(%Trans1.selected)
  28. # Step 2
  29. if is_step_enabled("ColorRed", 1.0):
  30. tween.tween_property(icon, ^"self_modulate", Color.RED, 1.0)
  31. # Step 3
  32. if is_step_enabled("MoveRight", 1.0):
  33. # as_relative() makes the value relative, so in this case it moves the icon
  34. # 200 pixels from the previous position.
  35. var tweener = tween.tween_property(icon, ^"position:x", 200.0, 1.0).as_relative()
  36. tweener.set_ease(%Ease3.selected)
  37. tweener.set_trans(%Trans3.selected)
  38. if is_step_enabled("Roll", 0.0):
  39. # parallel() makes the Tweener run in parallel to the previous one.
  40. var tweener = tween.parallel().tween_property(icon, ^"rotation", TAU, 1.0)
  41. tweener.set_ease(%Ease3.selected)
  42. tweener.set_trans(%Trans3.selected)
  43. # Step 4
  44. if is_step_enabled("MoveLeft", 1.0):
  45. tween.tween_property(icon, ^"position", Vector2.LEFT * 200, 1.0).as_relative()
  46. if is_step_enabled("Jump", 0.0):
  47. # Jump has 2 substeps, so to make it properly parallel, it can be done in a sub-Tween.
  48. # Here we are calling a lambda method that creates a sub-Tween.
  49. # Any number of Tweens can animate a single object in the same time.
  50. tween.parallel().tween_callback(func():
  51. # Note that transition is set on Tween, but ease is set on Tweener.
  52. # Values set on Tween will affect all Tweeners (as defaults) and values
  53. # on Tweeners can override them.
  54. sub_tween = create_tween().set_speed_scale(%SpeedSlider.value).set_trans(Tween.TRANS_SINE)
  55. sub_tween.tween_property(icon, ^"position:y", -150.0, 0.5).as_relative().set_ease(Tween.EASE_OUT)
  56. sub_tween.tween_property(icon, ^"position:y", 150.0, 0.5).as_relative().set_ease(Tween.EASE_IN)
  57. )
  58. # Step 5
  59. if is_step_enabled("Blink", 2.0):
  60. # Loops are handy when creating some animations.
  61. for i in 10:
  62. tween.tween_callback(icon.hide).set_delay(0.1)
  63. tween.tween_callback(icon.show).set_delay(0.1)
  64. # Step 6
  65. if is_step_enabled("Teleport", 0.5):
  66. # Tweening a value with 0 duration makes it change instantly.
  67. tween.tween_property(icon, ^"position", Vector2(325, 325), 0)
  68. tween.tween_interval(0.5)
  69. # Binds can be used for advanced callbacks.
  70. tween.tween_callback(icon.set_position.bind(Vector2(680, 215)))
  71. # Step 7
  72. if is_step_enabled("Curve", 3.5):
  73. # Method tweening is useful for animating values that can't be directly interpolated.
  74. # It can be used for remapping and some very advanced animations.
  75. # Here it's used for moving sprite along a path, using inline lambda function.
  76. var tweener = tween.tween_method(func(v): icon.position = path.position + path.curve.sample_baked(v),
  77. 0.0, path.curve.get_baked_length(), 3.0).set_delay(0.5)
  78. tweener.set_ease(%Ease7.selected)
  79. tweener.set_trans(%Trans7.selected)
  80. # Step 8
  81. if is_step_enabled("Wait", 2.0):
  82. # ...
  83. tween.tween_interval(2)
  84. # Step 9
  85. if is_step_enabled("Countdown", 3.0):
  86. tween.tween_callback(countdown_label.show)
  87. tween.tween_method(do_countdown, 4, 1, 3)
  88. tween.tween_callback(countdown_label.hide)
  89. # Step 10
  90. if is_step_enabled("Enlarge", 0.0):
  91. tween.tween_property(icon, ^"scale", Vector2.ONE * 5, 0.5).set_trans(Tween.TRANS_ELASTIC).set_ease(Tween.EASE_OUT)
  92. if is_step_enabled("Vanish", 1.0):
  93. tween.parallel().tween_property(icon, ^"self_modulate:a", 0.0, 1.0)
  94. if %Loops.value > 1 or %Infinite.button_pressed:
  95. tween.tween_callback(icon.show)
  96. tween.tween_callback(icon.set_self_modulate.bind(Color.WHITE))
  97. # RESET step
  98. if %Reset.button_pressed:
  99. tween.tween_callback(reset.bind(true))
  100. func do_countdown(v):
  101. countdown_label.text = str(v)
  102. func reset(soft := false):
  103. icon.position = icon_start_position
  104. icon.self_modulate = Color.WHITE
  105. icon.rotation = 0
  106. icon.scale = Vector2.ONE
  107. icon.show()
  108. countdown_label.hide()
  109. if soft:
  110. # Only reset properties.
  111. return
  112. if tween:
  113. tween.kill()
  114. tween = null
  115. if sub_tween:
  116. sub_tween.kill()
  117. sub_tween = null
  118. progress.max_value = 0
  119. func is_step_enabled(step, expected_time):
  120. var enabled = get_node("%" + step).button_pressed
  121. if enabled:
  122. progress.max_value += expected_time
  123. return enabled
  124. func pause_resume() -> void:
  125. if tween and tween.is_valid():
  126. if tween.is_running():
  127. tween.pause()
  128. else:
  129. tween.play()
  130. if sub_tween and sub_tween.is_valid():
  131. if sub_tween.is_running():
  132. sub_tween.pause()
  133. else:
  134. sub_tween.play()
  135. func kill_tween() -> void:
  136. if tween:
  137. tween.kill()
  138. if sub_tween:
  139. sub_tween.kill()
  140. func speed_changed(value: float) -> void:
  141. if tween:
  142. tween.set_speed_scale(value)
  143. if sub_tween:
  144. sub_tween.set_speed_scale(value)
  145. %SpeedLabel.text = str("x", value)
  146. func inifnite_toggled(button_pressed: bool) -> void:
  147. %Loops.editable = not button_pressed
  148. func _process(delta: float) -> void:
  149. if not tween or not tween.is_running():
  150. return
  151. progress.value = tween.get_total_elapsed_time()