ClojureのQuilでflappy bird。第1回

2023-04-18

「Nature of Code -Processingではじめる自然現象のシミュレーション」という本を入手して、ClojureのQuilを使って1章完了まで進めました。

おさらいに、フラッピーバードを作ってみようと思います。Nature of Code の内容を踏まえてつくるので、フラッピーバードには過剰な処理が入る予定です。

Clojureを勉強中なので、こうした方がいいよとかあれば、ツッコミお願いします。

Quilとは

JVM上で動く関数型言語のLISPであるClojureで、Processingできる環境。

公式サイトでは、ブラウザ上でも動かせます。

プロジェクト作成

まずはLeiningenでプロジェクトを作成

lein new quil flappy-bird

src/flappy_bird/core.cljに、サンプルのコードがコメント付きで作成されています。


├─  .gitignore
├─  LICENSE
├─  project.clj
├─  README.md
└─ /src
    └─ /flappy_bird
            └ core.clj

実行すると、円が色を変えながら右回転。

全体の動作

Processingの場合

Quilの元になっているProcessingの場合は、setupとdraw関数があります。

setupに書くのは、画面サイズの設定など、最初に一度だけ実行する処理。
drawに書くのは、座標の変更や図形の描画など、ずっと実行する処理。

座標などのデータはグローバル変数に保存します。

Quilの場合

Quilの場合は、setupとupdate-stateとdraw-stateの3つのがあります。

setupに書くのは、初期化処理と、一番最初にdraw-state関数に渡すデータを返す処理。
update-stateに書くのは、引数で受け取ったデータを書き換えて、返す処理。
draw-stateに書くのは、引数で受け取ったデータをもとに描画する処理。

座標などのデータは、関数型言語らしく、グローバル変数は使わずに、引数で受け取り、変更して、返り値で次に渡します。

setup(初期値) → draw-state(描画) → update-state(変更) → draw-date(描画) → update …。関数ごとに役割が分かれていて、draw-state関数で値を変更して返しても、update-stateには渡りません。(ただ、update-state内で描画した場合は画面表示されます)

初期状態のコード

(ns flappy-bird.core
  (:require [quil.core :as q]
            [quil.middleware :as m]))

(defn setup []
  (q/frame-rate 30)
  (q/color-mode :hsb)
 {:color 0   
   :angle 0})                          ;;初期の色と回転角を返す

(defn update-state [state]
  {:color (mod (+ (:color state) 0.7) 255)
   :angle (+ (:angle state) 0.1)})     ;;引数で受け取った値を元に新しい値を返す

(defn draw-state [state]
  (q/background 240)
  (q/fill (:color state) 255 255)     ;;引数で受け取った値を元に描画
  (let [angle (:angle state)
        x (* 150 (q/cos angle))
        y (* 150 (q/sin angle))]
    (q/with-translation [(/ (q/width) 2)
                         (/ (q/height) 2)]
      (q/ellipse x y 100 100))))

(q/defsketch flappy-bird               ;;画面サイズなどの基本的な設定
  :title "You spin my circle right round"
  :size [500 500]
  :setup setup
  :update update-state
  :draw draw-state
  :features [:keep-on-top]
 :middleware [m/fun-mode])

自機を表示する

まず、不要な処理を消して自機(とりあえず四角で表現)を表示させます。

(ns flappy-bird.core
  (:require [quil.core :as q]
            [quil.middleware :as m]))

(defn setup []
  (q/frame-rate 30)
  {:bird [100 100]})     ;;自機のxy座標をベクターで保持

(defn update-state [status]
  status)                  ;;xy座標を受け取って、そのまま返す

(defn draw-state [{:keys [bird]}]
  (q/background 240) 
  (let [[x y] bird] 
    (q/rect x y 30 30)))     ;;受け取ったXY座標に、30 30 の四角形を描画

(q/defsketch flappy-bird
  :title "flappy bird"
  :size [400 600]             ;;画面を縦長に設定
  :setup setup
  :update update-state
  :draw draw-state
  :features [:keep-on-top]
  :middleware [m/fun-mode])

四角形が表示されました。

まとめ

次回は、自機が移動できるように変更します。