Elmで時間をかけずにゲームを作る

# こんなものを作りました
![スクリーンショット 2019-12-21 7.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/020c12d6-edd6-fdb7-4033-709d97b0cecf.png)

https://ellie-app.com/7vPS6v6h2Y8a1
コロコロする四角形をゴールに導くだけのシンプルなゲームです。
作る過程で学んだことを共有したいと思います。

### 何分くらいで作ったのか？
全然、何分とかじゃないです。
何日も何日もやってました...。

### じゃあタイトル嘘じゃねえか
はい、その通りです...。
時間をかけずに作るつもりでしたが、時間がかかってしまいました...。
ですが、時間がない中で作るための工夫はしていました。

# 時間がない中で作るために

### パッケージを活用する
1から全てを自分で作ると時間がかかるだろうと考え、公開されているパッケージを活用することにしました。
https://package.elm-lang.org/
ここから**game**で検索してHitしたものを一通り眺めたうえで、一番シンプルそうだった[elm-playground](https://package.elm-lang.org/packages/evancz/elm-playground/latest/)を使うことにしました。

### 絵を描かない
elm-playgroundを使うと簡単にSVGの図形を描画できますので、ゲームにはこれを使いました。

### スマホでもPCでも作る
通勤電車の中でも開発できるように、スマホでも開発できるように[ellie](https://ellie-app.com/7vPS6v6h2Y8a1)を使いました。

### コンパイルエラーを恐れずに改造
まとまった時間がとりづらかったので、コンパイルエラーのまま保存とかしょっちゅうやっていました。
Elmのコンパイルエラーのメッセージが親切なこと、パターンマッチや型で守られていることによって、安心してぶっ壊すことができました。

# elm-playgroundのポイント

### pictureとanimationは練習
[PackageDocs](https://package.elm-lang.org/packages/evancz/elm-playground/latest/)を見ると、最初にこの2つの関数が登場しますが、これはゲームには使いませんでした。
ゲーム作りの前段の練習用、または、絵を描いたりアニメーションしたりということを目的とする場合に使うと良さそうです。

picture
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#picture) / [Demo](https://ellie-app.com/7pYm2Cjmwhda1)

animation
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#animation) / [Demo](https://ellie-app.com/7pYxbqjHFQJa1)

### gameが本命
game関数は、The Elm Architecture(以下TEAと呼称)と同じような感覚で扱えます。
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#game)

```elm:サンプルコード抜粋
main =
  game view update 0
```

`view`
TEAで言うviewと同じと考えて良いです。

`update`
こちらもほとんどTEAと同じように考えて良いです。
TEAと異なる特徴としては、毎秒60回(60fps)updateが呼び出されること、Msgが渡せないことでしょうか。

`0`
第三引数のコレは、[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#game)には`memory`と書いてあります。
`memory`とは何かというと、TEAで言うmodelです。
サンプルではシンプルにするために0にしているようでしたが、ここがレコードでも良いわけです。

### Shape型
描画する関数はShape型を返します。
Shape=絵と捉えて良いでしょう。
文字を表示するwords関数の結果もShapeとして扱われます。
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#Shape)

### move関数
アニメーションみたいに動かすという意味ではなく、Shapeの座標を指定するために使います。
座標を指定しないと、すべて画面の中央(0,0)に配置されます。
なんで中央が(0,0)なのよと思いましたが、スマホでもPCでも中央に表示されるのがメリットだと感じました。
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#move)

### その他のShapeを扱う関数
大きさを変えるscaleや、角度を変えるrotateなどがあります。
数はあまり多くないので、一通り試してみると良いかもしれません。
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#scale)

### Computer型
マウス、キーボードからの入力を扱ったり、画面のサイズを取得したりします。
viewやupdateに自動的に渡されます。
[Document](https://package.elm-lang.org/packages/evancz/elm-playground/latest/Playground#Computer)

# ゲームプログラムの構造
updateの中が複雑になりやすいのですが、私の作ったゲームではこのようにしました。
これらが毎秒60回行われています。

1. マウス入力状態を取得
マウスがクリックされていたらジャンプするので、y方向への移動量にマイナス値をセットします。

1. キャラクターの移動
キャラクターは勝手にコロコロ転がるので、x方向に移動します。
ジャンプや重力によってy方向に移動します。
移動した結果、壁やブロックにぶつかるかもしれませんが、一旦移動しちゃいます。

1. 当たり判定
壁やブロックにぶつかったかを判定して、ぶつかっていたら、めりこまないよう、キャラクターを移動します。

# 感想
結局何日もかけてゲームを作ってしまいましたが、その大半は、当たり判定など、ゲームそのものの作り込みの時間でした。
覚えることが少ないので、あまり時間をかけずにゲーム作りに取りかかれます。
Elmの文法入門にも適していると思いますので、Elm未経験の方も気軽に試してみてはいかがでしょうか。
[Elmの入門ガイドはこちら](https://guide.elm-lang.jp/)


# 余談:elm-playgroundに決めるまでの記録

<details><summary>ダラダラ長いので折りたたんであります</summary>
<div>

elmで作られたゲームはどれくらいあるのか、どういう作りをしているのかを知りたくて、まずは探しました。

### Google検索
https://github.com/rofrol/elm-games
elm game
でGoogle検索したら、真っ先にHITしたのがこれです。
elm製のゲームのリンク集のように見えます。

その親元のリポジトリがこちら。
https://github.com/rofrol/awesome-elm-gamedev/blob/master/README.md#list-of-games

### youtube検索
elm game dev で検索したところ、カンファレンスでの発表動画らしきものがHITしました。
じっくり見たいところですが、今回の時間をかけずにという主旨から外れそうなので見ませんでした。

### Github検索
githubで検索したらたくさん出てきました。
https://github.com/search?utf8=%E2%9C%93&q=elm+game

### ゲームが集まっているサイト
https://itch.io/
いくつかのゲームはここに登録されたものであることに気づきました。
PlayGameボタンを押すと、フルスクリーンモードに勝手にしてくれて便利そう。
このサイト内で「elm」で検索したら、elm製のゲームがいくつか出てきました。

### elm packages からgameで検索してHITしたパッケージたち
https://package.elm-lang.org/packages/Orasund/elm-game-essentials/latest/
https://package.elm-lang.org/packages/Orasund/pixelengine/latest/
マス目（grid）状の2Dゲームに特化したパッケージのようです。
サンプルが豊富で、こんなことができるんだ～とワクワクしました。

https://package.elm-lang.org/packages/Zinggi/elm-2d-game/latest/
WebGLをElmで簡単に扱えるようにするためのパッケージっぽいです。
2Dゲームに狙いを絞っている模様。

https://package.elm-lang.org/packages/justgook/elm-game-logic/latest/
[ECS](https://ja.m.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3%E3%83%BB%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%83%BB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)(Entity-Component-System)というゲーム開発のパターンをElmでやるためのパッケージのようです。
これ使えば簡単にゲームができるよ！という系のものではなさそう。
サンプルがないのでよくわからず。

</div></details>