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

# はじめに
[その9](https://qiita.com/noji505/items/edb878521df9df0902da)ではゲームのメイン部分の作成を行いました。
今回は前回作成したメイン部分を改善してみたいと思います。

# 改善ポイントについて
色々あると思うのですが、現状のゲームのルールを変えないという前提で改善するとなると、以下のようなものが考えられると思います。

■プレイヤー(雲)の動きが一定速度にしか動かない
■コインの出現タイミングが常に一定
■コインの出現枚数が1枚ずつしか出てこない

上記を改善することで、ゲームにメリハリが生まれると思います。


# 改善してみよう

まずは雲の移動処理を変更します。
ソースコードは以下となります。

```javascript:雲の移動処理変更

// 変数宣言
var kumoX;
var kumoY;
var spd;        // 移動速度
var spdCount;   // 移動カウント
var KUMO_WIDTH = 32;
var KUMO_HEIGHT = 16;

// 雲の移動、表示処理
var playerMove = 0;   // プレイヤーの移動方向(0:移動無し、1:左移動、2:右移動)

// カーソルキー入力で雲移動
if( (keyPress & KEY_LEFT) != 0 ){
    playerMove = 1;
}

if( (keyPress & KEY_RIGHT) != 0 ){
    playerMove = 2;
}
// 動いていない
if( playerMove == 0 ){
    if( spd < 0 ){    // 左移動中
        spdCount++;
        if( spdCount % 2 == 0 )    playerMove = 2;
    }
    if( spd > 0 ){    // 右移動中
        spdCount++;
        if( spdCount % 2 == 0 )    playerMove = 1;
    }
}
// 左移動
if( playerMove == 1 ){
    spd--;
    if( spd <= -5 ){
        spd = -5;
    }
}
// 右移動
if( playerMove == 2 ){
    spd++;
    if( spd >= 5 ){
        spd = 5;
    }
}

if( spd != 0 ){
    kumoX += spd;
    if( kumoX < 0 ){    // 壁判定
        kumoX = 0;
        spd *= -1;
    }
    if( kumoX >= SC_W - KUMO_WIDTH ){    // 壁判定
        kumoX = SC_W - KUMO_WIDTH;
        spd *= -1;
    }
}

// 雲表示
drawImage( img[0], kumoX, kumoY );

```

■変更点ポイント
* キー入力時、いきなり移動させるのではなく変数(playerMove)にセットし、その値で移動させるように変更
* 移動速度を段階的に上げるように変更
* 移動中にキーが離された場合は移動を止めるのですが、「移動方向に対して逆向きに操作されたことにする」(左なら右、右なら左)という処理にすることで実現
この時の移動処理を変数によって処理しているため、上述したplayerMove変数に値をセットするだけで実現することが出来ています

# 雲移動サンプル

変更したサンプルは以下になります。
また比較しやすいように、前回の挙動のサンプルも下に載せていますので比べてみて下さい。

[変更後のサンプル]
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNpGJeE" 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/rNpGJeE">
  Qiita21_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>

[変更前のサンプル]
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="jOYGZre" 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/jOYGZre">
  Qiita21_sample02(雲移動)</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>


# コインの出現間隔、枚数を変更
では続いて、コインの出現間隔と枚数を変更してみます。
出現間隔や枚数を変更するタイミングはコインを取って点数が増えたタイミングとします。
(例:10枚・・出現間隔が短くなる、20枚・・2枚ずつ出現する等)

ソースコードは以下となります。

```javascript:コインの出現間隔、出現枚数変更

// 変数宣言
var coinShowNum = 1;        // コイン出現枚数
var oldScore = 0;           // 一つ前のスコア

// コイン出現処理
coinShowCount++;
if( coinShowCount >= coinShowTimer ){
    for( var i=0; i<coinShowNum; i++ ){  // コイン出現枚数分ループ
        for( var j=0; j<coinX.length; j++ ){
            if( !isCoinShow[j] ){
                coinX[j] = getRand( 0, SC_W-COIN_WIDTH );
                coinY[j] = -16;
                isCoinShow[j] = true;
                break;
            }
        }
    }
    coinShowCount = 0;
}

// スコアが変更されたときに処理
if( score != oldScore ){
    oldScore = score;

    if( score == 5 ){
        coinShowTimer = 40;  // コイン出現タイマー更新
    }
    if( score == 10 ){
        coinShowNum = 2;     // コイン出現数更新
    }
}
```

■変更点ポイント
* コイン出現処理の際に、コイン出現枚数分ループし複数枚同時に出現出来るように変更
* スコアが加算された際に、スコアの値をチェックしコインの出現タイマーや出現数を更新する処理を追加
→1フレーム前のスコアと現在のスコアの値を比較し、異なったときに処理をすることで
「スコアが加算された時に一回だけ処理を行う」という処理を行うことが出来ます。

# コインの出現間隔、出現枚数変更サンプル

変更したサンプルは以下になります。

変化がすぐに分かるように
5点・・コインの出現間隔が半分になる
10点・・コインの出現枚数が2枚になる
としています。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEvXRQP" 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/ZEvXRQP">
  Qiita21_sample03(コイン出現数変更)</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>


# サンプル更新

今回の変更点を全て反映したサンプルは以下になります。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="abELKGN" 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/abELKGN">
  Qiita21_sample04(コインゲット02)</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>


# 最後に
今回行った改善は主にゲームのバランス調整なのですが、自分で作って自分でテストしていると上手くなってしまい、難易度が上がりがちになります。
なので、出来ることなら身近な人に第三者の目線でテストプレイをしてもらう等をして調整すると良いと思います。

次回はこのサンプルを使って別の機能を追加してみたいと思います。