aboutsummaryrefslogtreecommitdiff
path: root/animation.scm
blob: a1527538c4def5dc2270b5568cd2351d62909a62 (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
(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