JavaScriptでブロック崩しゲームを作る方法10選

JavaScriptを使ったブロック崩しゲーム開発 JS
この記事は約15分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読むと、JavaScriptを使ってブロック崩しゲームを作る方法が身につきます。

初心者にもわかりやすく、徹底解説していくので、どんな方でも安心して取り組めます。

また、対処法や注意点、カスタマイズ方法も紹介していますので、完成度の高いゲームが作れるようになります。

●ブロック崩しゲームの基本構成

ブロック崩しゲームは、プレイヤーが操作するボールを使って画面上のブロックを破壊するゲームです。基本構成は次の3つです。

○ゲーム画面の設定

ゲーム画面は、HTML5のcanvas要素を使用して描画します。

canvas要素は、グラフィックスやアニメーションを描画するのに適しています。

○プレイヤーの操作

プレイヤーは、キーボードやマウス、タッチ操作でバーを左右に移動させ、ボールを跳ね返します。

操作方法は、JavaScriptのイベントリスナーを使って実装します。

○ブロックの配置

ブロックは、2次元配列を使って配置します。

衝突判定を行い、ボールがブロックに当たった場合はブロックを消す処理を実装します。

●JavaScriptでブロック崩しゲームを作る方法

それでは、JavaScriptでブロック崩しゲームを作る方法をサンプルコードと共に解説していきます。

○サンプルコード1:ゲーム画面の描画

このコードでは、HTMLのcanvas要素を使ってゲーム画面を描画しています。

この例では、canvas要素の大きさを設定し、背景色を塗りつぶしています。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ブロック崩しゲーム</title>
<style>
  canvas { display: block; margin: auto; }
</style>
</head>
<body>
<canvas id="gameScreen" width="640" height="480"></canvas>
<script>
  const canvas = document.getElementById('gameScreen');
  const ctx = canvas.getContext('2d');

  // 背景色を塗りつぶす
  ctx.fillStyle = 'black';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
</body>
</html>

○サンプルコード2:プレイヤーの操作を実装

このコードでは、キーボードの矢印キーを使ってプレイヤーがバーを左右に動かす操作を実装しています。

この例では、キーボードイベントリスナーを用いて、矢印キーが押された際にバーが移動する処理を行っています。

let barX = (canvas.width - 100) / 2; // バーの初期位置
const barSpeed = 7; // バーの移動速度

document.addEventListener('keydown', (e) => {
  if (e.key === 'ArrowLeft') {
    barX -= barSpeed;
  } else if (e.key === 'ArrowRight') {
    barX += barSpeed;
  }

  // バーが画面外に出ないよう制限
  barX = Math.max(0, Math.min(canvas.width - 100, barX));
});

○サンプルコード3:ブロックの配置と衝突判定

このコードでは、ブロックの配置と、ボールがブロックに衝突した際の処理を実装しています。

この例では、2次元配列を使ってブロックの配置を表現し、衝突判定を行い、衝突したブロックを消す処理を行っています。

const rowCount = 5; // ブロックの行数
const colCount = 8; // ブロックの列数
const blockSize = { width: 70, height: 20 }; // ブロックのサイズ
const blockPadding = 10; // ブロック同士の間隔

const blocks = [];

// ブロックの初期化
for (let row = 0; row < rowCount; row++) {
  blocks[row] = [];
  for (let col = 0; col < colCount; col++) {
    blocks[row][col] = { x: 0, y: 0, visible: true };
  }
}

// ブロックの描画
function drawBlocks() {
  ctx.fillStyle = 'blue';
  for (let row = 0; row < rowCount; row++) {
    for (let col = 0; col < colCount; col++) {
      if (blocks[row][col].visible) {
        const x = col * (blockSize.width + blockPadding) + blockPadding;
        const y = row * (blockSize.height + blockPadding) + blockPadding;
        blocks[row][col].x = x;
        blocks[row][col].y = y;
        ctx.fillRect(x, y, blockSize.width, blockSize.height);
      }
    }
  }
}

