`(kakko ,man)

Find a guide into tomorrow by taking lessons from the past

Lisp Game Programming 2 <Stage 5>

3面切り替えのスクロールができたので、ここも一気にスタートメニューからゲームオーバーのメッセージまで作成。

ここでの工夫は、画面のモードの切り替え方法。

https://github.com/jueqingsizhe66/lispbuilder-1/blob/master/lispbuilder-sdl/examples/particles.lisp

どうしても、日本語でメッセージを出したい人はこちらを参照。

http://d.hatena.ne.jp/masatoi/20120914/1347600686

 

;; Step4 <Game Start Message>
;; -----------------------------------------------------------------------------------------------
(defvar *screen-mode* 1) ; screen mode toggle switch 0:fullscreen 1:windowed
(defvar *switch* nil) ; screen change flag

(defgeneric Game-start-message (pointer character stage keystate))
(defmethod Game-start-message (pointer character stage keystate) ; game start message
  "Draw game opening message"
  ; title
  (dotimes (i 8) ; show title
    (setf (x character) (+ 192 (* i 32)) 
            (id character) (+ 19 i))

    (Draw character))
  ; memu
   (sdl:draw-string-solid-* "S T A R T" 224 328 :color sdl:*white* :font *menu-font*) ; show menu
   (if (= *screen-mode* 0)
       (sdl:draw-string-solid-* "S C R E E N : F U L L" 224 360 :color sdl:*white* :font *menu-font*)
       (sdl:draw-string-solid-* "S C R E E N : W I N D O W" 224 360 :color sdl:*white* :font *menu-font*))
       (sdl:draw-string-solid-* "E X I T" 224 392 :color sdl:*white* :font *menu-font*)
  ; select menu
  (cond ((up keystate) ; select menu
              (decf (y pointer) 32)
              (setf (up keystate) nil)
              (when (<= (y pointer) 328) ; y:328 is START menu position
                (setf (y pointer) 328
               (start stage) t)))
           ((down keystate)
              (incf (y pointer) 32)
              (setf (down keystate) nil)
              (when (>= (y pointer) 392) ; y:392 is EXIT menu position
                (setf (y pointer) 392
                (start stage) nil)))
           ((lshift keystate)
              (if (= *screen-mode* 1) ; screen-mode toggle switch
                (setf *screen-mode* 0) ; 0:fullscreen 1:windowed
                (setf *screen-mode* 1))
                (setf *switch* t)
                (setf (lshift keystate) nil)))
  ; show pointer
  (sdl:draw-string-solid-* ">" (x pointer) (y pointer) :color sdl:*white* :font *menu-font*)
  ; game start or exit
  (cond ((and (z keystate) (eql (start stage) t) (= (y pointer) 328)) ; input z-key on start menu
                      (setf (title-loop stage) nil
                              (z keystate) nil)) ; z key state reset
            ((and (z keystate) (eql (start stage) nil) (= (y pointer) 392)) ; input z-key on exit menu
               (sdl:push-quit-event)))
               (sdl:update-display))

;; Step4 <Game Over Message>
;; -----------------------------------------------------------------------------------------------
(defgeneric Game-over-message (stage))
(defmethod Game-over-message (stage)
  "Draw game ending message"
  (sdl:clear-display sdl:*black*)
  ; message
  ; (sdl:draw-string-solid-* "君の活躍によりアボガドロ軍は撤退した。"
  ; 178 64 :color sdl:*white* :font *menu-font*)
  (sdl:draw-string-solid-* "THE ABOGADRO FORCES WITHDREW BY YOUR  SUCCESS" 150 64 :color sdl:*white* :font *menu-font*)

  (sdl:draw-string-solid-* "C O N G R A T U L A T I O N S" 208 96 :color sdl:*white* :font *menu-font*)
  (sdl:draw-string-solid-* "Y O U R S C O R E 0000000 " ; <--dummy
                                     224 160 :color sdl:*white* :font *menu-font*)
  (sdl:draw-string-solid-* "H I G H S C O R E 0005000" ; <--dummy
                                     224 192 :color sdl:*white* :font *menu-font*)
  (sdl:update-display)
  (sleep 10)
  ; reset variables
  (setf (title-loop stage) t
          (stage-flag stage) t
          *map-pointer* 64
          (stage-number stage) 0))

;; Step4 <Judge Map End>
;; -----------------------------------------------------------------------------------------------
(defgeneric Judge-map-end(stage))
(defmethod Judge-map-end (stage)
  (when (and (= (stage-number stage) 3) ; stage 3 and map-poiner is 0
       (= *map-pointer* 0)) ; game over
    (Game-over-message stage)))

;; Step4 <Set Screen Mode>
;; -----------------------------------------------------------------------------------------------
(defun Set-screen-mode()
  (when (eql *switch* t)
    (if (= *screen-mode* 0) ; fullscreen-mode on
      (sdl:resize-window 640 480 :sw t :fullscreen t)
      (sdl:resize-window 640 480 :sw t :resizable t))
      (setf *switch* nil))) ; twice executing prevent

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

; <Set Charactor Object>
(let((ship (make-instance 'entity :id 0 :x 304 :y 416 :width 32 :height 32 :dx 4 :dy 4 :state 1))
       (keystate (make-instance 'keystate))
       (game-field (make-instance 'game-field :field-x 160 :field-y 16 :width 480 :height 464))
       (stage (make-instance 'stage :stage-number (or nil 0) :title-loop t))
       (character (make-instance 'object :id 19 :y 100))
       (pointer (make-instance 'object :x 208 :y 328)))

(sdl:with-events (:poll)
  (:quit-event ()
    (setf *screen-mode* 1
            *switch* nil)
t)

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

(:idle ()
;<Title Loop>
(when (eql (title-loop stage) t) ; title loop
  (sdl:clear-display sdl:*black*)
  (Game-start-message pointer character stage keystate))

; <Game Loop>
  (when (eql (title-loop stage) nil) ; game loop

  ; <Set Screen Mode>
    (Set-screen-mode)
  ; <Clear Display>
    (sdl:clear-display sdl:*black*)
  ; <Show Message> 
    (Stage-start-message stage)
  ; <Draw Map>
    (Scroll-background *atlas*)
    (Scroll-mask)
  ; <Move Ship>
    (Move-ship ship keystate)
  ; <Fix Ship Position>
    (Fix-ship-position ship game-field)
  ; <Draw Images>
    (when (= (state ship) 1)
      (Draw ship)) ; draw ship
  ; <Set Map Edge>
    (Set-map-edge stage) ; set map draw point
  ; <Judge All Map Used>
    (Judge-map-end stage)

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

 (6/6)インスタンスの状況が分からなかったため青字の部分を追加