Works again.
[uxul-world.git] / animation.lisp
1 ;;; Copyright 2009-2011 Christoph Senjak
2
3 ;; Basic definitions for animations.
4
5 (in-package :uxul-world)
6
7 (defparameter *graphics-table* nil)
8
9 ;; the functions may assume that the contents of a graphics-file -
10 ;; once read - will not change at any time - so it wont reload
11 ;; graphics with an equivalent path any time you load an image.
12
13 (defclass animation (xy-coordinates)
14   (
15 ;;   (images :initarg :images
16 ;;                   :initform (make-array (list 0) :element-type 'sdl:surface)
17 ;;                   :accessor images
18 ;; ;                 :type (simple-array 'sdl:surface (*))
19 ;;                   :documentation "Array with the images")
20    (full-widths :initarg :full-widths
21                 :initform (make-array (list 0))
22                 :accessor full-widths
23                 :documentation "Widths of images")
24    (full-heights :initarg :full-heights
25                 :initform (make-array (list 0))
26                 :accessor full-heights
27                 :documentation "Heights of images")
28    (images :initarg :images
29            :initform (make-array (list 0))
30            :accessor images
31            :documentation "Array of images")
32    (sprite-image-number :initform 0
33                         :initarg :sprite-image-number
34                         :accessor sprite-image-number
35 ;                       :type xy-struct
36                         :documentation "The Element-Number of the
37                        current image. This slot should not be set
38                        directly.")
39    (sprite-delay :initarg :sprite-delay
40                  :initform 0
41                  :accessor sprite-delay
42 ;                :type integer
43                  :documentation "How much frames to overjump on the
44 whole until changing to the next image of the animation.")
45    (already-jumped :initform 0
46                    :initarg :already-jumped
47                    :accessor already-jumped
48 ;                  :type integer
49                    :documentation "How much frames have been already
50    drawn until the last jump? If this equals to <sprite-delay>, the
51    next image is selected. Dont set this variable yourself." )
52    (visible :initarg :visible
53             :initform T
54             :accessor visible
55 ;           :type boolean
56             :documentation "Should this Animation be visible (i.e. be
57             drawn when the draw-method is called)? Anyway, the
58             draw-method will - even if set to false - \"animate\" the
59             animation, i.e. rotate the image currently drawn, if not
60             paused. It simply wont draw the graphics to the
61             screen.")
62    (reference-to-original :initarg :reference-to-original
63                           :accessor reference-to-original
64                           :initform nil
65                           :documentation "DO NOT SET THIS MANUALLY! DO
66 NOT USE IT! This may not stay in later versions of this Program. It
67 will be used to minimize the number of file-accesses for loading
68 animations. For any animation created from a file by the api from
69 below, this will refer to an animation in the *graphics-table*." )))
70
71 (defmethod draw ((obj animation))
72   (when (not (<= (sprite-delay obj) 0)) ;<=, because -a means "paused,
73                                         ;but a is the delay when
74                                         ;playing again", and 0 means
75                                         ;"no playing"
76     (incf (already-jumped obj))
77     (when (= (sprite-delay obj) (already-jumped obj))
78       (setf (already-jumped obj) 0)
79       (setf (sprite-image-number obj) (mod (+ 1 (sprite-image-number obj)) (length (images obj))))))
80   (when (visible obj)
81     (make-quad (elt (images obj) (sprite-image-number obj))
82                (round (x obj))
83                (round (y obj))
84                (elt (full-widths obj) (sprite-image-number obj))
85                (elt (full-heights obj) (sprite-image-number obj)))))
86
87 ;additional methods to make life easier
88 (defmethod pause ((obj animation))
89   "toggle the playing-flag (sgn sprite-delay), see documentation of draw-method."
90   (setf (sprite-delay obj) (- (sprite-delay obj))))
91
92 (defmethod is-paused ((obj animation))
93   "is animation paused?"
94   (< (sprite-delay obj) 0))
95
96 (defmethod is-playing ((obj animation))
97   "is animation playing?"
98   (< 0 (sprite-delay obj)))
99
100 (defmethod ensure-pause ((obj animation))
101   "ensures that the animation is paused if playing, otherwise, nothing is done."
102   (when (is-playing obj) (pause obj)))
103
104 (defmethod ensure-playing ((obj animation))
105   "ensures that the animation is playing if paused, otherwise, nothing is done."
106   (when (is-paused obj) (pause obj)))
107
108 (defmethod rewind ((obj animation))
109   "rewind the animation"
110   (setf (slot-value obj 'sprite-image-number) 0))
111
112 (defun make-animation (frame-skip &rest image-list)
113   "Create an animation from the list of animation-names given in the
114 images-variable."
115   ;(format t "make-animation is being called~%")
116   (make-instance 'animation
117                  :full-widths (mapcar #'car image-list)
118                  :full-heights (mapcar #'cadr image-list)
119                  :images (mapcar #'cddr image-list)
120                  :sprite-delay frame-skip))