kairo-gokko (8) 描画部分をDXOpalに交換



手っ取り早く可視化したかったので Plumo を使ってきましたが、 Plumo はしょぼいのでマウスで操作したり効果音を出したりできません。 そこで、DXOpal を使って書き直します。 最近 DX 流行ってますしね(それは違うやつ)。

github.com

まあ、マウス操作も効果音もまだ必要にはなってないのですが……。


やっていきます。

Gemfilegem "dxopal" を追加して bundle install

インストールできたら下記で必要なファイルを用意します。

$ bundle exec dxopal new game1
DXOpal v1.5.1
Wrote index.html
Wrote main.rb
Wrote dxopal.min.js

$ mv game1/* .

$ rmdir game1/

とりあえず実行。

bundle exec dxopal server

ブラウザで http://localhost:7521/index.html を開いて "Hello!" と表示されれば OK。次へ。


viewer.rb に書いていた処理を main.rb に移し替えていきます。

まずは data.json を読めるようにします。 Native + XMLHttpRequest を使う方法もあるようですが (mieki256's diary - DXOpalでタイルマップBGを描画)、 JSONdata.rb に吐いて require_remote で読む方法を思いついたのでこれで済ませます。雑。でも手軽。

前処理で data.json に出力していた部分を修正。

--- a/preprocess.rb
+++ b/preprocess.rb
@@ -22,5 +22,7 @@ circuit = Circuit.create(
   page.rectangles
 )
 
+puts "$data_json = <<EOB"
 print JSON.pretty_generate(circuit.to_plain)
 print "\n"
+puts "EOB"

出力先のファイル名を修正。

--- a/run.sh
+++ b/run.sh
@@ -2,6 +2,6 @@
 
 set -o errexit
 
-ruby preprocess.rb "$@" > data.json
+ruby preprocess.rb "$@" > data.rb
 
 bundle exec ruby viewer.rb

main.rb から読み込み。 require_remote では拡張子を省略してはいけない点に注意( 参考 )。 頭の ./ はなくても動きますがなんとなく今までの書き方に合わせて付けています。

--- a/main.rb
+++ b/main.rb
@@ -1,5 +1,10 @@
 require 'dxopal'
 include DXOpal
+
+require_remote "./data.rb"
+
+puts $data_json
+
 Window.load_resources do
   Window.bgcolor = C_BLACK

読み込んだ JSON が開発者ツールのコンソールに表示されました。 よしよし。


circuit.rb は前処理と実行(DXOpal な環境)の両方で使うので RUBY_ENGINE を見て require の部分を切り替えるようにします。

if RUBY_ENGINE == "opal"
  require_remote "./unit.rb"
else
  require "./unit"
end

JSON が読めたら次は circuit オブジェクトの復元。

# main.rb

require_remote "./circuit.rb"

def parse_json(json)
  Native(`JSON.parse(json)`)
end

circuit = Circuit.from_plain(
  parse_json($data_json)
)

puts circuit

できますね。


circuit オブジェクトが復元できたので、次は描画処理の移植に進みます。

DXOpal 版の Drawer クラスを用意します。 試しにまずは draw_line だけ移植してみましょう。

# drawer_dxopal.rb

class Drawer
  def initialize(ppc)
    @ppc = ppc
  end

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

view.rb の方ではこれまでの drawer.rb の代わりに drawer_dxopal.rb を require します。

--- a/view.rb
+++ b/view.rb
@@ -1,4 +1,5 @@
-require "./drawer"
+# require "./drawer"
+require_remote "./drawer_dxopal.rb"
 
 class View
   def initialize(ppc)

main.rb の修正。

--- a/main.rb
+++ b/main.rb
@@ -3,6 +3,10 @@ include DXOpal
 
 require_remote "./data.rb"
 require_remote "./circuit.rb"
+require_remote "./view.rb"
+
+# pixels per cell
+PPC = 30
 
 def parse_json(json)
   Native(`JSON.parse(json)`)
@@ -12,12 +16,12 @@ circuit = Circuit.from_plain(
   parse_json($data_json)
 )
 
-puts circuit
+view = View.new(PPC)
 
 Window.load_resources do
   Window.bgcolor = C_BLACK
 
   Window.loop do
-    Window.draw_font(0, 0, "Hello!", Font.default, color: C_WHITE)
+    view.draw_grid(8, 10)
   end
 end

グリッド線が描けました!

f:id:sonota88:20200223162103p:plain


後は draw_box も同様に移植して、回路部分も描画します。

f:id:sonota88:20200223161914p:plain

できました〜。