Last modified: 2010/05/14 01:58:48

Common LispでSDLを使おう計画
目的
追加設定
SDLを包括するフレームワーク
フレームワークサンプル

Common LispでSDLを使おう計画

目的

lispbuilder-sdlを用いて、携帯アプリのプロトタイプをCommon Lispで作ってみようと思います。

追加設定

追加パッケージ

sudo aptitude install libsdl-ttf-2.0-dev

コンパイル

cd clbuild/source/lispbuilder-sdl-ttf
make
sudo cp build/liblispbuilder-sdl-ttf-glue.so /usr/local/lib/

SDLを包括するフレームワーク

(in-package :com.strnet.game-framework)

(defparameter *image-directory* "/home/kazamai/program/common-lisp/source/practice/")

(defparameter *font-path* "/usr/share/fonts/truetype/sazanami/sazanami-gothic.ttf")
(defparameter *screen-width* 240)
(defparameter *screen-height* 240)
(defparameter *frame-rate* 20)
(defparameter *font-size* 12)
(defparameter *title* "STR Mobile Game")
(defparameter *image-format* "png")
(defparameter *mouse-x* 0)
(defparameter *mouse-y* 0)
(defparameter *mouse-clicked* 0)


(defclass image-define ()
  ((id :initarg :id :initform nil :accessor id)
   (color-key-point :initarg :color-key-point :initform nil :accessor color-key-point)))


(defun get-font ()
  (make-instance 'ttf-font-definition
                 :size *font-size*
                 :filename (create-path *font-path*)))


(defparameter *key-state* nil)

(defun push-key-state (id)
  (pushnew id *key-state*))

(defun pop-key-state (id)
  (setf *key-state* (remove id *key-state*)))

(defun left? ()
  (member :STR_KEY_LEFT *key-state*))

(defun right? ()
  (member :STR_KEY_RIGHT *key-state*))

(defun up? ()
  (member :STR_KEY_UP *key-state*))

(defun down? ()
  (member :STR_KEY_DOWN *key-state*))


(defparameter *key-event* nil)

(defun match-key-event-p (id)
  (eql id *key-event*))

(defun set-key-event (id)
  (setf *key-event* id))

(defun reset-key-event ()
  (setf *key-event* nil))

(defun reset-mouse-event ()
  (setf *mouse-clicked* nil))


(defparameter *images* nil)

(defun load-image-data (img-define)
  (with-slots (id color-key-point) img-define
    (setf (aref *images* id)
          (sdl-image:load-image (create-path (format nil "~d.~(~a~)" id *image-format*) *image-directory*)
                                :color-key-at color-key-point))
    (or (aref *images* id) (error "image load failed. id: ~a" id))))
  
(defun init-images (image-defines)
  (setf *images* (make-array (length image-defines) :initial-element nil))
  (mapcar #'load-image-data image-defines))


(defun draw-image (id x y &key sx sy w h)
  (let ((img (aref *images* id)))
    (if (and sx sy w h)
        (set-cell-* sx sy w h :surface img))
    (draw-surface-at-* img x y)))

(defun draw-string (string x y &key (color *white*))
  (draw-string-solid-* string x y
                       :color color
                       :surface *default-display*))


(defmacro do-mainloop (image-defines &body body)
  `(with-init ()
     (window *screen-width* *screen-height* :title-caption *title*)
     (enable-unicode t)
     (unless (initialise-default-font (get-font))
       (error "Cannot initialize the font."))
    
     (init-images ,image-defines)

     (setf (sdl:frame-rate) *frame-rate*)

     (with-events ()
       (:quit-event () t)
       (:key-down-event (:key key)
                        (if (key= key :SDL-KEY-ESCAPE) (push-quit-event))
                        (if (key= key :SDL-KEY-LEFT) (push-key-state :STR_KEY_LEFT))
                        (if (key= key :SDL-KEY-RIGHT) (push-key-state :STR_KEY_RIGHT))
                        (if (key= key :SDL-KEY-UP) (push-key-state :STR_KEY_UP))
                        (if (key= key :SDL-KEY-DOWN) (push-key-state :STR_KEY_DOWN))
                        (if (key= key :SDL-KEY-Z) (set-key-event :STR_SOFTKEY_1))
                        (if (key= key :SDL-KEY-X) (set-key-event :STR_SOFTKEY_2))
                        (if (key= key :SDL-KEY-RETURN) (set-key-event :STR_FIRE)))
    
       (:key-up-event (:key key)
                      (if (key= key :SDL-KEY-LEFT) (pop-key-state :STR_KEY_LEFT))
                      (if (key= key :SDL-KEY-RIGHT) (pop-key-state :STR_KEY_RIGHT))
                      (if (key= key :SDL-KEY-UP) (pop-key-state :STR_KEY_UP))
                      (if (key= key :SDL-KEY-DOWN) (pop-key-state :STR_KEY_DOWN)))

       (:mouse-button-down-event (:button button :state state :x mouse-x :y mouse-y)
                                 (when (= 1 state)
                                   (setf *mouse-clicked* button)
                                   (setf *mouse-x* mouse-x)
                                   (setf *mouse-y* mouse-y)))
                                  
                   
       (:video-expose-event () (update-display))

       (:idle ()
              (fill-surface *black*)
              ,@body
              (update-display)))))

フレームワークサンプル

矢印キーを押すと画像が動くサンプル

(defpackage :com.strnet.mobile-game
  (:use :cl :com.strnet.game-framework)
  (:export :main))

(in-package :com.strnet.mobile-game)

(defparameter *image-defines* nil)
(push (make-instance 'image-define :id 0 :color-key-point #(0 0)) *image-defines*)

(defparameter *x* 0)
(defparameter *y* 0)

(defun main ()
  (do-mainloop *image-defines*

    (if (left?) (decf *x*))
    (if (right?) (incf *x*))
    (if (up?) (decf *y*))
    (if (down?) (incf *y*))

    (draw-image 0 *x* *y*)))