ClojureのQuilでflappy bird。第7回

「Nature of Code -Processingではじめる自然現象のシミュレーション」という本を入手。1章完了まで進めたので、おさらいに、フラッピーバードを作成中。
Clojureを勉強中なので、こうした方がいいよとかあれば、ツッコミお願いします。

前回は、衝突判定を作成しました。

今回は、ただランダムに表示されている障害物を、上下一組のペアで表示されるようにします。

上下一組で土管を表示

まず、指定した座標に一定の大きさで左向きに移動する土管(moverのマップ)を返す関数を作ります。


(def pipe-width 50)
(def pipe-height 500)

(defn make-pipe [x y]
  (-> (mv/mover x y
                pipe-width pipe-height)
      (mv/apply-force [-1. 0.])))

x座標と、2つのパイプの中心のY座標と、パイプの隙間の高さを指定して、上下1組2つの土管を返す関数を作ります。

(defn make-pair-pipe [x y-center gap]
  (let [upper-y (- y-center (/ gap 2) pipe-height) 
        lower-y (+ y-center (/ gap 2))] 
    [(make-pipe x lower-y)
     (make-pipe x upper-y)]))

setup関数の中で、中央の隙間のY位置がランダムな土管のペアを、一定の間隔ごとに作成します

(defn setup []
  (q/frame-rate 30)
  (q/text-size 24)
  (let [number-of-pipes 100
        pipe-spacing 180
        gap 200
        xs (map #(+ (q/width) (* pipe-spacing %1)) 
                (range number-of-pipes))              ;(400 580 760 940…
        y-centers (for [_ (range number-of-pipes)] 
                    (rand-int (q/height)))            ;((233 262 74 405…
        pipes (-> (map #(make-pair-pipe %1 %2 gap) 
                       xs y-centers )
                  flatten)]
    
    {:bird (mv/mover (/ (q/width) 4.) (/ (q/height) 2.) 30. 30.)
     :pipes pipes
     :game-over? false}))

得点の表示

得点の計算は、自機が通過した(自機より左にある)土管の数を数えて、(上下で一組なので)2で割った値にしました。

(defn setup []
  (q/frame-rate 30)
  (q/text-size 24)                                              ;;
  {:bird (mv/mover (/ (q/width) 4.) (/ (q/height) 2.) 30. 30.)
    ;;略
    })                                                    

;;略

(defn draw-state [{:keys [bird pipes game-over? score]}]    ;;scoreを追加
  (if game-over?

     ;;略
    (do 
      (q/background bgcolor)
      (q/text (format "score: %07d" score) 30 30)     ;;画面左上に特典を表示
      (mv/display bird)
      (doseq [p pipes]
        (mv/display p))
      (let [get-x first                               
            score (->> pipes                          
                       (filter #(< (-> % :location get-x) (-> bird :location get-x)))
                       count                        ;; 自機が通過したパイプを数えて
                       (* 0.5))]
        (q/text (format "score: %07.0f" score) 30 30)))))  ;表示

まとめ

今回は、土管が上下ペアで現れるようにして、クリアした土管の数を表示しました。

あとは、

  • 地面を追加
  • 効果音を鳴らす