aboutsummaryrefslogtreecommitdiff
path: root/animation.scm
diff options
context:
space:
mode:
Diffstat (limited to 'animation.scm')
-rw-r--r--animation.scm55
1 files changed, 55 insertions, 0 deletions
diff --git a/animation.scm b/animation.scm
new file mode 100644
index 0000000..e6627fe
--- /dev/null
+++ b/animation.scm
@@ -0,0 +1,55 @@
+(module downstroke/animation *
+ (import scheme
+ (chicken base)
+ (chicken keyword)
+ downstroke/entity
+ downstroke/world)
+
+ ;; ---- Animation data accessors ----
+
+ (define (animation-frames anim) (get-keyword #:frames anim))
+ (define (animation-duration anim) (get-keyword #:duration anim))
+
+ ;; ---- frame->tile-id ----
+ ;; Given a frames list and frame index, return the tile ID (1-indexed).
+
+ (define (frame->tile-id frames frame-idx)
+ (+ 1 (list-ref frames (modulo frame-idx (length frames)))))
+
+ ;; ---- set-animation ----
+ ;; Switch to a new animation, resetting frame and tick counters.
+ ;; No-op if the animation is already active (avoids restart mid-loop).
+
+ (define (set-animation entity name)
+ (if (eq? (entity-ref entity #:anim-name #f) name)
+ entity
+ (entity-set (entity-set (entity-set entity #:anim-name name)
+ #:anim-frame 0)
+ #:anim-tick 0)))
+
+ ;; ---- animate-entity ----
+ ;; Advance the animation tick/frame counter for one game tick.
+ ;; Pass the animation table for this entity's type.
+ ;; Entities without #:anim-name are returned unchanged.
+
+ (define (animate-entity entity animations)
+ (let ((anim-name (entity-ref entity #:anim-name #f)))
+ (if (not anim-name)
+ entity
+ (let* ((entry (assq anim-name animations))
+ (anim (and entry (cdr entry))))
+ (if (not anim)
+ entity
+ (let* ((tick (+ 1 (entity-ref entity #:anim-tick 0)))
+ (duration (animation-duration anim))
+ (frames (animation-frames anim))
+ (frame (entity-ref entity #:anim-frame 0)))
+ (if (>= tick duration)
+ (let ((new-frame (modulo (+ frame 1) (length frames))))
+ (entity-set (entity-set (entity-set entity
+ #:anim-tick 0)
+ #:anim-frame new-frame)
+ #:tile-id (frame->tile-id frames new-frame)))
+ (entity-set (entity-set entity #:anim-tick tick)
+ #:tile-id (frame->tile-id frames frame)))))))))
+) ;; End of animation module