aboutsummaryrefslogtreecommitdiff
path: root/tests/animation-test.scm
blob: 00dd217cc312e1590da7d321ce9ff39281e92b7d (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
(import test
        (only (list-utils alist) plist->alist))
(include "entity.scm")
(include "tilemap.scm")
(include "world.scm")
(include "animation.scm")
(import (downstroke entity) (downstroke world) (downstroke animation))

;; Test helpers: construct alist entities / animation defs from readable plist kwargs.
(define (entity . kws) (plist->alist kws))
(define (anim . kws) (plist->alist kws))

(test-begin "animation")

(test-group "frame->tile-id"
  (test-group "tile IDs only"
    (test "first frame, frames (0)" 0 (frame->tile-id '(0) 0))
    (test "wraps around" 0 (frame->tile-id '(0 1) 2))
    (test "frame 1 of (27 28)" 28 (frame->tile-id '(27 28) 1)))
  (test-group "tile IDs and durations"
    (test "first frame, frames (0)" 0 (frame->tile-id '((0 10)) 0))
    (test "wraps around" 0 (frame->tile-id '((0 10) (1 10)) 2))
    (test "frame 1 of (27 28)" 28 (frame->tile-id '((27 10) (28 10)) 1))))

(test-group "frame->duration"
  (test "first frame, frames (0)" 100 (frame->duration '((#:frames . ((0 100))))
						       0))
  (test "wraps around" 100 (frame->duration '((#:frames . ((0 100) (1 200))))
					    0))
  (test "frame 1 of (27 28)" 200 (frame->duration '((#:frames . ((27 100) (28 200))))
						  1))
  )

(test-group "set-animation"
  (let ((e (entity #:type 'player #:anim-name 'idle #:anim-frame 5 #:anim-tick 8)))
    (test "no-op if already active" e (set-animation e 'idle))
    (let ((switched (set-animation e 'walk)))
      (test "switches anim-name" 'walk (entity-ref switched #:anim-name))
      (test "resets frame" 0 (entity-ref switched #:anim-frame))
      (test "resets tick" 0 (entity-ref switched #:anim-tick)))))

(test-group "animate-entity"
  (test-group "Single frames"
    (let* ((anims (list (anim #:name 'walk #:frames '(2 3) #:duration 4)))
           (e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 0))
           (stepped (animate-entity e anims 1)))
      (test "increments tick" 1 (entity-ref stepped #:anim-tick))
      (test "sets tile-id on first tick" 2 (entity-ref stepped #:tile-id)))
    (let* ((anims (list (anim #:name 'walk #:frames '(0 1) #:duration 2)))
           (e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 1))
           (advanced (animate-entity e anims 200)))
      (test "advances frame when tick reaches duration" 1 (entity-ref advanced #:anim-frame))
      (test "resets tick on frame advance" 0 (entity-ref advanced #:anim-tick))))
  (test-group "Frames with duration"
    (let* ((anims (list (anim #:name 'walk #:frames '((0 10) (1 20)) #:duration 4)))
           (e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 9))
           (stepped (animate-entity e anims 200)))
      (test "ticks resets on frame switch" 0 (entity-ref stepped #:anim-tick))
      (test "sets tile-id on 10th tick" 1 (entity-ref stepped #:tile-id))
      (test "sets duration to frame duration" 20 (entity-ref stepped #:duration))))
  (test-group "Empty"
    (let* ((e (entity #:type 'player)))
      (test "unchanged entity without anim-name" e (animate-entity e '() 1)))))

(test-group "animation pipeline"
  (test-group "animated entity"
    (let* ((anims (list (anim #:name 'walk #:frames '(2 3) #:duration 4)))
           (e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 0 #:animations anims))
	   (stepped-entity (apply-animation #f e 10)))
      (test "Updated animated entity" 10 (entity-ref stepped-entity #:anim-tick)))
    (let* ((e (entity #:type 'static))
	   (stepped-entity (apply-animation #f e 10)))
      (test "unchanged static entity" #f (entity-ref stepped-entity #:anim-tick)))))

(test-end "animation")
(test-exit)