素のHTML, CSS, JavaScriptで0から始めるWeb開発【応用編】

こんにちは、エムティーアイの井上です。今回はこれからWeb開発を始めたいという方向けにWeb開発の基礎となる部分を紹介します。

このシリーズのゴールはWeb開発に必要な3つの言語 HTML, CSS, JavaScript の仕組みを理解し書けるようになることにあります。HTML, CSS, JavaScriptでテトリスを作りながらそれぞれの仕組みをご紹介いたします。 全体で4部構成になっており今回はその第4弾【応用編】となります。

f:id:mti-hackers:20171117141649p:plain

今回実装する機能

今回実装する機能は下記の3つです。

  1. キーボードでブロックを操作する
  2. そろった行を消す
  3. 積みあがったらゲームオーバーとする

キーボードでブロックを操作する

JavaScriptではキー入力を利用することができます。 利用方法としては、クリックしたときに呼び出す関数を決め、キー入力があったときに呼び出すだけです。

キー入力されたときの処理は以下のように書けます。

// キーボードイベントを監視する
document.addEventListener("keydown", onKeyDown);

// キー入力によってそれぞれの関数を呼び出す
function onKeyDown(event) {
  if (event.keyCode === 37) {
    moveLeft();
  } else if (event.keyCode === 39) {
    moveRight();
  }
}

moveLeft , moveRight はすでに関数だけは用意しましたね。 上記のプログラムではKeyCodeをもとにどのキーが押されたかを判断し、それぞれの関数を呼び出しています。 キーコードの確認をしたい場合は http://keycode.info/ にて確認することができます。

それでは次に実際に左右に動かす部分の実装を行います。 まずは簡単に、 fallingBlockNum で指定されたブロックを単純に左右に動かすようにします。

function moveRight() {
  // ブロックを右に移動させる
  for (var row = 0; row < 20; row++) {
    for (var col = 9; col >= 0; col--) {
      if (cells[row][col].blockNum === fallingBlockNum) {
        cells[row][col + 1].className = cells[row][col].className;
        cells[row][col + 1].blockNum = cells[row][col].blockNum;
        cells[row][col].className = "";
        cells[row][col].blockNum = null;
      }
    }
  }
}

function moveLeft() {
  // ブロックを左に移動させる
  for (var row = 0; row < 20; row++) {
    for (var col = 0; col < 10; col++) {
      if (cells[row][col].blockNum === fallingBlockNum) {
        cells[row][col - 1].className = cells[row][col].className;
        cells[row][col - 1].blockNum = cells[row][col].blockNum;
        cells[row][col].className = "";
        cells[row][col].blockNum = null;
      }
    }
  }
}

落ちるときの処理とやっていることはほとんど一緒ですね。 ただし、一番右側に来た時や、ブロックがあっていけない場合がありますね? こういったとき、どのように条件を加えるかは fallBlocks を参考に挑戦してみましょう。

そろった行を消す

そろった行を消すのは簡単ですね。 1行ずつそろったかを確認し、削除するだけです。 しかし、削除した行より上のブロックをすべて1マス下にずらすのを忘れないようにしましょう!

function deleteRow() {
  // そろっている行を消す
  for (var row = 19; row >= 0; row--) {
    var canDelete = true;
    for (var col = 0; col < 10; col++) {
      if (cells[row][col].className === "") {
        canDelete = false;
      }
    }
    if (canDelete) {
      // 1行消す
      for (var col = 0; col < 10; col++) {
        cells[row][col].className = "";
      }
      // 上の行のブロックをすべて1マス落とす
      for (var downRow = row - 1; row >= 0; row--) {
        for (var col = 0; col < 10; col++) {
          cells[downRow + 1][col].className = cells[downRow][col].className;
          cells[downRow + 1][col].blockNum = cells[downRow][col].blockNum;
          cells[downRow][col].className = "";
          cells[downRow][col].blockNum = null;
        }
      }
    }
  }
}

積みあがったらゲームオーバーとする

これもシンプルですね。 上2行にブロックがあるときに止めればよいだけですから、 積み上がり切っているかどうかを判定してからほかの処理に入るようにしましょう!

loadTable();
setInterval(function () {
  count++;
  document.getElementById("hello_text").textContent = "はじめてのJavaScript(" + count + ")";
  // ブロックが積み上がり切っていないかのチェック
  for (var row = 0; row < 2; row++) {
    for (var col = 0; col < 10; col++) {
      if (cells[row][col].className !== "") {
        alert("game over");
      }
    }
  }
  if (hasFallingBlock()) { // 落下中のブロックがあるか確認する
    fallBlocks();// あればブロックを落とす
  } else { // なければ
    deleteRow();// そろっている行を消す
    generateBlock();// ランダムにブロックを作成する
  }
}, 1000);

最後に

これにて全4回のWeb開発ことはじめを終わりとします。 まだまだ気にしなければいけないデバッグなどがあることにお気づきだとは思います。 ぜひ、ご自身でトライしてみてください!