bigsleepの日記

2015-11-15

elm使ってなにか書いてみた

00:11

書いてみたものはこれです

https://github.com/bigsleep/mapeditor

なんかゲームを作ろうかと思いつつ全然作ってないんですが

作ったらマップエディターとかが必要かなと思ってそんな感じのものを作りつつ

elmでhtmlのイベントを扱うやり方などを学んだりしました。

cssも調べつつ書いてみたんですがなんかおかしいかもしれません。

色々実験で少しづつ書き足していったのでサンプルコードとしてはわかりにくいです。


elm-html

viewでhtmlを生成するところにelm-htmlライブラリを使いました。

http://package.elm-lang.org/packages/evancz/elm-html/4.0.1/

coreのライブラリにもGraphics.Elementなどhtmlを出力するモジュールがあるんですが

公式サイトのexamplesでもelm-htmlライブラリが使われていたりして、こっちを使うほうが

普通なのかなという感じがしました。

elm-htmlではvirtual-domというのを使っていて描画が速かったりするようです。

htmlに型がついているのはいい気がするんですが、

htmlシンタックスで書いてコンパイル時にelmの関数に変換するとかもできたら便利かなと思いました。


htmlイベント

htmlイベントを扱うためのものはelm-htmlHtml.Eventsにありました。

http://package.elm-lang.org/packages/evancz/elm-html/4.0.1/Html-Events


公式サイトのhtmlの例

http://elm-lang.org/examples/buttons


Html.Eventsにあるonなんとかの関数を使ってhtml要素にAttributeとして埋め込んで

イベントを拾うような感じのようです。


AddressはSignalに値を流すのに使うもので

Signal.mailbox という関数を使うとAddressとSignalの組がとれます。

http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Signal#Mailbox



Json.Decode

イベントのオブジェクトから色々な値を取り出すのにJsonのデコーダーを使うようです。

多分haskellのaesonとかの書き方に似てそうでした。

http://package.elm-lang.org/packages/evancz/elm-html/4.0.1/Html-Events#on

http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Json-Decode


使い方にこちらの記事を参考にさせてもらいました

http://qiita.com/jooex/items/7c2f44fc961d14880d96


ただこれで値とれないものもあるようで

キャンバスの座標を取得するときにgetBoundingClientRect()というのが

必要みたいなんですがデコーダーの書き方がわからず

結局portを使ってJavaScript側にイベントを拾う処理を書きました。


port

JavaScript側で定義したものをelm側で使ったり

逆にelm側で定義したものをJavaScript側で使ったりするのにportというのを使います。

http://elm-lang.org/guide/interop


portで使える型は限られているようでユーザーが定義した型は使えないみたいです。

上のページの一番下あたりに使える型一覧があります。

elm側でviewの処理を書かない時などはSignal Json.Valueをexportして

JavaScript側でhtml作るとかでもいいかもしれません。

今回はなるべくelm側に書こうとしてたんですがキャンバスの座標を取得するところだけport使って書きました。


どんな感じで書くのか

今回書いたコードの入力のアクションは下のような感じにしました。

タイルを置く、タイルを動かす、リサイズするという感じです。

type AppInput
    = PutTile Int (Int, Int)
    | Move (Int, Int) (Int, Int)
    | ResizeMap (Int, Int)

最初はここにMouseDownとかUIで拾う入力を直接書いてたんですが、

UIは変わったりもするのでモデル側の入力にはもっと具体的な

操作として書く方がいい気がして上のようにしました。

キーボードマウス、ボタンクリックなどUIで拾ったイベントを色々加工して

必要な入力に持っていくのがいいのかなと思います。


大分前にこちらのスライドを読んだのを思い出したりして参考にさせてもらいました。

生イベントから意味イベントを作ろうということが書かれてました。

http://www.itpl.co.jp/tech/func/event-driven.pdf

追記

こちらのスライドでも上のスライドが紹介されていて、自分はこっちを先に見てたのかもしれません。こちらもelmの書き方の参考になりました。

http://www.slideshare.net/maedaunderscore/elmfunctional-reactive-programming

トラックバック - http://d.hatena.ne.jp/bigsleep/20151115/1447600274