canvas上で群れを表現

# 前置き
プログラミング初心者のため、見苦しいコードが多いです。プログラムを組んで何か作るの好きです！

※ 2020/10/30追記
Pythonでボイドを利用したゲームを作ってみたので良かったら見てください。

- <a href="https://solo-engineer.tech/python/how-to-make-mygame/">【Tkinter実践】Pythonでオリジナルゲームを作る</a>

# 生き物に関するプログラミングがしたい！
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/430a5611-edbb-a132-4818-91b0547d6989.jpeg)

小さいころから生き物が好きだった。プログラミングで生物の行動シュミレーションなど出来たら面白そうだ。
調べたらボイドというアルゴリズムを見つけた。

# ボイドって？
![img_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/41c49528-e5ce-145c-82b5-adc81c62dd69.jpeg)

> ボイド(Boids)は、アメリカのアニメーション・プログラマ、クレイグ・レイノルズが考案・作製した人工生命シミュレーションプログラムである。名称は「鳥もどき(bird-oid)」から取られている。

wikipediaからの引用。コンピュータ上に鳥オブジェクトを作成し、それに対して以下の**3つのルール**を作用させるだけで、鳥の群れを再現出来るというアルゴリズムのようだ。

## １．**結合(Cohesion)**

<img width="450" alt="cohesion.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/2cfc8fe6-caa5-9c6e-e6bf-3b701a0267c7.png">

群れの個体の全ての座標からそれらの中心位置を求め、個体全てがそこへ向かうようにする。

## ２．**分離(Separation)**

<img width="450" alt="separation.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/1b8ee3c1-5dda-374c-8c9e-a8c80d9e6d09.png">

個体同士がある一定の距離を常に取るようにする。

## ３．**整列(Alignment)**

<img width="452" alt="alignment.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/a4b17b4a-3bd1-9d69-dc04-f1ae378863fa.png">

群れの個体全ての速度ベクトルを群れの速度ベクトルに合わせる

# 流行りのHTML5 + Javascriptで実装
## 今更だけどHTML5ってすごい！
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/7921c463-00ad-7b73-a18b-2c0d9a6d8f52.gif)

canvasの登場で本当に便利になりましたね。
一回だけFlashコンテンツ作ったことがあったけれども、今では全く見られなくなりましたね。おも〇ろムービーズなつかしい。ウォーリーをさがさないでなど好きでした。

## 参考サイト
前にチョロッとjsを触ったことがあるんですが、調べてみると色々変わったらしいので

- <a href="https://qiita.com/shibukawa/items/19ab5c381bbb2e09d0d9">イマドキのJavaScriptの書き方2018</a>

こちらの記事を参考にさせて頂きました。

## 鳥ではなくボールで

鳥オブジェクトをcanvas上に描くことも考えたのですが、まずは慣れてからにしようと思って、今回はボールオブジェクトにしました。また今度、鳥オブジェクトを作ってみたいなと思います。

<p class="codepen" data-height="438" data-theme-id="dark" data-default-tab="js,result" data-user="lizard_nest" data-slug-hash="zYYxqYP" style="height: 438px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="BallBoids">
  <span>See the Pen <a href="https://codepen.io/lizard_nest/pen/zYYxqYP">
  BallBoids</a> by hoihoi (<a href="https://codepen.io/lizard_nest">@lizard_nest</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 色々な動き
ボイドは上記の通り結合、分離、整列の3つのルールを適用することで鳥の群れの様な動きを得ることが出来ました。しかし、ルールを減らしてみても、面白い動きを得ることが出来ました。試しに以下の場合のように減らしてみます。

<table>
<tr><td>-</td><td><b>結合</b></td><td><b>分離</b></td><td><b>整列</b></td></tr>
<tr><td>場合①</td><td>〇</td><td>×</td><td>×</td></tr>
<tr><td>場合②</td><td>〇</td><td>〇</td><td>×</td></tr>
<tr><td>場合③</td><td>×</td><td>〇</td><td>×</td></tr>
<tr><td>場合④</td><td>×</td><td>〇</td><td>〇</td></tr>
</table>

## 場合①（結合）
![sepaonly.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/a6a727de-33b3-e0f2-b687-15608ea18d16.gif)
分離と整列のルールを無くすと、ボールは群れの中心にのみ向かいます。
そのため、群れ全体が近づいてきてしまうと、群れの中心も一定になってきてしまうため、時間がたつと塊のようになってしまいますね。何故かDS版どうぶつの森のハチを思い出しました。

##場合②（結合、分離）
![sepacohe.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/043ddd84-e88b-84a7-3982-cae42482f44a.gif)
これは一見3つのルールを適用したボイドと似ていますが、整列していない所為で群れ全体にまとまりがないですね。群れの外側の個体を見ると違いが分かりやすいです。

## 場合③（分離）
![sepaonlygati.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/445abca8-a0f7-f7a3-e330-485e1a90eb3e.gif)
分離ルールは言ってしまえば、ボールとボールの当たり判定と同じ意味のため、ただボールが他のボールとぶつかったら反射するという動きを繰り返していますね。もはや、群れを形成出来ていないです。
## 場合④（分離、整列）
![aligncohe.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454421/28222ec3-9e3d-f318-bcba-a644cdd6de2d.gif)
群れ全体が外枠である正方形型になっていますね。整列のおかげで群れ全体の速度ベクトルは合わせられているので、群れとしての形は成しています。外枠が円とかだったら円形の群れを形成するのかな？

# 最後に
ボイドはゲームなどでも群れを再現するために使われていたりするそうです。そのぐらい現実の鳥の群れの動きに近いのでしょうね。
駄文ですが、読んで頂きありがとうございました。