git.fiddlerwoaroof.com
bodge-like.lisp
4d63beae
 (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))))