背景の移動処理

今回はブロック崩しと異なり背景画像を用意してあります。宇宙空間の背景画像を

タグに適用します。 背景画像の移動処理ですが表示位置を示す変数bgYに値を加算し、その値を背景画像のY座標に設定します。これだけで自動的に背景が延々と下に移動することになります。デフォルトのスタイル設定では背景画像は上下左右にタイル状に敷き詰められますから、このようにするだけで背景画像が切れ目なく表示され移動させることができます。 背景画像のサイズには制限がありませんが、基本的に横幅は320ピクセルにしておきます。縦幅は自由です。大きめの画像にしておき星雲や星団などを描けば、より雰囲気が出るでしょう。

コード07

        function moveBG(){
            bgY = bgY + 2;  // 2ピクセルごと背景画像を下に移動
            document.body.style.backgroundPositionY = bgY;
        }

最後に

今回は少し長めのプログラムですが、敵が弾を発射するように改造したり、ステージ制にし難易度を変化させていくのもよいでしょう。実際のビデオゲームではスペースインベーダーから、進化していく過程をたどります。どのように進化していくのかは以下のリンクでたどってみると面白いかもしれません。

・スペースインベーダー

・ギャラクシアン

・ギャラガ

・ギャプラス

*なお、このプログラムは自由に改造して配布しても問題ありません。適当にプログラム書き換えて楽しんでください。

