kairo-gokko (26) 見た目の修正など



先に進む前に見た目に関する修正をここでやっておきます。

今やらなくてもいいものばかりなのですが (実際にプロトタイプの時はどれも後回しにしていました)、 ブログ記事を書く都合による修正と、 ついでなので見た目まわりをいくつか修正します。


ブログ記事を書く都合というのは、 GIF画像のことです。

f:id:sonota88:20200317053554g:plain

実際に動かして自分で操作する場合はクリック時に効果音によるフィードバックがありますが、 GIF画像だと音が出なくてクリックしたことが分かりにくいなと。

そこで、視覚的なフィードバックも追加します。

# main.rb

class PushHistory
  DURATION_SEC = 0.4
  @@history = []

  def self.add(pos)
    @@history << [pos, Time.now]
  end

  def self.sweep(now)
    @@history = @@history.select { |pos, time|
      now - time <= DURATION_SEC
    }
  end

  def self.get_for_draw(now)
    @@history.map { |pos, time|
      ratio = (now - time) / DURATION_SEC
      [pos, ratio]
    }
  end
end
# class View

  def draw_push_reaction(pos, ratio)
    x = pos.x
    y = pos.y
    alpha = 127 * (1 - ratio)
    r = 0.9 + ratio * 0.3

    @drawer.draw_circle_fill(
      x + 0.5, y + 0.5,
      r,
      [alpha, 150, 150, 150]
    )
  end

クリックされた位置と時刻を記憶しておく PushHistory というクラスを追加し、 そのデータを使って描画するようにしました。

こういうの追加していくとどんどん本質的でないコードで膨れていくので、全体の曳光弾が通るまでは控えめにしておきたいという気持ちもありますが、 「ブログに書く都合」「GIFでは音が出ないので〜」というのはそれなりにリーズナブルな要件なので、まあいいかという感じです。

f:id:sonota88:20200319071438g:plain

ちょっと分かりやすくなったのではないでしょうか?


次に、描画のぼやけ対策です。 これもブログに貼る都合ですね。 それと色を決める際の都合(狙った色にならないことの方が困る)。 Plumo のときは気にせずやっていましたが。

これまでセルのピクセルPPC (pixels per cell) = 30 として作ってきました。 これまでは特に問題はありませんでしたが、 回路が大きくなってくるとスペースの問題で これまでよりも小さめに表示したくなります。

このとき、単純に座標を変換して縮小表示しようとすると、ピクセル座標が半端な値になり、線がぼやけてしまいます。

f:id:sonota88:20200319071835p:plain

そこで、描画処理の際に座標を補正(整数化)することにしました。

( ※ DXOpal では座標を整数で指定した場合にくっきり表示されるようになっています。 参考: DXOpalのWindow.draw_boxのバグを修正した - Qiita

dxopal_sdl.rb を使っているときは補正は不要です(開発用なので適当でよい)。 ブラウザ+DXOpal な環境で動かすときだけ補正されればよいので、 drawer_dxopal.rb で吸収することにしました。 こうすると View クラスでは座標補正について意識せずに済みます。

このような補正用のメソッドを用意して、

# drawer_dxopal.rb
# class Drawer

  def adjust_px(raw_px)
    raw_px.round
  end

描画の直前で補正します。 例として draw_line。 ちょっとごちゃごちゃした感じになってしまいますが、しょうがないかな……。

# drawer_dxopal.rb
# class Drawer

  def draw_line(x1, y1, x2, y2, color)
    Window.draw_line(
      adjust_px(x1 * @ppc), adjust_px(y1 * @ppc),
      adjust_px(x2 * @ppc), adjust_px(y2 * @ppc),
      color
    )
  end

PPC = 25 の場合の比較です。

修正前:
f:id:sonota88:20200319071835p:plain

修正後:
f:id:sonota88:20200319071944p:plain

くっきりしました!


ここまでがブログのための修正。

次に、スイッチの描画がちょっと気になっていたのでちょっといじりたい。 これは単純に「思いついたのでやってみたかった」系のやつですね。

何かというと、現状ではたとえばエッジが OFF で スイッチが ON のとき 次のような見た目になりますが、 エッジが通電していないのになんでスイッチは光っているの?   と不自然に感じなくもないです。

f:id:sonota88:20200319073051p:plain

そこで、外枠はエッジと同じ色にしてはどうかと考えました。

つまり、 スイッチの状態は中の部分の位置と色で表現されるのはこれまで通りで、 外枠がエッジの一部っぽく見えるようにします。

f:id:sonota88:20200319073325g:plain

どうでしょうか。 リレーと組み合わせた場合はこんな感じになります。

f:id:sonota88:20200319072326g:plain

機能として不可欠というわけではないのでこの修正はなくても先に進めますが、 見た目がちょっとおもしろくなるので、 これに関してはおもしろさ優先でギミックとして採用してみました。

うーん、こうして見ると、緑色は通電状態に対応しているので中の部分の色は変えた方がいい?   ……とか考えてしまいますが、きりがないのでいったん放置して進みます。


あと、気になっていたのが main.rb の draw メソッドです。

# main.rb

def draw(view, ...)
  view.draw_foo
  view.draw_bar
  ...
end

このパターン、いかにもこれは View の責務でしょという雰囲気が漂っていますね。 この際 View に移動しましょう。

# main.rb
def main_loop(circuit, view)
  # ...

  view.draw(circuit, ...)
end

MVC で言えば circuit がモデル相当でしょう。 モデルをそのままビューに渡して「後はやっといてね」 と丸投げする形になりました。