ブラウザゲームを作ってみよう(その8:サンプルゲーム作成その1)

# はじめに
[その7](https://qiita.com/noji505/items/df0e7e8589a0b8ed9206)では当たり判定処理を行いました。
今回は今までのものを組み合わせて簡単なサンプルゲームを作ってみたいと思います。

# サンプルゲームイメージ
![img01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/cd4d00c0-8728-7cf7-6fd7-be407aa6d134.png)

これが今回作成するゲームのイメージになります。
それぞれの要素の詳細は以下です。

| No | 内容 | 説明 | 画像イメージ |
|:-:|:-:|:--|:-:|
| 1 | 雲 | 操作するメインキャラクターです  | ![00_kumo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/1ff88e50-0532-64ec-0276-f2603666d36f.png) |
| 2 | コイン | 上から降ってくるので雲を操作して集めます  | ![01_coin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/67c29cd1-3d0b-6253-8a01-d06589967841.png) |
| 3 | スコア | コインを取ると加算されます  |   |
| 4 | ライフ | ライフです<br>コインを取り損なうと減ります  | ![02_life.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/6ddc6215-2d33-9c6c-dca9-88bce7998fb8.png) |

# ゲームのルールについて
先ほどのイメージで何となく想像がつくかと思うのですが、大まかなルールは以下となります。

1.画面上部からコインがランダムで降ってくる
2.左右キーで雲を動かしてコインを取る
3.コインを取るとスコア加算
4.コインを取りそこなって画面下まで落ちるとライフが減る
5.ライフが0になると終了

# ゲームのサイクルについて
ゲームのメイン部分は以上で説明が出来たので、次はサイクルについて考えたいと思います。
今回のサンプルでは主にこのサイクルの部分を作っていきます。

サイクルのイメージ
![img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/6a2a72cd-68f0-cd0e-216e-222263fe6946.png)
1.タイトル画面・・キー入力でゲームメイン画面へ
2.ゲームメイン画面・・ライフが0になったらゲーム結果画面へ
3.ゲーム結果画面・・キー入力でタイトル画面へ

それぞれの画面毎に予めソースコードを分けておくと管理しやすいです。

```javascript:main.js

//=======================================================================================
//  ゲームループ※ここの処理が常に実行されます
//=======================================================================================
var gameState = 0;   // ステータス(0:タイトル画面、1:ゲームメイン画面、2:ゲーム結果画面)

function gameLoop()
{
    switch( gameState ){
    case 0:
        titleMainLoop();
        break;

    case 1:
        gameMainLoop();
        break;

    case 2:
        gameResultLoop();
        break;
    }
}
```

```javascript:title.js

//=======================================================================================
//  タイトル画面
//=======================================================================================

// タイトル画面初期化
function titleInit()
{
    // ※タイトル画面開始前に初期化する場合はここに記述
    gameState = 0;  // タイトル画面ループへ
}

// タイトル画面ループ
function titleMainLoop()
{
    if( keyTrg == KEY_SPACE ){
        gameInit();  // ゲーム画面初期化へ
    }
}

```

```javascript:game.js
//=======================================================================================
//  ゲーム画面
//=======================================================================================

// ゲーム画面初期化
function gameInit()
{
    // ※ゲーム画面開始前に初期化する場合はここに記述
    gameState = 1;
}

// ゲーム画面ループ
function gameMainLoop()
{
    // ゲームのメイン部分を記述

    // ※ライフが0になったらゲーム結果画面初期化を実行
}
```

```javascript:result.js
//=======================================================================================
//  ゲーム結果画面
//=======================================================================================

// ゲーム結果画面初期化
function resultInit()
{
    // ※ゲーム結果前に初期化する場合はここに記述
    gameState = 2;    // ゲーム結果画面ループへ
}

// ゲーム結果画面ループ
function resultMainLoop()
{
    if( keyTrg == KEY_SPACE ){
        titleInit();  // タイトル画面初期化へ
    }
}
```
各画面毎に「初期化」と「ループ」がそれぞれセットになっているのが分かるかと思います。
ループに入る前に初期化を入れることで、準備を挟むことが出来るので例えば
■ゲーム結果画面でリトライを選択するとタイトル画面に行かずにすぐにゲーム開始させたい

といった仕様変更があった場合でも、すぐに対応出来ます。

# サンプル

今回のサンプルは下記になります。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGaEOzL" data-user="noji505" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/noji505/pen/bGaEOzL">
  Qiita19_sample01(ゲームサンプル)</a> by nojima (<a href="https://codepen.io/noji505">@noji505</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※スペースキーで各シーンへ遷移します。


# 最後に
今回のようなシーン管理は基本的にどのようなゲームでも作成することになるので雛形的に使えると思います。
次回はゲームのメイン部分を作っていきたいと思います。