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)インスタンスの状況が分からなかったため青字の部分を追加