LoginSignup
6

More than 5 years have passed since last update.

Organization

実例で学ぶ purescript ライブラリの開発

purescript-enchantjs

本記事では PureScript の初学者を対象にして、PureScript ライブラリの開発手順を紹介します。
purescript-enchantjs は PureScript を使ってゲームを作成するためのライブラリです。
https://github.com/algas/purescript-enchantjs
purescript-enchantjs は PureScript による Enchant.js のラッパーです。Enchant.js を呼び出しているだけなので、ほぼすべての機能は Enchant.js に依存します。PureScript の手習いのために作ってみました。bower のライブラリとして登録してあります。

PureScript の依存ライブラリ

PureScript でライブラリ開発を行うには以下が必要です。

  • Haskell Platform: Haskell の実行環境
  • node.js: JavaScript の実行環境
  • npm: Node.js のパッケージマネージャ(サーバ側)
  • bower: Node.js のパッケージマネージャ(クライアント側)
  • grunt: タスク実行ツール

purescript だけあれば PureScript で書かれたソースのビルドはできますが、ライブラリとして開発するためには JavaScript 開発のためのツールを使うことによって効率よく開発できます。
インストール手順は次項で説明します。

purescript のインストール

Haskell のビルド環境がセットアップしてあるものとします。
Haskell Platform を入れておけば間違いないです。
下記のコマンドで purescript がインストールできます。
cabal install purescript
筆者の環境では purescript 0.5.6.2 を使っています。

purescript-enchantjs の使い方

以下のコマンドで purescript-enchantjs を取得してあるものとします。

git clone https://github.com/algas/purescript-enchantjs.git && cd purescript-enchantjs

  1. node.js + npm のインストール
    nodebrewnvm を使って node.js をインストールしてください。 npm は同時にインストールされるはずです。 インストールはそれぞれのサイトを参考にするとよいです。
  2. bower のインストール
    package.json に書いた設定にしたがって npm を使って bower 関連のライブラリをインストールします。
    npm install
  3. grunt のインストール
    bower.json に書いた設定にしたがって bower を使って grunt をインストールします。
    bower update
  4. ビルドの実行
    Gruntfile.js に書かれたタスクを grunt が実行します。
    grunt main
    これで PureScript で書いたコードが JavaScript (js/index.js) に翻訳されます。
  5. ライブラリおよび画像のダウンロード
    Enchant.js 本体とサンプルアプリで使っている画像を github から取得します。
    wget -O js/enchant.js https://raw.githubusercontent.com/uei/enchant.js-builds/master/build/enchant.js
    wget https://raw.githubusercontent.com/wise9/enchant.js/master/images/chara1.png
  6. 描画確認
    Webブラウザで index.html を開きます。 キャラクターが画面の上部を左右に歩き回っていれば成功です。

どうやって描画されるのか

index.html を見てみましょう。

index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Enchant Example</title>
    <script src="js/enchant.js"></script>
  </head>
  <body style="margin:0; padding: 0;">
    <h1>Hello</h1>
    <script src="js/index.js"></script>
    <script>
      enchant();
      onload = PS.Main.main;
    </script>
  </body>
</html>

上記のように enchant.js と index.js を呼び出していることが分かります。
index.js は grunt によって PureScript からビルドされた成果物です。
enchant(); で enchant インスタンスを生成しています。
onload = PS.Main.mainsrc/Main.purs をページ実行時に呼び出すように記述してあります。
Main.purs は Enchant.js Live Sample の JavaScript を PureScript で書いたものになっています。

purescript-enchantjs を支える技術

FFI (Foreign Function Interface)

PureScript には FFI という機能があり、これを使うことで JavaScript で実装された関数を PureScript の関数として呼び出すことができます。
既存の JavaScript ライブラリの関数を利用したい場合に FFI で関数をラップすることで、再実装せずにそのライブラリを使えます。

開発に使ったライブラリ

  • grunt-init-purescript
    PureScript ライブラリ開発のためのひな形を生成してくれるツールです。依存ライブラリの設定を自動生成してくれます。
    grunt-init-purescript で出力されたファイルを元にして package.json, bower.json, Gruntfile.js を書きます。
  • purescript-easy-ffi
    purescript-enchantjs では Enchant.js をラップするために FFI による関数を大量に記述しています。 purescript-easy-ffi を使うことで記述量を削減することができます。
before-easy-ffi.purs
foreign import log
 "function log(string) {\
 \  return function () {\
 \    console.log(string);\
 \  };\
 \}"
 :: forall r. String -> Eff (console :: Unit | r) Unit
after-easy-ffi.purs
log :: forall r. String -> Eff (console :: Unit | r) Unit
log = unsafeForeignProcedure ["string", ""] "console.log(string);"

思ったこととか

  • PureScript に限らず AltJS 全般に言えることですが JavaScript やその開発環境の知識がないと AltJS による開発できません。
  • 本当はもっと複雑なゲームサンプルを自作しようしていたのですが、状態遷移を記述するのが面倒で今回の記事には間に合いませんでした。 PureScript 力が足りてないようです。
  • purescript-enchantjs を使ってゲームを作ってみたいという奇特な方向けにライブラリを内包していない repository も用意してあります。
  • grunt-watch を使うと自動でビルドが走るようになるから楽かもしれない。

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6