git.fiddlerwoaroof.com
Raw Blame History
(defpackage :fwoar.bodge-like
  (:use :cl )
  (:export ))
(in-package :fwoar.bodge-like)

(defclass feature ()
  ((%sym :reader sym :initarg sym)))

(defclass monster (feature)
  ((%position :accessor pos :initform (gamekit:vec2 (random 12)
                                                    (random 12)))))

(defclass dog (monster)
  ()
  (:default-initargs sym "d"))

(defun monster (sym)
  (make-instance 'monster 'sym sym))

(defclass player (feature)
  ((%position :accessor pos :initform (gamekit:vec2 0 0)))
  (:default-initargs sym "@"))

(defparameter *white* (gamekit:vec4 1 1 1 1))
(defparameter *black* (gamekit:vec4 0 0 0 0.8))
(defparameter *tile-size* 32)

(gamekit:defgame bodgelike ()
  ((%player :reader player :initform (make-instance 'player))
   (%monsters :accessor monsters :initform ()))
  (:viewport-title "@")
  (:viewport-height (* 12 *tile-size*))
  (:viewport-width (* 12 *tile-size*)))

(defun draw-tile (row col &optional (size *tile-size*))
  (gamekit:draw-rect (gamekit:vec2 (* row size)
                                   (* col size))
                     size size
                     :fill-paint *black*))

(defvar *my-font*)
(defun draw-feature (feature &optional pos (tile-size *tile-size*))
  (let* ((pos (if pos
                  pos
                  (pos feature)))
         (row (gamekit:x pos))
         (col (gamekit:y pos))
         (tile-origin (gamekit:vec2 (* row tile-size)
                                    (* col tile-size)))
         (feature-text (etypecase feature
                         (string feature)
                         (feature (sym feature)))))
    (multiple-value-bind (text-origin text-width text-height)
        (gamekit:calc-text-bounds feature-text *my-font*)
      (let ((text-origin
              (gamekit:add tile-origin
                           (gamekit:mult -1 text-origin)
                           (gamekit:mult 0.5
                                         (gamekit:subt (gamekit:vec2 tile-size tile-size)
                                                       (gamekit:vec2 text-width text-height))))))
        (gamekit:draw-text feature-text text-origin
                           :fill-color *white*
                           :font *my-font*)))))


(gamekit:define-font :fantasy "/tmp/foo/font.ttf")


(defgeneric interact2 (game obj1 obj2)
  (:method (game obj1 obj2) nil)
  (:method (game obj1 obj2) t)
  (:method (game (obj1 player) (obj2 dog))
    (format t "~&Ruff! ~s~%" (gamekit:subt (pos obj2)
                                           (pos obj1)))
    (setf (pos obj2)
          (gamekit:add (pos obj2)
                       (gamekit:subt (pos obj2)
                                     (pos obj1))))
    nil))

(defun find-in-space (pos obj-list)
  (find pos obj-list 
        :key 'pos 
        :test 'bodge-math:vec=))

(defun update (thing fun &rest args)
  (apply fun thing args))

(define-modify-macro updatef (fun &rest args)
  update)

(defun move-handler (delta)
  (lambda (game player)
    (updatef (pos player)
             (lambda (old-pos)
               (let* ((new-pos (gamekit:add old-pos delta))
                      (feature-in-space (find-in-space new-pos (monsters game))))
                 (if (and feature-in-space (interact2 game player feature-in-space))
                     old-pos
                     new-pos))))) )

(defun move-left (game player)
  (let ((handler (move-handler (gamekit:vec2 -1 0))))
    (lambda ()
      (funcall handler game player))))

(defun move-right (game player)
  (let ((handler (move-handler (gamekit:vec2 1 0)))) 
    (lambda ()
      (funcall handler game player))))

(defun move-up (game player)
  (let ((handler (move-handler (gamekit:vec2 0 1)))) 
    (lambda ()
      (funcall handler game player))))

(defun move-down (game player)
  (let ((handler (move-handler (gamekit:vec2 0 -1)))) 
    (lambda ()
      (funcall handler game player))))


(defmethod gamekit:post-initialize ((game bodgelike))
  (gamekit:bind-button :h :pressed
                       (move-left game (player game)))
  (gamekit:bind-button :j :pressed
                       (move-down game (player game)))
  (gamekit:bind-button :k :pressed
                       (move-up game (player game)))
  (gamekit:bind-button :l :pressed
                       (move-right game (player game))))

(defmethod style )

(defmethod gamekit:draw ((system bodgelike))
  (dotimes (row 16)
    (dotimes (col 16)
      (draw-tile row col)))
  (let ((*my-font* (gamekit:make-font :fantasy (* 0.8 *tile-size*))))
    (mapcar 'draw-feature
            (monsters system))
    (draw-feature (player system))))