// 衝突判定
function checkCollision() {
  for (let row = 0; row < rowCount; row++) {
    for (let col = 0; col < colCount; col++) {
      const block = blocks[row][col];
      if (block.visible && isColliding(block)) {
        block.visible = false;
        changeBallDirection();
      }
    }
  }
}

// ボールがブロックに衝突しているかを判定する関数
function isColliding(block) {
  // ここに衝突判定の処理を記述
}

○サンプルコード4:スコアとライフの表示

このコードでは、スコアとライフを表示する処理を実装しています。

この例では、スコアの増加やライフの減少を管理し、画面上に表示しています。

let score = 0; // スコア
let lives = 3; // ライフ

// スコアとライフの表示
function drawScoreAndLives() {
  ctx.font = '16px Arial';
  ctx.fillStyle = 'white';
  ctx.fillText(`Score: ${score}`, 10, 20);
  ctx.fillText(`Lives: ${lives}`, 10, 40);
}

○サンプルコード5:ゲームオーバーとリトライの処理

このコードでは、ゲームオーバー時の処理とリトライ処理を実装しています。

この例では、ライフがなくなった時にゲームオーバー画面を表示し、クリックまたはキー入力でゲームをリトライできるようにしています。

let isGameOver = false;

// ゲームオーバーの表示
function showGameOver() {
  ctx.font = '48px Arial';
  ctx.fillStyle = 'red';
  ctx.fillText('Game Over', canvas.width / 2 - 100, canvas.height / 2);
}

// ゲームオーバー処理
function gameOver() {
  isGameOver = true;
  showGameOver();
  canvas.addEventListener('click', retry, false);
  document.addEventListener('keydown', retry, false);
}

// リトライ処理
function retry() {
  if (isGameOver) {
    isGameOver = false;
    lives = 3;
    score = 0;
    initializeBlocks();
    canvas.removeEventListener('click', retry, false);
    document.removeEventListener('keydown', retry, false);
  }
}

// メインループ
function gameLoop() {
  if (lives <= 0) {
    gameOver();
  } else {
    update();
    draw();
  }

  if (!isGameOver) {
    requestAnimationFrame(gameLoop);
  }
}

○サンプルコード6:サウンドエフェクトの追加

このコードでは、サウンドエフェクトを追加する方法を紹介しています。

この例では、ブロックとボールが衝突した時や、ボールが画面外に出た時にサウンドが再生されるようにしています。

const hitSound = new Audio('hit.mp3');
const loseSound = new Audio('lose.mp3');

// 衝突時のサウンド再生
function playHitSound() {
  hitSound.currentTime = 0;
  hitSound.play();
}

// ボールが画面外に出た時のサウンド再生
function playLoseSound() {
  loseSound.currentTime = 0;
  loseSound.play();
}

○サンプルコード7:ゲームの難易度の調整

このコードでは、ゲームの難易度を調整する方法を紹介しています。

この例では、スピードやブロックの数を変更することで難易度を調整しています。

const baseSpeed = 2;
const difficultyMultiplier = 1.5; // 難易度の倍率

// 難易度調整
function adjustDifficulty() {
  ballSpeed.x = baseSpeed * difficultyMultiplier;
  ballSpeed.y = -baseSpeed * difficultyMultiplier;
}

○サンプルコード8:パワーアップアイテムの実装

このコードでは、パワーアップアイテムを実装する方法を紹介しています。

この例では、パワーアップアイテムが出現し、プレイヤーがそれを取得すると一定時間パドルが大きくなるようにしています。

const powerUps = [];
const powerUpSize = 20;
const powerUpDuration = 5000; // パワーアップ効果の持続時間 (ms)

