scalaとprocessingを使った倉庫番を作ったお

https://github.com/alphaneet/game-souko-scala


コンパイルやゲームの説明などはgithubのほうのREADMEを参考にしてくだしあ。
ここでは内部について簡単に書いていきたい思います。


もっとこうしたらいいという意見があればぜひお願いします>_<

コンポネーション(label, button)の配置

https://github.com/alphaneet/tool-uieditor-scala


この前作成したuieditorを使ってuiを配置し、xmlで吐き出しています。
それを読み込んでラベルやボタンなどを生成しています。


以下は、buttonの生成するxmlのサンプルです

<element>
  <id>3</id>
  <kind>button</kind>
  <name>Exit</name>
  <text>終了</text>
  <x>288</x><y>240</y>
  <w>100</w><h>30</h>
  <size>18</size>
</element>

アプリ側で使用するにはmyutil.Sceneクラスを継承します

// Sceneのコンストラクタ引数を省略すると
// getClass.getSimpleName+".xml"(この場合TestScene.xml)が呼ばれる
class TestScene  extends Scene {
  override def draw {
    background(255)
    Skin.draw
  }
}

// xmlファイル名を直接指定することもできる
class Test2Scene extends Scene("hoge.xml") {
  override def draw {
    background(255)
    Skin.draw
  }
}

drawメソッド(processingのAPIです)内でSkin.drawを呼び出せば読み込んだxml通りのコンポネーションが表示されます

定数(point, rect)の設定

ゲームではプレイヤーの位置(point)やマップの範囲(rect)などの定数も指定したい場合があります。
定数を設定する仕組みもuieditorには含まれていて point(座標) と rect(座標+幅)があります。
後々ペジュを使った弾の弾道軌道の数式を吐き出す機能も追加したいと思ってます。


エディター側で配置した定数は以下のようなxmlに吐き出されます。

<element>
  <id>0</id>
  <kind>rect</kind>
  <name>MAP</name>
  <text>MAP</text>
  <x>8</x><y>8</y>
  <w>288</w><h>288</h>
  <size>12</size>
</element>

アプリ側で使用するにはSkin.registerConstantsメソッドを呼び出します

// Skin.registerConstants をコールすると自動的に数値が代入される
var MAP_X, MAP_Y, MAP_W, MAP_H = 0

Skin.registerConstants 

これには次のようなメリット、デメリットがあると思います

メリット
  • 普通の変数感覚で使える
デメリット
  • 動的に生成できないので必ず宣言しなければならない。
  • varにしなければならない
  • リフレクションを使って代入しているので型安全ではない
  • 初めての人から見ると何が起こってるのか分かりづらい


どうみてもデメリットのほうが多いです本当にありが(ry
外部の設定ファイルを普通の定数感覚で使えるうまい方法がありましたら教えてくだしあ


webアプリケーションはあんまり作った経験はないんですが
railsのデータベースの操作(O/Rマッパー?)がこういう感じだったような記憶があります


自分の中の理想は以下のようなrubyスクリプトです。
yamlファイルから読み込んだデータを用いて動的にメソッドを生成し
あたかも普通の変数のように記述できる形です。

# yamlファイルの中身(test.yaml)
# save_path: C:\data

class YamlReader 
  def initialize(filename)
    hash = YAML.load_file(filename)

    # 動的に変数を生成
    hash.each do |key,val|
      self.class.class_eval do
        define_method(key) { val }
      end
    end
  end
end
$conf = YamlReader.new("test.yaml")
$conf.save_path # yamlファイルから読み込んだデータを変数のように扱える

このような書き方は動的な生成ができる言語ならではなんでしょうが・・・
詳細は知らないのですがscala2.9 でdynamic(動的?)機能が強化されるらしいので
scala2.9になった時また色々考えてみたいと思っています。

これから

processingの本体はAppletを継承したクラスなのでアプレットとして動かせることができます。


そのためにはscala-library.jarの容量が重そうなのでproguardを使用して圧縮、最適化してみようと思います。(ちょっとやってみたんですけどうまく変換できなかったお・ω・)


gae上でアプレットを動かせたら、鯖と連携してユーザーが作成したマップをみんなで遊べるようにしてみたいです。