`(kakko ,man)

Find a guide into tomorrow by taking lessons from the past

Lisp Game Programming <Step10-2>

2番目は、enemyのstateが1(alive)で画面内に位置し(少しでもはみ出したら弾を発射しない)、出現してから64回移動したらenemy-shot(弾)を撃つプログラム
shot位置はenemyの真ん中に設定し、移動方向はenemyの種類で異なる

enemy1 ⇒ enemy-shotは真下に移動

enemy2⇒ enemy-shotは真上に移動

enemy3⇒ enemy-shotは真横に移動(enemy3の移動方向で左右が決定)

;; Step10 <Set Enemy Shot>
;; -----------------------------------------------------------------------------------------------
(defgeneric Set-enemy-shot (foe))

(defmethod Set-enemy-shot (foe)
  "enemy shot appear position set and move"
  (dolist (enemy (enemy-list foe))
  (when (and (= (state enemy) 1)
                      (> (x enemy) 0)
                      (< (x enemy) (- *graphic-width* 32))
                      (> (y enemy) 0)
                      (< (y enemy) (- *graphic-height* 32))
                      (= (mod (move-cnt enemy) 64) 0))
  (let ((enemy-shot (make-instance 'entity :imageid 2 :id 1 :state 0)))
    (push enemy-shot (enemy-shot-list foe)))
    (dolist (enemy-shot (enemy-shot-list foe))
    (when (= (state enemy-shot) 0)
      (setf (y enemy-shot) (+ (y enemy) 8))
      (setf (x enemy-shot) (+ (x enemy) 8))
      (setf (state enemy-shot) 1)
      (ecase (id enemy)
        (2 (progn
               (setf (dx enemy-shot) 0)
               (setf (dy enemy-shot) 6)))
        (3 (progn
               (setf (dx enemy-shot) 0)
               (setf (dy enemy-shot) -6)))
        (4 (progn
               (if (= (dx enemy) -3)
                 (setf (dx enemy-shot) -6)
               (setf (dx enemy-shot) 6))
               (setf (dy enemy-shot) 0)))))))))