kairo-gokko (12-2) 通電 2



次はもうちょっと複雑なパターンを……と思いましたが、 その前にエッジ 1本の通電判定処理だけ作ってみることにします。

動くものができるとモチベーションも上がるでしょう。


  • クリックでスイッチだけ状態を更新
  • スイッチの状態に応じてエッジの通電状態を更新

の2段階に分けて実装します。

スイッチの状態を更新

マウスでスイッチ(の位置)をクリックしたことを検出して Switch#toggle() で状態をトグルするようにしました。

--- a/main.rb
+++ b/main.rb
@@ -42,7 +42,15 @@ Window.load_resources do
     my = (Input.mouse_y / PPC).floor
 
     if Input.mouse_push?(M_LBUTTON)
-      Sound[:click].play
+      mpos = Point(mx, my)
+
+      pushed_switch =
+        circuit.switches.find { |switch| switch.pos == mpos }
+
+      if pushed_switch
+        pushed_switch.toggle()
+      end

       Sound[:click].play
     end
 
     view.draw_grid(8, 10)

スイッチの状態に応じて表示色を変えて、

--- a/view.rb
+++ b/view.rb
@@ -66,6 +66,8 @@ class View
   end
 
   def draw_switch(switch)
+    color = switch.on? ? C_ACTIVE : C_INACTIVE
+
     @drawer.draw_box_fill(
       switch.x + 0.1, switch.y + 0.1,
       switch.x + 0.9, switch.y + 0.9,

 ... snip ...

同じように、状態に応じてスイッチの四角の中の横棒の位置を変えます。

f:id:sonota88:20200229124246g:plain

クリックで色と形が変わるようになり、スイッチ感が出てきました!

エッジの状態を更新

スイッチと同様に、Unit::Edgeインスタンス変数 @state と、状態参照・更新のために #on?()#update() を追加して、通電判定用のクラス Tuden を追加しました。

ひとまずこれだけ。

class Tuden
  def self.tuden?(switch)
    switch.on?
  end
end

名前をどうするか悩みましたが、どれもしっくりこなかったので Tuden で進めます。 いいんですこれで。ユビキタス言語だから。たぶん。 いい名前を思いついたら後でリネームします……。


Circuit#update_edges() を追加。 まずは曳光弾を通したいので、エッジ 1本、スイッチ 1本のケースだけを考えます。

class Circuit
  # ...
  def update_edges
    is_tuden = Tuden.tuden?(@switches[0])
    @edges[0].update(is_tuden)
  end

  # ...

いやー、この is_tuden という名前もひどいなあ。はっはっは。


Circuit#update_edges() をメインループから呼び出します。

Window.load_resources do
  Window.bgcolor = C_BLACK

  Window.loop do
    mx = (Input.mouse_x / PPC).floor
    my = (Input.mouse_y / PPC).floor

    if Input.mouse_push?(M_LBUTTON)
      mpos = Point(mx, my)

      pushed_switch =
        circuit.switches.find { |switch| switch.pos == mpos }

      if pushed_switch
        Sound[:click].play
        pushed_switch.toggle()
      end
    end

    circuit.update_edges()

    # 以下描画処理

あとはスイッチの場合と同様に、エッジの状態に応じて描画色を変えれば……

  def draw_edge(edge)
    color = edge.on? ? C_ACTIVE : C_INACTIVE

    # ...

f:id:sonota88:20200229133435g:plain

https://sonota88.github.io/kairo-gokko/pages/12/index.html で試せます。※マウス操作のできないスマホタブレットは非対応。 )

できました!

スイッチの切り替えでエッジの通電状態が変化しています(変化しているように見えます)!

まだエッジ 1本にスイッチ 1個だけですが、 やはり自分の操作でインタラクティブに動くようになると楽しいですね。


まずはスイッチ1個の場合の曳光弾が通りました。 次は複数のスイッチに対応させましょう。