ブロックとボールの接触判定

ボールが移動するたびにブロックとの接触判定を行います。ブロックの総数だけfor()を使って繰り返しボールとの座標値を調べます。接触しているかどうかは前回説明したボールとパドルの接触判定と全く同じです。パドルのかわりにブロックになっているだけです。

ブロックと接触した場合はブロックが破壊されたことになるので、ブロックを消してスコアを加算します。また、ブロックの存在を示すフラグをfalseにし、ブロックが消されたことを示します。このようにフラグを用意しておくことで、繰り返しの先頭でブロックの有無を判断し、存在しない場合はループの先頭に戻って素早く処理が行われるようにすることができます。ブロックがを1つ壊すごとにカウンタを増やし、ブロックの総数と同じになったら再度ブロックを生成しゲームを続けるようにします。

特定の座標より大きい場合にはブロックとの接触判定をしないようにし高速化することもできますが、ここでは高速化に関しては一切行っていません。また、ラウンド制にするのもよいでしょう。一回でもミスをするとゲームオーバーになってしまうので持ち玉制にしてプレイヤーを楽しませる方法もあります。

ブロックとボールが接触するとブロックが破壊される

ボールが画面下に落ちるとゲームオーバーになる。持ち玉制に改良する方法もある

コード02

        function checkBlock(){
            for(var i=0; i<total; i++){ // ブロックの数だけ繰り返す
                if (!blockFlag[i]) continue;    // ブロックがない場合は繰り返しの先頭に戻る
                if ( ((ballX + ballW) >= blockX[i]) && (ballX <= (blockX[i] + blockW)) && 
                    ((ballY + ballH) >= blockY[i]) && (ballY <= (blockY[i] + blockH)) ) {   // ボールがブロックに当たった
                        blockFlag[i] = false;   // ブロックを消す
                        document.getElementById("blk"+i).style.visibility = "hidden";   // ブロックの表示も消す
                        dy = -dy;   // 移動方向を反転させる
                        score = score + 1;  // スコアを加算
                        document.getElementById("score").innerHTML = score+"点";
                        count++;    // カウンタを増やす
                        if (count == total){    // 全てのブロックを消した
                            drawBlock();    // 再度ブロックを描画しゲームを継続する
                        }
                }
            }
        }

ブロックを描画

ゲーム開始時とステージをクリアした時に呼び出されるのがブロックの描画関数であるdrawBlock()です。ここでは横に9つ、縦に5つブロックを生成しています。for()の中の5と9の数字を変更すれば好きな数のブロックを描画できます。ただし、画面外にはみ出してしまうとボールでは破壊できなくなるので、必ず画面内に収まるようにブロックを生成し配置する必要があります。表示する座標はスタイルシートで設定し絶対座標値とします。この座標値は接触判定で使えるように配列変数blockX, blockYにも入れておくようにします。

コード03

        function drawBlock(){
            var txt = "";
            total = 0;  // ブロックの総数を0にする
            for(var j=0; j<5; j++){ // 縦5個
                for (var i=0; i<9; i++){    // 横9個
                    var bx = i * 32 + 16;   // 横の表示位置を求める
                    var by = j * 20 + 40;   // 縦の表示位置を求める
                    blockX[total] = bx; // ブロックのX座標を配列変数に入れる
                    blockY[total] = by; // ブロックのY座標を配列変数に入れる
                    blockFlag[total] = true;    // ブロックの存在を「有り」にする
                    txt += '<img src="images/block.gif" width="24" height="8" style="position:absolute;left:'+bx+'px;top:'+by+'px;" id="blk'+total+'">';
                    total++;    // ブロック数を増やす
                }
            }
            document.getElementById("gameScreen").innerHTML = txt;
            count = 0;  // カウンタをリセット
        }