完成したプログラムコード

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta name="viewport" content="initial-scale=1, user-scalable=no">
    <title>Space Insect</title>
    <style type="text/css"><!--
        body { background-color: #000000; background-image:url(images/bg.gif) }
        #gameScreen { position:absolute; left:0px; top:0px; width:320px; height:356px; }
        #gameForm { position:absolute; left:50px; top:170px; z-index:10; }
        #gameForm input { font-size:24pt; z-index:10; }
        #score { position:absolute; left:4px; top:2px; color:#ffffff; }
        #laser { position:absolute; left:10px; top:-50px; color:#ffffff; }
        #fighter { position:absolute; left:4px; top:260px; color:#ffffff; }
    --></style>
    <script type="text/javascript"><!--
        // ===============================================
        // 初期設定
        // ===============================================
        var laserX = -10;   // レーザーのX座標
        var laserY = -50;   // レーザーのY座標
        var laserW = 3; // レーザーの横幅
        var laserH = 20;    // レーザーの縦幅
        var dy = -10;   // レーザーの縦の移動量
        var fighterX = 1;   // 自機のX座標
        var fighterY = 260; // 自機のY座標
        var fighterW = 24;  // 自機の横幅
        var fighterH = 24;  // 自機の縦幅
        var fighterDx = 8;  // 1回の自機の移動量
        var pointX = 0;
        var enemyFlag = new Array();    // 敵の有無を示すフラグ
        var enemyX = new Array();   // 敵のX座標
        var enemyY = new Array();   // 敵のY座標
        var enemyW = 24;    // 自機の横幅
        var enemyH = 24;    // 自機の縦幅
        var total;  // 敵の総数
        var count;  // 消した敵をカウントするための変数
        var bgY = 0;    // 背景画像のY座標
        var patDX = [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0, 0, 0, -1, -2, -3, -4, -5, -6, -5, -4, -3, -2, -1, 0, 0, 0 ];
        var patCount = 0;
        // ===============================================
        // 自機の位置を設定するためのイベントを設定
        // ===============================================
        window.addEventListener("load", function(){ // ページ内容が読み込まれたらイベントを設定
            document.addEventListener("touchmove", function(){
                event.preventDefault(); // デフォルトのイベントを禁止する
                fighterX =event.touches[0].pageX - fighterW / 2;    // タッチされた横位置を取得し自機の座標とする
                document.getElementById("fighter").style.left = fighterX;   // 自機を指定したX座標に表示する
            }, false);
            drawEnemy();    // 雰囲気を出すために敵を描画する
        });
        // ===============================================
        // レーザーを発射する
        // ===============================================
        function startLaser(){
            laserX = fighterX + 10;
            laserY = fighterY;
        }
        // ===============================================
        // レーザーを移動させる
        // ===============================================
        function moveLaser(){
            if (!gameFlag) return;  // ゲーム中でなければ処理しない
            laserY = laserY + dy;   // レーザーを縦方向に移動させる
            document.getElementById("laser").style.left = laserX;   // レーザーを指定したX座標に表示する
            document.getElementById("laser").style.top = laserY;    // レーザーを指定したY座標に表示する
            hitEnemy(); // 敵との接触判定
            if (laserY< -laserH) startLaser();  // レーザーを再度発射する
        }
        // ===============================================
        // 敵とレーザーとの接触判定
        // ===============================================
        function hitEnemy(){
            for(var i=0; i<total; i++){ // 敵の数だけ繰り返す
                if (!enemyFlag[i]) continue;    // 敵がいない場合は繰り返しの先頭に戻る
                if ( ((laserX + laserW) >= enemyX[i]) && (laserX <= (enemyX[i] + enemyW)) && 
                    ((laserY + laserH) >= enemyY[i]) && (laserY <= (enemyY[i] + enemyH)) ) {    // レーザーが敵に当たった
                        enemyFlag[i] = false;   // 敵を消す
                        document.getElementById("enemy"+i).style.visibility = "hidden"; // 敵の表示も消す
                        startLaser();
                        score = score + 1;  // スコアを加算
                        document.getElementById("score").innerHTML = score+"点";
                        count++;    // カウンタを増やす
                        if (count == total){    // 全ての敵を消した
                            drawEnemy();    // 再度敵を描画しゲームを継続する
                        }
                }
            }
        }
        // ===============================================
        // 敵を移動
        // ===============================================
        function moveEnemy(){
            if (!gameFlag) return;  // ゲーム中でなければ処理しない
            for(var i=0; i<total; i++){
                if (!enemyFlag[i]) continue;    // 敵がいない場合は繰り返しの先頭に戻る
                enemyX[i] = enemyX[i] + patDX[patCount];
                enemyY[i] = enemyY[i] + 0.2;
                document.getElementById("enemy"+i).style.left = enemyX[i];
                document.getElementById("enemy"+i).style.top = enemyY[i];
                if (enemyY[i] > 260) {  // 侵略されたらゲームオーバー
                    gameFlag = false;   // ゲームは終了したのでフラグをオフにする
                    alert("地球は侵略されました。ゲームオーバー");
                    document.getElementById("gameForm").style.visibility = "visible";
                    clearInterval(timerID); // タイマーを解除
                    return;
                }
            }
            patCount = patCount + 1;
            patCount = patCount % patDX.length; // 動きの量を示す配列の要素数を超えないようにする
        }
        // ===============================================
        // 背景を移動
        // ===============================================
        function moveBG(){
            bgY = bgY + 2;  // 2ピクセルごと背景画像を下に移動
            document.body.style.backgroundPositionY = bgY;
        }
        // ===============================================
        // 敵を描画
        // ===============================================
        function drawEnemy(){
            var txt = "";
            total = 0;  // 敵の総数を0にする
            for(var j=0; j<4; j++){ // 縦4
                for (var i=0; i<9; i++){    // 横9
                    var tx = i * 32 + 10;   // 横の表示位置を求める
                    var ty = j * 32 + 40;   // 縦の表示位置を求める
                    enemyX[total] = tx; // 敵のX座標を配列変数に入れる
                    enemyY[total] = ty; // 敵のY座標を配列変数に入れる
                    enemyFlag[total] = true;    // 敵の存在を「有り」にする
                txt += '<img src="images/enemy.gif" width="24" height="24" style="position:absolute;left:'+tx+'px;top:'+ty+'px;" id="enemy'+total+'">';
                    total++;    // 敵の数を増やす
                }
            }
            document.getElementById("gameScreen").innerHTML = txt;
            count = 0;  // カウンタをリセット
        }
        // ===============================================
        // ゲーム開始
        // ===============================================
        function gameStart(){
            document.getElementById("gameForm").style.visibility = "hidden";
            drawEnemy();    // 敵を描画
            score = 0;  // 0点
            gameFlag = true;    // ゲーム中であることを示すフラグをセットする
            document.getElementById("score").innerHTML = "0点";
            timerID = setInterval("moveLaser();moveBG();moveEnemy()", 20);  // 20ミリ秒ごとに処理するようにタイマーを設定
        }
    // --></script>
    </head>
    <body>
    <div id="score">0点</div>
    <div id="gameScreen"></div>
    <form id="gameForm">
        <input type="button" value="ゲーム開始" ontouchstart="gameStart()">
    </form>
    <img id="laser" src="images/laser.gif" width="3" height="20">
    <img id="fighter" src="images/fighter.gif" width="24" height="24">
    </body>
</html>