M fairy.lisp => fairy.lisp +11 -0
@@ 2,6 2,7 @@
(:use :cl)
(:export draw
defdraw
+ update
element
origin
scale
@@ 21,6 22,8 @@
(defgeneric draw (element)
(:documentation "Draw the element on the screen"))
+(defgeneric update (element dt)
+ (:documentation "Update the element after ~dt~ ms."))
(defclass element ()
((origin :initarg :origin
@@ 33,6 36,9 @@
:initform t
:accessor visible)))
+(defmethod update ((el element) dt)
+ ())
+
(defmacro defdraw ((el class) &rest body)
`(defmethod draw ((,el ,class))
(with-slots (origin scale visible) ,el
@@ 95,6 101,11 @@
(cdr (assoc key (children el))))
value))
+(defmethod update ((el layer) dt)
+ (dolist (e (children el))
+ (update (cdr e) dt))
+ (call-next-method))
+
(defmethod delete-child ((el layer) child)
(setf (children el) (remove child (children el) :key #'cdr)))
M tiled.lisp => tiled.lisp +34 -3
@@ 1,6 1,9 @@
(defpackage :fairy/tiled
(:use :cl)
- (:export tile))
+ (:export tile
+ current
+ start-frame-animation
+ stop-frame-animation))
(cl:in-package :fairy/tiled)
@@ 11,10 14,29 @@
:writer (setf change-tileset))
(current :initarg :current
:initform 0
- :accessor :current)
+ :accessor current)
+ (frames :initform nil
+ :accessor frames)
+ (animation-period :initform 0
+ :accessor animation-period)
+ (animation-started-since :initform 0
+ :accessor animation-started-since)
(get-resource :initarg :get-resource
:initform 'alexandria:make-keyword
- :reader :get-resource)))
+ :reader get-resource)))
+
+(defmethod start-frame-animation ((el tile) seq period)
+ (when (car seq)
+ (setf (frames el) seq)
+ (setf (animation-period el) period)
+ (setf (animation-started-since el) 0)
+ (setf (current el) (car seq))))
+
+(defmethod stop-frame-animation ((el tile) new-current)
+ (setf (frames el) nil)
+ (setf (animation-period el) 0)
+ (setf (animation-started-since el) 0)
+ (setf (current el) new-current))
(defmethod initialize-instance :after ((el tile) &key)
(let ((tileset (cl-tiled:load-tileset (tileset el))))
@@ 44,3 66,12 @@
(* line tile-height))
:width tile-width
:height tile-height))))
+
+(defmethod fairy:update ((el tile) dt)
+ (with-slots (animation-period frames animation-started-since) el
+ (when frames
+ (let* ((time (+ (animation-started-since el) dt))
+ (frame-duration (/ animation-period (length frames)))
+ (new-current (mod (truncate time frame-duration) (length frames))))
+ (setf (current el) (nth new-current frames))
+ (setf (animation-started-since el) time)))))