class PowerUp {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.width = powerUpSize;
    this.height = powerUpSize;
    this.active = true;
  }

  draw() {
    if (this.active) {
      ctx.fillStyle = 'blue';
      ctx.fillRect(this.x, this.y, this.width, this.height);
    }
  }

  update() {
    if (this.active) {
      this.y += 2;
      if (this.y > canvas.height) {
        this.active = false;
      }
    }
  }

  checkCollision() {
    if (this.active) {
      if (
        this.x < paddle.x + paddle.width &&
        this.x + this.width > paddle.x &&
        this.y < paddle.y + paddle.height &&
        this.y + this.height > paddle.y
      ) {
        this.active = false;
        activatePowerUp();
      }
    }
  }
}

function activatePowerUp() {
  const originalPaddleWidth = paddle.width;
  paddle.width *= 2;

  setTimeout(() => {
    paddle.width = originalPaddleWidth;
  }, powerUpDuration);
}

function spawnPowerUp(x, y) {
  const powerUp = new PowerUp(x, y);
  powerUps.push(powerUp);
}

function updatePowerUps() {
  for (const powerUp of powerUps) {
    powerUp.update();
    powerUp.checkCollision();
  }
}

function drawPowerUps() {
  for (const powerUp of powerUps) {
    powerUp.draw();
  }
}

○サンプルコード9:スマートフォン対応の操作方法

このコードでは、スマートフォン対応の操作方法を実装する方法を紹介しています。

この例では、画面をタッチしてスライドすることでパドルを操作できるようにしています。

let touchStartX = 0;

canvas.addEventListener('touchstart', (e) => {
  e.preventDefault();
  touchStartX = e.touches[0].clientX;
}, false);

canvas.addEventListener('touchmove', (e) => {
  e.preventDefault();
  const deltaX = e.touches[0].clientX - touchStartX;
  touchStartX = e.touches[0].clientX;
  paddle.x += deltaX;
}, false);

○サンプルコード10:オリジナルデザインのブロックを作成

このコードでは、オリジナルデザインのブロックを作成する方法を紹介しています。

この例では、画像ファイルを使用してブロックのデザインをカスタマイズしています。

const blockImage = new Image();
blockImage.src = 'path/to/your/image.png';

class CustomBlock extends Block {
  constructor(x, y) {
    super(x, y);
  }

  draw() {
    if (this.active) {
      ctx.drawImage(blockImage, this.x, this.y, this.width, this.height);
    }
  }
}

function createCustomBlocks() {
  for (let i = 0; i < blockRowCount; i++) {
    for (let j = 0; j < blockColumnCount; j++) {
      const x = (j * (blockWidth + blockPadding)) + blockOffsetLeft;
      const y = (i * (blockHeight + blockPadding)) + blockOffsetTop;
      const block = new CustomBlock(x, y);
      blocks[i][j] = block;
    }
  }
}

// 既存のブロック生成コードをコメントアウト
// createBlocks();

// カスタムブロック生成コードを追加
createCustomBlocks();

これで、オリジナルデザインのブロックが作成されます。

画像ファイルのパスを指定し、CustomBlockクラスを使ってオリジナルデザインのブロックを生成します。

createCustomBlocks関数を呼び出してカスタムブロックを作成し、既存のブロック生成コードをコメントアウトしてください。

●注意点と対処法

ゲーム開発において、注意すべき点や対処法がいくつかあります。

例えば、パフォーマンスの最適化、ブラウザの互換性、リソースの管理などが挙げられます。

これらの問題に対処することで、ゲームの品質を向上させることができます。

●カスタマイズ方法

ゲームのカスタマイズ方法は様々です。

例えば、グラフィックやサウンドの変更、ゲームのルールや難易度の調整、新しいゲームモードの追加などが考えられます。

これらの変更を通じて、独自のゲームを作成することができます。

まとめ

以上で、ブロック崩しゲームの基本的な要素やカスタマイズ方法を説明しました。

サンプルコードを参考にして、自分だけのオリジナルなブロック崩しゲームを作成してみてください。