読者です 読者をやめる 読者になる 読者になる

elmを使ってゲームを作ってみた

まとめ

  • elmlangを使って、10年ぐらい前にガラケーでこんなゲームをやっていたという記憶を元に簡単なゲームを作ってみた
  • Haskellっぽいけど、そんなにHaskell書けなくても問題ない
  • html、css、およびjsに関する知識が必要ないので簡単に作れる
  • コンパイルのエラーも丁寧でシンプルなので、英語がそんなに得意じゃなくてもできる
  • ゲームをつくる場合はSignal(通常のページならAddress)を知る必要がある

背景

  • elmlangのversionが0.16になり、かなり使えるようになってきたという噂をきいたので、なんか作ってみたかった
  • jsを長い間触っていなかったので、リハビリがしたかった(結果的にjsを触ることはなかった)

目的

  • 単純なゲームをつくることでelmlangでの開発を一通り体験する

実装

  • 準備

elmlangのversionは0.16

単純に公式のライブラリを使って1ファイルを生成するだけなら下記を知っているだけで大丈夫

# npmでインストールできる
$ npm install -g elm
# 下記のコマンドでelmファイルからhtmlを生成できる
$ elm-make main.elm --output=main.html
  • ソース

ぱっと見てわかりにくいかなというところだけ載せておきます

残りはこちらで確認してください

delta = Signal.map Time.inMilliseconds <| Time.fps 30

input : Signal Input
input =
  Signal.sampleOn delta <|
    Signal.map4 Input
      Keyboard.space
      Keyboard.arrows
      initialSeed
      delta

上記のコードでは30fpsのタイミングでキーボードのspaceや矢印を取得して、状態の更新に利用しています。Signalはリストとして扱うことはできないのでmap、map2...map5まで用意されています。上記のコードでは4つのシグナルをまとめています

elmには関数宣言でのパターンマッチがないので、空リストの場合などはcase文でかく必要があります

viewMoji : Moji -> Form
viewMoji ({x, y, char, scolor}as moji) =
  text (Text.fromString char |> Text.color scolor)
    |> move (x, y)
    |> scale 4

上記のコードにある"|>"は"x |> f = f x"という意味なので、表示させる要素の色や大きさなど複数指定していく時に便利です。逆の"<|"もあります

Signalの(~)と(<~)ですが、version0.16で削除されているので使えません。私はこれで結構時間を使ってしまいました(importの仕方が違うのかとか調べていました) remove (~) and (<~)

ゲーム

  • 動作はchromeでしか確認していません
  • このページだと矢印キーでページが動いてしまうので、別ページで開いて遊んでみてください

URL

遊び方
  • キーでスタート
  • restartは未実装
  • 黒い文字は文字の示す方向の矢印キーを押す

"右"なら→、"下"なら↓

  • 赤い文字は流れているラインの方向を押す

一番左を流れる文字は←、真ん中は⇣

文字が上でも赤色で左のラインを流れていたら、←を押す

問題点

  • キーが押されている間は継続的にSignalが発行されてしまう -> 同じ方向の入力が連続するときに一回押すだけですべて処理されてしまう

おそらくChangeかキーが押されたときのSignalとmergeすればいいはずだが、まだ実装はできていない

  • ゲームのレベルが上がった時の文字の流れる速度がうまく調整できていない

うまく調整できる計算式があれば、ちゃんとしたゲームっぽくなると思う

  • ソースが汚い

Haskellもそんなに書けないし、elmlangも1日しか触っていないので無駄が多いコードになってると思います(是非、助言や疑問点があったら指摘をしていただきたいです)

参考