Lisp Game Programming 2 <Stage 8>
マップ上に登場する敵以外のもので「オプション」と「ボム」のアイテムがあるが、どのように処理しているのかざっと見てみると、こんな感じの動作をしている
オプション → 取ると、自分の周りを回転するバルーンが1個ずつ増え、最大は2個まで。
それ以上取ると、点数が500点増える
ボム → 左下のボムマークが増えていき、ボム(爆弾を爆発させる)回数がボムマ
ーク分となる。
とりあえず、オプションがおもしろそうなので該当する部分のコードを書いてみる。
degree-radianの変換はどっかで見たような気もするが忘れた。
⇒ ab-stage8.lispの一部
;; Step8 <Move Balloon> ;; ----------------------------------------------------------------------------------------------- (defun degree-radian (degree) ; convert from radian to degree (/ (* degree pi) 180)) ; degree -> radian (defvar *angle* 0) (defgeneric Move-balloon (balloon-manager ship)) (defmethod Move-balloon (balloon-manager ship) (when (or (= (state ship) 1) (= (state ship) 3)) (when (> *angle* 360) (setf *angle* 0)) (incf *angle* 4) (when (<= *angle* 360) (let ((i (balloon-cnt balloon-manager))) (dolist (balloon (balloon-list balloon-manager)) (if (= i 2) ; 48 is distance from left balloon to right balloon (setf (x balloon) (+ (x ship) (floor (* (cos (degree-radian *angle*)) 48))) (y balloon) (+ (y ship) (floor (* (sin (degree-radian *angle*)) 48)))) (setf (x balloon) (- (x ship) (floor (* (cos (degree-radian *angle*)) 48))) (y balloon) (- (y ship) (floor (* (sin (degree-radian *angle*)) 48))))) (decf i 1)))))) ;; Step8 <Generate Balloon> ;; ----------------------------------------------------------------------------------------------- (defgeneric Generate-balloon (balloon-manager ship)) (defmethod Generate-balloon (balloon-manager ship) "balloon appear position set" (when (and (/= (balloon-cnt balloon-manager) 0) (< (length (balloon-list balloon-manager)) 2)) ; max 2 balloon (dotimes (i (balloon-cnt balloon-manager)) (let ((balloon (make-instance 'entity :id 10 :state 1))) (if (= i 0) (setf (x balloon) (- (x ship) 48)) (setf (x balloon) (+ (x ship) 48))) (setf (y balloon) (y ship)) (push balloon (balloon-list balloon-manager)))))) ;; step8 <Draw Balloon> ;; ----------------------------------------------------------------------------------------------- (defgeneric Draw-balloon (balloon-manager ship)) (defmethod Draw-balloon (balloon-manager ship) (when (and (or (/= (state ship) 1) (state ship) 3) (/= (balloon-cnt balloon-manager) 0)) (dolist (balloon (balloon-list balloon-manager)) (Draw balloon)))) ;; Step8 <Move Item> ;; ----------------------------------------------------------------------------------------------- (defgeneric Move-item (item-manager game-field)) (defmethod Move-item (item-manager game-field) "item move" (dolist (item (item-list item-manager)) (when (= (state item) 1) ; option-item is alive (incf (y item) (dy item))) ; option-item 16 dot down (when (> (y item) (height game-field)) ; out of screen (setf (state item) 0)))) ;; Step8 <Remove Item> ;; ----------------------------------------------------------------------------------------------- (defgeneric Remove-item (item-manager)) (defmethod Remove-item (item-manager) "item remove from list" (setf (item-list item-manager) (delete-if #'(lambda (item) (= (state item) 0)) (item-list item-manager)))) ;; Step8 <Hit Item> ;; ----------------------------------------------------------------------------------------------- (defvar *itemget-flag* nil) (defgeneric Hit-item-p (item-manager balloon-manager score ship)) (defmethod Hit-item-p (item-manager balloon-manager score ship) (when (/= (state ship) 2) (dolist (item (item-list item-manager)) (when(and (> (+ (x ship) 32) (x item)) (< (x ship) (+ (x item) 32)) (> (+ (y ship) 32) (y item)) (< (y ship) (+ (y item) 32))) (setf (state item) 0) ; item is disappered (when (eql *itemget-flag* nil) (setf *itemget-flag* t)) (when (= (id item) 17) (if (< (balloon-cnt balloon-manager) 2) (incf (balloon-cnt balloon-manager) 1) (incf (score score) 500))) (when (= (id item) 18) (incf (n-bomb score) 1)) (setf *itemget-flag* nil))))) ;; step8 <Draw Item> ;; ----------------------------------------------------------------------------------------------- (defgeneric Draw-item (item-manager)) (defmethod Draw-item (item-manager) (dolist (item (item-list item-manager)) (Draw item)))
当然、こんなものも必要になり、
(define-class balloon-manager () (balloon-list balloon-cnt) nil) ; balloon-list list of balloon ; balloon-cnt max 2 balloon (define-class item-manager () (item-list item-flag) nil) ; item-list list of item ; item-flag item get flag
メインループはこんな感じ。
;; step1 <Game Frame> ;; ----------------------------------------------------------------------------------------------- (defun Common-abogadro () "main routine" (sdl:with-init (sdl:sdl-init-video sdl:sdl-init-audio) ; use video and audio (sdl:window 640 480 :position 'center ; size 640*480, position center ; :position #(192 50) ; position x(192) y(50) :title-caption "ABOGADRO" :icon-caption "ABOGADRO" :flags '(sdl:sdl-doublebuf sdl:sdl-sw-surface)) ; <Initialize> (Initialize) ; graphics initialize ; <Set Font> (Set-font) ; set font ; <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)) (score (make-instance 'score :highscore 50000 :oneup 50000 :n-ship 3 :n-bomb 3)) (score-ship (make-instance 'object :id 5 :x 160 :y 48)) (score-bomb (make-instance 'object :id 6 :x 160 :y 448)) (shot-manager (make-instance 'shot-manager)) (enemy-manager (make-instance 'enemy-manager)) (balloon-manager (make-instance 'balloon-manager :balloon-cnt (or nil 0))) (item-manager (make-instance 'item-manager))) (sdl:with-events (:poll) (:quit-event () (setf *screen-mode* 1 *switch* nil) (Reset-variables stage enemy-manager balloon-manager score) t) ; <Update Key State> (: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) (setf (id ship) 0)) ; set ship id 0 (normal form) (: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*) ; <Move Ship> (Move-ship ship keystate) ; <Fix Ship Position> (Fix-ship-position ship game-field) ; <Shot :Move Set Draw Delete> (Move-shot shot-manager) (Set-shot shot-manager ship keystate balloon-manager) (when (= (state ship) 1) (Draw ship)) ; draw ship (Draw-shot shot-manager) (Remove-dead-shot shot-manager) ; <Enemy :Move Generate Draw Remove> (Move-enemy enemy-manager game-field) (Generate-enemy-item *enemymap* enemy-manager item-manager) (Draw-enemy enemy-manager) (Remove-enemy enemy-manager) ; <Balloon :Move Set Draw> (Move-balloon balloon-manager ship) (Generate-balloon balloon-manager ship) (Draw-balloon balloon-manager ship) ; <Item : Move Draw Remove Hit> (Move-item item-manager game-field) (Draw-item item-manager) (Remove-item item-manager) (hit-item-p item-manager balloon-manager score ship) ; <Upper and Lower Window Mask> (Scroll-mask) ; <Draw Score Panel> (Score-panel score score-ship score-bomb) ; <Set Map Pinter> (Set-map-pointer) ; set map draw point ; <Judge Stage End> (Judge-stage-end stage enemy-manager score balloon-manager) (sdl:update-display)))))))