~lthms/fairy.lisp

ffa0db56604a0e706baae4fbf3a731b983116821 — Thomas Letan 6 years ago 7a1807a
feature: It is now possible to add animation (at least to tiles)
2 files changed, 45 insertions(+), 3 deletions(-)

M fairy.lisp
M tiled.lisp
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)))))