(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))))