2 Tweens
dxtr edited this page 2026-10-20 10:09:08 +02:00

Tweens

A tween changes values over time, as Godot's Tween does: a spark that grows and fades, a menu that slides in, a camera's zoom eased to where it is wanted. create-tween makes one of a node, bound to it, and its tweeners run in turn, or side by side with :parallel t. This spark, added to a playing tree, grows and fades over a quarter of a second, then frees itself:

(sc:define-node spark (s2d:node-2d)
  ((color :initarg :color :initform '(1 0.9 0.3 1) :type p2d:color :accessor spark-color
          :property t)))

(defmethod (setf spark-color) :after (color (spark spark))
  (declare (ignore color))
  (s2d:queue-redraw spark))

(defmethod s2d:draw ((spark spark) canvas)
  (p2d:fill-circle canvas 0 0 6 (spark-color spark)))

(defmethod sc:ready ((spark spark))
  (let ((tween (sc:create-tween spark)))
    (sc:tween-property tween spark :scale (gm:make-dvec2 :x 2 :y 2) 0.25
                       :transition :quad :ease :out)
    (sc:tween-property tween spark '(:color :a) 0.0 0.25 :parallel t)
    (sc:connect tween 'sc:finished spark 'sc:queue-free)))

Halfway, its scale is 1.75 and its colour's alpha 0.5.

  • Making one: (create-tween node) binds the tween to the node, which must be in a tree: it waits while the node is out of the tree or does not behave, as while its tree is edited, and goes once the node is freed. (create-tween tree) makes one bound to no node. The tree steps its tweens from its next frame, after each frame's process, or with (setf (tween-process-mode tween) :physics) after each physics step, and lets one go once it finishes or is killed. Append the tweeners as the tween is made: nothing is appended once it has started.
  • Tweeners: tween-property changes a property of an object, a node, a resource or another object with properties, to a value over some seconds; tween-interval waits; tween-callback calls a function; tween-method calls a function with a value changing over time, for what is no property; and tween-subtween runs another tween of the tree as one step. Each runs after the one before, or beside it with :parallel t; (setf (tween-parallel tween) t) makes that the default, and :parallel nil runs one after.
  • Properties are named by their symbol, or by any symbol of their name, as :scale, or with a component, as (:color :a) or (:position :x). A property tweener changes from the value the property has as it begins, or from :from, or with :from-current t from the value it had as the tween was made; :relative t adds the value given to where it begins; :delay waits first; and :interpolator, a function, maps the eased weight to the one used, as Godot's custom interpolators do. A value the property does not take, as an alpha beyond 1 where a transition overshoots, stops at the end it overshot.
  • Easing: :transition is one of Godot's twelve, :linear, :sine, :quad, :cubic, :quart, :quint, :expo, :circ, :elastic, :bounce, :back and :spring, and :ease one of :in, :out, :in-out and :out-in. tween-transition and tween-ease are a tween's defaults, :linear and :in-out to begin with. ease-weight gives how far along an eased change is, and interpolate-value a value along one, for a game that eases values itself.
  • Running: tween-loops, 1 by default, runs the steps that many times, or with no end for 0; tween-speed-scale runs faster or slower; pause-tween and play-tween pause and resume; stop-tween takes it back to its start; kill-tween ends it for good; and step-tween advances it by hand. A tween emits step-finished, loop-finished and finished, and each tweener finished, as signals.
  • Values: reals, integers rounded; cl-gmath's vectors and other vectors, component by component; lists of reals as colours, as floats; strings, by how much of them shows; and symbols, switching halfway. Methods of interpolate and add-value tween a game's own kinds of values. A component blends in its own float format, as a 2D node's position's x as a double-float. Stepping allocates nothing for single-float and integer properties, for vectors a property copies, as a 2D node's position, for a 2D node's position and scale components and its rotation, and for a property whose class gives the vector or cell of floats it is kept in with property-place, as a double-float kept in a cell (see Resources): the tween changes it there and calls property-place-changed, where the class does what setting the property does. Another double-float property is set with a new double-float each step, as Lisp passes one, and a list's values are made anew each step.
  • Errors: an error in what a tween does, a callback, a method, or setting a property, stops its bound node, as an error in a callback does, with node-stopped; a tween bound to no node warns with tween-failed. Either way the tween is killed and the tree goes on. A tween with no end whose steps take no time is stopped, as Godot stops one.