enchant.jsでブロック崩しを作った時の躓いたポイント

# enchant.jsを使ってブロック崩しを作る

過去に自分が書いたソースコードは[こちら](https://github.com/toshiki-tosshi/breakout/)
動作は[こちら](http://gravity-breakout.herokuapp.com/)から確認することができます。

## 開発環境
MacOS Catalina 10.15.1
enchant.js v0.8.3
Google Chrome: 78.0.3904.108

## はじめに
当記事はHTML5とJavaScriptのフレームワークである`enchant.js`を使ったブロック崩しについて纏めた記事です。このフレームワークはゲームを簡単に作ったり、シミュレーションを行ったりできます。今回は物理シミュレーションを行う世界の`enchant.box2d.PhysicsWorld`クラスを扱います。尚、過去に自分が書いた[こちら](https://github.com/toshiki-tosshi/breakout/)のソースコードを基に解説します。

## この記事を書いた主な理由
- 自分の備忘録として、また友人に教わりながら実装したので、**他の人へ理解の輪を広げるため**。
- enchant.jsを利用した作品例があまり見つからなかったため。

## 開発時の問題点・困難だった点
- 公式documentを読むことへの抵抗があったのと、その読み方が分からなかったために実装が難しかったこと
- enchant.jsの理解が曖昧だったこと
- そもそもコーディングに慣れていなかったこと

## 定義した関数
プログラム内で定義した関数名・役割を以下に列挙します。引数の意味や使用例についてはソースコードをご覧ください。
何をやりたいのかを考えてからその動作をする関数を確認し、それを参考に実装するのも1つの方法だと思います。
尚、関数がそれぞれどの動きを表すのかを数字と紐付けて番号を振ったので参考にしてみてください。

<img width="1680" alt="enchantjs.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296499/672b4ed2-ba62-90ef-83dc-769c014b2b1b.png">

```javascript:main.js
1. function createScoreLabel(size_and_font, color, x, y)
// スコアラベル作成
2. function createHelpLabel(size_and_font, color)
// ヘルプラベル作成
3. function createGameScene()
// ゲームのシーン作成
4. function createBall(ball_num, x, y, dx, dy)
// ボール作成
5. function createItem(radius, x, y, dx, dy)
// アイテム作成
6. function createWall(width, height, friction, restitution, x, y)
// 壁作成
7. function createBlock(block_num, col, row)
// ブロック作成
8. function judgeObj(ary)
// 引数にオブジェクトの配列を取り、オブジェクトと何か(例えば、画面下の衝突判定(削除判定)等)を行います。
```
シーン系

```javascript:main.js
// スタート時
function createStartScene()
// クリア時
function createClearScene()
// 失敗時
function createFalseScene()
// ステージクリアと次ステージの間
function createRestScene()
// クリア後
function createEndScene() 
// ポーズボタンを押した時の一時停止期間
function createPoseScene()
// シーン変更
function replaceScene(createStartScene())
```

## 主に自分が躓いたポイント

以下の各ポイント・セクション毎に説明していきます。

- sprite(オブジェクト)の違い
- 衝突判定とオブジェクトの除去
- 画面サイズの取得(おまけ)

### Sprite(オブジェクト)の違い
enchant.jsには`Sprite`オブジェクトと`PhySprite`オブジェクトがあります。当初私は`Sprite`と`PhySprite`は同一世界で扱えるものだと認識していました。しかし、衝突判定を実装している時に、画面からは消えるのにオブジェクトが消えない理由が分かりませんでした。その原因を探っていった結果、この勘違いが原因でした。`Sprite`はただのオブジェクト、`PhySprite`は物理シミュレーションで扱うオブジェクトであることを確認してください。

### 衝突判定とオブジェクトの除去
下記の`judgeObj(ary)`関数は引数にオブジェクトのリストを受け取って、カーソルより下になったオブジェクトを削除します。`object.destroy()`だけだと、要素としては消えますが、衝突判定は残ってしまっています。そのために`scene.removeChild(object)`でシーンから除去する必要があります。

```javascript:main.js
function judgeObj(ary) {
    for (var i = 0; i < ary.length; i++) {
        if (ary[i].y > game.height) {
            ary[i].destroy();
            scene.removeChild(ary[i]);
            ary.splice(i, 1);
        }
    }
}
```

### 画面サイズの取得(おまけ)
これは**enchant.js**とは関係ありませんが、画面サイズに合わせて何かを配置したい時やレスポンシブ対応をしたい場合は以下の方法で取得することができます。

```javascript:main.js
// 縦の長さ
window.innerHeight;
// 横の長さ
window.innerWidth;
```
以上です。細かい箇所に関しては[公式ドキュメント](https://wise9.github.io/enchant.js/doc/plugins/ja/symbols/enchant.box2d.PhysicsWorld.html)を読めば書いてあると思います。

# おわりに
この記事が誰かの疑問の解消になれば良いなと思います。また、あくまでこれは1記事です。実装する際はこの記事ではなく**公式ドキュメント**を参考にしながらコーディングすることを強くお勧めします。

## 参考
[enchant.js 公式ドキュメント - Class enchant.box2d.PhysicsWorld](https://wise9.github.io/enchant.js/doc/plugins/ja/symbols/enchant.box2d.PhysicsWorld.html)