aboutsummaryrefslogtreecommitdiff
path: root/animation.scm
blob: 4caf1fe4df38a1f5dfe0a125e9d6515342f5d8bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
(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 (advance-animation entity anim)
    (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)))))

  (define (animate-entity entity animations)
    (let* ((anim-name (entity-ref entity #:anim-name #f))
           (entry     (and anim-name (assq anim-name animations)))
           (anim      (and entry (cdr entry))))
      (if anim
          (advance-animation entity anim)
          entity)))
) ;; End of animation module