~octaspire/crates2

48af8d424fb40d543461afd530ba80fa8fc90092 — octaspire 10 months ago 0f7e2b5
Add initial block timer
6 files changed, 90 insertions(+), 11 deletions(-)

M crates2.asd
M doc/TODO.org
A src/block-timer.lisp
M src/classes.lisp
M src/level.lisp
M src/levels.lisp
M crates2.asd => crates2.asd +1 -0
@@ 27,6 27,7 @@
                 (:file "player")
                 (:file "slopes")
                 (:file "turnstiles")
                 (:file "block-timer")
                 (:file "vacuum")
                 (:file "level")
                 (:file "textual")

M doc/TODO.org => doc/TODO.org +3 -1
@@ 1,1 1,3 @@
Empty.
- Remove the lamented slot from the crate class and use only the
  lamented state to represent removed crates. Now information is
  stored in two places.

A src/block-timer.lisp => src/block-timer.lisp +49 -0
@@ 0,0 1,49 @@
;; Octaspire Crates 2 - Puzzle Game
;; Copyright 2020 octaspire.com
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
(in-package :crates2)

;; Methods

(defmethod update ((self block-timer))
  (ecase (block-timer-state self)
    (:idle nil)
    (:active
     (incf (block-timer-uptime self) 0.5)
     (when (<= (time-left self) 0)
       (lament self)))
    (:lamented nil))
  (call-next-method))

(defmethod time-left ((self block-timer))
  (ceiling (- (block-timer-time self)
              (block-timer-uptime self))))

(defmethod lament ((self block-timer))
  (setf (block-timer-state self) :lamented)
  (setf (lamented self) t))

(defmethod visual ((self block-timer))
  (let ((durstr (if (block-timer-durable self) "D" "|"))
        (statstr (if (eq (block-timer-state self) :idle) "|" "X"))
        (timestr (format nil "~2,'0d" (time-left self))))
    (format nil "BT~A~A~A" durstr statstr timestr)))

(defmethod collide ((self block-timer) (target moving))
  (ecase (block-timer-state self)
    (:idle (setf (block-timer-state self) :active))
    (:active (unless (block-timer-durable self)
               (lament self)))
    (:lamented nil)))


M src/classes.lisp => src/classes.lisp +28 -4
@@ 14,6 14,8 @@
;; limitations under the License.
(in-package :crates2)

;; Classes

(defclass crate ()
  ((x :initarg :x
      :initform 0


@@ 24,6 26,9 @@
   (z :initarg :z
      :initform 0
      :accessor crate-z)
   (lamented :initarg lamented
             :initform nil
             :accessor lamented)
   (visible :initarg :visible
            :accessor crate-visible)
   (state :initarg :state


@@ 36,10 41,7 @@
             :accessor velocity)
   (active :initarg :active
           :initform t
           :accessor active)
   (lamented :initarg lamented
             :initform nil
             :accessor lamented)))
           :accessor active)))

(defclass wall (crate)
  ())


@@ 83,6 85,20 @@
(defclass turnstile-s (turnstile-s1)
  ())

(defclass block-timer (crate)
  ((state :initarg :state
          :initform :idle
          :accessor block-timer-state)
   (time :initarg :time
         :accessor block-timer-time
         :initform 10)
   (uptime :initarg :time
           :accessor block-timer-uptime
           :initform 0)
   (durable :initarg :durable
           :accessor block-timer-durable
           :initform t)))

(defclass exit (crate)
  ((activated :initarg :activated
              :accessor exit-activated


@@ 99,3 115,11 @@
  ((full :initarg :full
         :accessor full
         :initform nil)))

;; Generic functions

(defgeneric time-left (self)
  (:documentation "Calculate time left in crate SELF") )

(defgeneric lament (self)
  (:documentation "Make crate SELF lamented") )

M src/level.lisp => src/level.lisp +2 -3
@@ 34,6 34,5 @@
(defun purge-lamented ()
  (setf *level* (remove-if #'(lambda (crate)
                               (let ((type (type-of crate)))
                                 (and (subtypep type 'moving)
                                      (not (eq type 'player))
                                      (lamented crate)))) *level*)))
                                 (unless (eq type 'player)
                                   (lamented crate)))) *level*)))

M src/levels.lisp => src/levels.lisp +7 -3
@@ 14,11 14,11 @@
;; limitations under the License.
(in-package :crates2)

(defparameter *num-levels* 10)
(defparameter *num-levels* 11)

(defun load-level (index)
  (ecase index
        (0 (list (list nil nil nil :east nil nil nil :east)
    (0 (list (list nil nil nil :east nil nil nil :east)
             (list (make-instance 'exit        :x 6 :y 3 :z 0)
                   (make-instance 'turnstile-e :x 3 :y 3 :z 0)
                   (make-instance 'player      :x 1 :y 3 :z 0))))


@@ 60,5 60,9 @@
    (9 (list (list :west nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
             (list (make-instance 'exit :x 1 :y 2 :z 0)
                   (make-instance 'vacuum :x 3 :y 2 :z -1)
                   (make-instance 'player :x 5 :y 2 :z 0))))))
                   (make-instance 'player :x 5 :y 2 :z 0))))
    (10 (list (list nil nil nil nil :west nil nil nil nil :west nil nil nil nil)
              (list (make-instance 'exit        :x 1 :y 3 :z 0)
                    (make-instance 'block-timer :x 4 :y 3 :z 0)
                    (make-instance 'player      :x 8 :y 3 :z 0))))))