summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2018-08-28 14:09:51 -0400
committerDavid Thompson <dthompson2@worcester.edu>2018-08-28 18:02:13 -0400
commit84ff75e4dad02f1362425d5208b4c57aa237eb39 (patch)
tree6c057c81aa2ef2716c2dbef570f2186d5cf38d2c
parent8dd4d148bde3a947bd312d5c222f680b16043ef1 (diff)
node-2d: Add tweened animations for position, rotation, and scale.
-rw-r--r--starling/node-2d.scm140
1 files changed, 91 insertions, 49 deletions
diff --git a/starling/node-2d.scm b/starling/node-2d.scm
index 368e8a2..ccbb17b 100644
--- a/starling/node-2d.scm
+++ b/starling/node-2d.scm
@@ -21,6 +21,7 @@
;;; Code:
(define-module (starling node-2d)
+ #:use-module (chickadee math easings)
#:use-module (chickadee math matrix)
#:use-module (chickadee math rect)
#:use-module (chickadee math vector)
@@ -59,13 +60,13 @@
rotation
skew
pivot
- move
+ move-by
move-to
teleport
- rotate
+ rotate-by
rotate-to
- zoom
- zoom-to
+ scale-by
+ scale-to
<sprite>
texture
@@ -232,6 +233,25 @@
(define (dirty! node)
(set! (dirty-matrix? node) #t))
+(define-method (compute-matrices! (node <node-2d>))
+ (let ((local (local-matrix node))
+ (world (world-matrix node)))
+ (matrix4-2d-transform! local
+ #:origin (origin node)
+ #:position (render-position node)
+ #:rotation (rotation node)
+ #:scale (scale node)
+ #:skew (skew node))
+ ;; Compute world matrix by multiplying by the parent node's
+ ;; matrix, if there is a 2D parent node, that is.
+ (if (and (parent node) (is-a? (parent node) <node-2d>))
+ (matrix4-mult! world local (world-matrix (parent node)))
+ (begin
+ (matrix4-identity! world)
+ (matrix4-mult! world world local)))))
+
+;; Animation helpers
+
(define-method (pivot (node <node-2d>) x y)
"Change origin of NODE to (X, Y)."
(let ((o (origin node)))
@@ -239,75 +259,97 @@
(set-vec2-y! o y)
(dirty! node)))
-(define-method (move (node <node-2d>) dx dy)
- "Move NODE by (DX, DY)."
- (let ((p (position node)))
- (set-vec2-x! p (+ (vec2-x p) dx))
- (set-vec2-y! p (+ (vec2-y p) dy))
- (dirty! node)))
-
(define-method (move-to (node <node-2d>) x y)
- "Move NODE to (X, Y)."
(let ((p (position node)))
(set-vec2-x! p x)
(set-vec2-y! p y)
(dirty! node)))
+(define-method (move-to (node <node-2d>) x y duration ease)
+ (let ((p (position node)))
+ (move-by node (- x (vec2-x p)) (- y (vec2-y p)) duration ease)))
+
+(define-method (move-to (node <node-2d>) x y duration)
+ (move-to node x y duration smoothstep))
+
+(define-method (move-by (node <node-2d>) dx dy)
+ (let ((p (position node)))
+ (move-to node (+ (vec2-x p) dx) (+ (vec2-y p) dy))))
+
+(define-method (move-by (node <node-2d>) dx dy duration ease)
+ (let* ((p (position node))
+ (start-x (vec2-x p))
+ (start-y (vec2-y p)))
+ (tween duration 0.0 1.0
+ (lambda (n)
+ (move-to node
+ (+ start-x (* dx n))
+ (+ start-y (* dy n))))
+ #:ease ease)))
+
+(define-method (move-by (node <node-2d>) dx dy duration)
+ (move-by node dx dy duration smoothstep))
+
(define-method (teleport (node <node-2d>) x y)
- "Move NODE to (X, Y) without applying animation smoothing."
(move-to node x y)
(let ((lp (last-position node)))
(set-vec2-x! lp x)
(set-vec2-y! lp y)))
-(define-method (rotate (node <node-2d>) dtheta)
- "Rotate NODE about the Z axis by DTHETA radians."
- (set! (rotation node) (+ (rotation node) dtheta))
- (dirty! node))
-
(define-method (rotate-to (node <node-2d>) theta)
- "Rotate NODE to THETA radians about the Z axis."
(set! (rotation node) theta)
(dirty! node))
-(define-method (zoom (node <node-2d>) dsx dsy)
- "Scale NODE by the scaling factor (DSX, DSY)."
- (let ((s (scale node)))
- (set-vec2-x! s (+ (vec2-x s) dsx))
- (set-vec2-y! s (+ (vec2-y s) dsy))
- (dirty! node)))
+(define-method (rotate-to (node <node-2d>) theta duration ease)
+ (tween duration (rotation node) theta
+ (lambda (r)
+ (rotate-to node r))
+ #:ease ease))
+
+(define-method (rotate-to (node <node-2d>) theta duration)
+ (rotate-to node theta duration smoothstep))
+
+(define-method (rotate-by (node <node-2d>) dtheta)
+ (rotate-to node (+ (rotation node) dtheta)))
+
+(define-method (rotate-by (node <node-2d>) dtheta duration ease)
+ (rotate-to node (+ (rotation node) dtheta) duration ease))
-(define-method (zoom (node <node-2d>) ds)
- "Scale NODE by the scaling factor (DS, DS)."
- (zoom node ds ds))
+(define-method (rotate-by (node <node-2d>) dtheta duration)
+ (rotate-by node dtheta duration smoothstep))
-(define-method (zoom-to (node <node-2d>) sx sy)
- "Set the scaling factor for NODE to (SX, SY)."
+(define-method (scale-to (node <node-2d>) sx sy)
(let ((s (scale node)))
(set-vec2-x! s sx)
(set-vec2-y! s sy)
(dirty! node)))
-(define-method (zoom-to (node <node-2d>) s)
- "Set the scaling factor for node to (S, S)."
- (zoom-to node s s))
+(define-method (scale-to (node <node-2d>) sx sy duration ease)
+ (let ((s (scale node)))
+ (scale-by node (- sx (vec2-x s)) (- sy (vec2-y s)) duration ease)))
-(define-method (compute-matrices! (node <node-2d>))
- (let ((local (local-matrix node))
- (world (world-matrix node)))
- (matrix4-2d-transform! local
- #:origin (origin node)
- #:position (render-position node)
- #:rotation (rotation node)
- #:scale (scale node)
- #:skew (skew node))
- ;; Compute world matrix by multiplying by the parent node's
- ;; matrix, if there is a 2D parent node, that is.
- (if (and (parent node) (is-a? (parent node) <node-2d>))
- (matrix4-mult! world local (world-matrix (parent node)))
- (begin
- (matrix4-identity! world)
- (matrix4-mult! world world local)))))
+(define-method (scale-to (node <node-2d>) sx sy duration)
+ (scale-to node sx sy duration smoothstep))
+
+(define-method (scale-by (node <node-2d>) dsx dsy)
+ (let ((s (scale node)))
+ (scale-to node (+ (vec2-x s) dsx) (+ (vec2-y s) dsy))))
+
+(define-method (scale-by (node <node-2d>) dsx dsy duration ease)
+ (let* ((s (scale node))
+ (start-x (vec2-x s))
+ (start-y (vec2-y s)))
+ (tween duration 0.0 1.0
+ (lambda (n)
+ (scale-to node
+ (+ start-x (* dsx n))
+ (+ start-y (* dsy n))))
+ #:ease ease)))
+
+(define-method (scale-by (node <node-2d>) dsx dsy duration)
+ (scale-by node dsx dsy duration smoothstep))
+
+;; Events
(define-method (update* (node <node-2d>) dt)
(vec2-copy! (position node) (last-position node))