読者です 読者をやめる 読者になる 読者になる

`(kakko ,man)

Find a guide into tomorrow by taking lessons from the past

Lisp Game Programming <Step6>

キー操作でshipを上下左右に動かすため、キーの状況を管理するクラスを作成

そして、shipを移動させるためのメソッドも作成する

↑↓→←zのどれかのキーが押されたら、keystateクラスのそれぞれにtがセットされる

なお、Shipが移動できるのは、shipのstateがalive、rivivalの場合のみに設定

;; step6 <Key State>
;; -----------------------------------------------------------------------------------------------
(defclass keystate ()
  ((%right :initarg :right :initform nil :accessor right)
   (%left :initarg :left :initform nil :accessor left)
   (%up :initarg :up :initform nil :accessor up)
   (%down :initarg :down :initform nil :accessor down)
   (%z :initarg :z :initform nil :accessor z))
  (:documentation "The Keystate Class"))

(defgeneric Update-keystate (key boolean keystate))

(defmethod Update-keystate (key boolean keystate)
  (cond ((sdl:key= key :SDL-KEY-RIGHT) (setf (right keystate) boolean))
             ((sdl:key= key :SDL-KEY-LEFT) (setf (left keystate) boolean))
             ((sdl:key= key :SDL-KEY-UP) (setf (up keystate) boolean))
             ((sdl:key= key :SDL-KEY-DOWN) (setf (down keystate) boolean))
             ((sdl:key= key :SDL-KEY-Z) (setf (z keystate) boolean))))

(defgeneric Move-ship (ship keystate))

(defmethod Move-ship (ship keystate)
  (when (or (= (state ship) 1)
                   (= (state ship) 3))
  (cond ((right keystate) (incf (x ship) (dx ship)))
             ((left keystate) (decf (x ship) (dx ship)))
             ((up keystate) (decf (y ship) (dy ship)))
             ((down keystate) (incf (y ship) (dy ship))))))

メインルーチンは以下

(defun Common-shooter ()
  "main routine"
  (sdl:with-init (sdl:sdl-init-video sdl:sdl-init-audio) ; use video and audio
  (sdl:window 640 480 :position #(192 50) ; size 640*480, position x(192) y(50)
                                       :title-caption "THE SHOOTER"
                                       :icon-caption "THE SHOOTER"
                                       :double-buffer T)
                                     ; :fullscreen T)
  ; step 3
  (Initialize) ; graphics initialize
  ; step 5
  (Set-font) ; set font 
  ; step 2 
  (Open-sound) ; open audio and load sound data 
  ; step 2
  (Play-music *bg-music*) ; play music
  ; step 3 - 6
  (let ((keystate (make-instance 'keystate)) ; step 6 add sentence
         (ship (make-instance 'entity :imageid 0 :id 0 :x 224 :y 416
                                                     :width 32 :height 32 :dx 4 :dy 4 :state 1))
         (score-ship (make-instance 'object :imageid 0 :id 0 :x 496 :y 128))
         (mapchip (make-instance 'object :imageid 1 :id 0)))

  (sdl:update-display)
  (sdl:with-events (:poll)
  (:quit-event ()
  ; step 2
  (Stop-sound) ; sample and music stop
  (Close-sound) ; close audio
    t)
  ; step 6
  (:key-down-event (:key key)
    (if (sdl:key= key :SDL-KEY-ESCAPE)
        (sdl:push-quit-event)
      (Update-keystate key t keystate)))
    (:key-up-event (:key key)
      (Update-keystate key nil keystate))
    (:idle ()
    ; Game body
    ; step 6
 (Move-ship ship keystate)
    ; step 4
    (Scroll mapchip) ; scroll background
    ; step 3
    (when (= (state ship) 1)
      (Draw ship)) ; draw ship
    ; step 5
    (Score-panel score-ship) ; draw score panel

  (sdl:update-display))))))

こんな感じでキーでshipを動かすことができるようになる

但し、画面の範囲からはみ出すため、画面内に留めておくプログラムが必要

f:id:tomekame0126:20140706144630p:plain