summaryrefslogtreecommitdiff
path: root/2d/animation.scm
diff options
context:
space:
mode:
Diffstat (limited to '2d/animation.scm')
-rw-r--r--2d/animation.scm129
1 files changed, 70 insertions, 59 deletions
diff --git a/2d/animation.scm b/2d/animation.scm
index fad4828..2c9e9f0 100644
--- a/2d/animation.scm
+++ b/2d/animation.scm
@@ -32,80 +32,91 @@
;; The <animation> type represents a vector of textures or texture
;; regions that are to be played in sequence and possibly looped.
(define-record-type <animation>
- (make-animation frames duration loop)
+ (make-animation frames frame-duration loop)
animation?
(frames animation-frames)
- (duration animation-duration)
+ (frame-duration animation-frame-duration)
(loop animation-loop?))
(define (animation-frame animation index)
- "Returns the frame for the given index."
+ "Return the texture for the given frame INDEX."
(vector-ref (animation-frames animation) index))
(define (animation-length animation)
- "Returns the number of frames in the animation"
+ "Return the number of frames in the ANIMATION."
(vector-length (animation-frames animation)))
+(define (animation-duration animation)
+ "Return the total duration of ANIMATION in ticks."
+ (* (animation-length animation)
+ (animation-frame-duration animation)))
+
(export make-animation
animation?
animation-frames
- animation-duration
+ animation-frame-duration
animation-loop?
animation-frame
- animation-length)
+ animation-length
+ animation-duration)
-;; The <animation-state> type encapsulates the state for playing an
+;; The <animator> type encapsulates the state for playing an
;; animation.
-(define-record-type <animation-state>
- (%make-animation-state animation frame-index frame-time playing)
- animation-state?
- (animation animation-state-animation)
- (frame-index animation-state-frame-index)
- (frame-time animation-state-frame-time)
- (playing animation-state-playing?))
-
-(define (make-animation-state animation)
+(define-record-type <animator>
+ (%make-animator animation frame time)
+ animator?
+ (animation animator-animation)
+ (frame animator-frame set-animator-frame!)
+ (time animator-time set-animator-time!))
+
+(define (make-animator animation)
"Creates a new animation state object."
- (%make-animation-state animation 0 0 #t))
-
-(define (tick-animation-state state)
- "Increments the frame time for the animation state and determines
-which frame to show. Returns a new animation state object when the
-animation is playing. Otherwise the state passed in is returned."
- (let ((frame-time (1+ (animation-state-frame-time state)))
- (frame-index (animation-state-frame-index state))
- (playing (animation-state-playing? state))
- (animation (animation-state-animation state)))
-
- ;; Return the same state object if the animation is not playing.
- (cond ((not playing)
- state)
- ;; Return a new state object with a reset frame-index and
- ;; frame-time if we've reached the end of the animation.
- ;; Stops playing the animation if the animation does not
- ;; loop.
- ((and playing (= frame-time (animation-duration animation)))
- (let* ((frame-index (modulo (1+ frame-index)
- (animation-length animation)))
- (frame-time 0)
- (playing (or (not (= frame-index 0))
- (animation-loop? animation))))
- (%make-animation-state animation frame-index frame-time playing)))
- ;; Return a new state object with an incremented frame index.
- (else
- (%make-animation-state animation frame-index frame-time playing)))))
-
-(define (animation-state-frame state)
- "Returns the texture or texture region for the state's animation at
-the current frame index."
- (animation-frame (animation-state-animation state)
- (animation-state-frame-index state)))
-
-(export make-animation-state
- animation-state?
- animation-state-animation
- animation-state-frame-index
- animation-state-frame-time
- animation-state-playing?
- animation-state-frame
- tick-animation-state)
+ (%make-animator animation 0 0))
+
+(define (animator-frame-complete? state)
+ (>= (animator-time state)
+ (animation-frame-duration (animator-animation state))))
+
+(define (animator-playing? state)
+ "Return true if animation STATE is not done playing the
+animation. This will always return #t if the animation loops."
+ (not (= (animator-frame state) -1)))
+
+(define (animator-next-frame state)
+ "Return the next frame index for the animation STATE. Return -1 when
+the animation is complete."
+ (let ((frame (1+ (animator-frame state)))
+ (animation (animator-animation state)))
+ (cond ((< frame (animation-length animation)) frame)
+ ((animation-loop? animation) 0)
+ (else -1))))
+
+(define (animator-texture state)
+ "Returns the texture for the animation at the current frame index."
+ (animation-frame (animator-animation state)
+ (animator-frame state)))
+
+(define (animator-next! state)
+ "Advance to the next animation frame for the given animation STATE."
+ (set-animator-time! state 0)
+ (set-animator-frame! state (animator-next-frame state)))
+
+(define (animator-update! state)
+ "Increments the frame time for the animation STATE and advances to
+the next frame in the animation if necessary."
+ (when (animator-playing? state)
+ (set-animator-time! state (1+ (animator-time state)))
+ (when (animator-frame-complete? state)
+ (animator-next! state))))
+
+(export make-animator
+ animator?
+ animator-animation
+ animator-frame
+ animator-time
+ animator-frame-complete?
+ animator-playing?
+ animator-next-frame
+ animator-texture
+ animator-next!
+ animator-update!)