今回はJavaScriptでインベーダーゲームを実装してみます。
HTMLファイルに以下のように記述してください。
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Invader Game</title>
</head>
<body>
<canvas id="canvas" width="500" height="500">
Your browser does not support canvas.
</canvas>
</body>
</html>
```
次に、JavaScriptファイルを記述します。
```js
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
// 定数
const INVADER_SIZE = 30; // インベーダーのサイズ
const INVADER_NUM = 20; // インベーダーの数
const INVADER_SPEED = 2; // インベーダーのスピード(ピクセル/フレーム)
const SHOT_SPEED = 5; // 弾のスピード(ピクセル/フレーム)
// ゲームオーバーフラグ
let isGameOver = false;
// スコア
let score = 0;
// パドル
let paddle = {
x: 0,
y: canvas.height - 20,
width: 80,
height: 10,
speed: 5
};
// 弾の配列
let shots = [];
// インベーダーの配列
let invaders = [];
for (let i = 0; i < INVADER_NUM; i++) {
invaders.push({
x: i * 50 + 50,
y: 50,
width: INVADER_SIZE,
height: INVADER_SIZE,
speed: INVADER_SPEED
});
}
// パドルを描画する
function drawPaddle() {
context.fillStyle = '#0095DD';
context.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
// 弾を描画する
function drawShots() {
context.fillStyle = '#FF0000';
for (let i = 0; i < shots.length; i++) {
let shot = shots[i];
context.fillRect(shot.x, shot.y, 5, 10);
}
}
// インベーダーを描画する
function drawInvaders() {
context.fillStyle = '#00FF00';
for (let i = 0; i < invaders.length; i++) {
let invader = invaders[i];
context.fillRect(invader.x, invader.y, invader.width, invader.height);
}
}
// スコアを描画する
function drawScore() {
context.fillStyle = '#000';
context.font = '20px Arial';
context.fillText('Score: ' + score, 10, 30);
}
// ゲームオーバーを描画する
function drawGameOver() {
context.fillStyle = '#000';
context.font = '50px Arial';
context.fillText('Game Over', 100, 250);
}
// 新しい弾を発射する
function shoot() {
shots.push({
x: paddle.x + paddle.width / 2 - 2,
y: paddle.y - 10,
speed: SHOT_SPEED
});
}
// 弾を移動する
function moveShots() {
for (let i = 0; i < shots.length; i++) {
let shot = shots[i];
shot.y -= shot.speed;
// 弾が画面外に出たら削除する
if (shot.y < 0) {
shots.splice(i--, 1);
}
}
}
// インベーダーを移動する
function moveInvaders() {
for (let i = 0; i < invaders.length; i++) {
let invader = invaders[i];
invader.x += invader.speed;
// インベーダーが左右の壁にぶつかったら下に移動する
if (invader.x + invader.width > canvas.width || invader.x < 0) {
invader.speed *= -1;
invader.y += invader.height;
// インベーダーがパドルにぶつかったらゲームオーバー
if (invader.y + invader.height > paddle.y) {
isGameOver = true;
}
}
}
}
// 衝突判定
function collisionDetection() {
for (let i = 0; i < shots.length; i++) {
let shot = shots[i];
for (let j = 0; j < invaders.length; j++) {
let invader = invaders[j];
if (shot.x > invader.x && shot.x < invader.x + invader.width && shot.y > invader.y && shot.y < invader.y + invader.height) {
// 弾とインベーダーが衝突したら弾とインベーダーを削除し、スコアを加算する
shots.splice(i--, 1);
invaders.splice(j--, 1);
score += 10;
// インベーダーを全滅させたらゲームクリア
if (invaders.length === 0) {
setTimeout(function() {
alert('Congratulations! You cleared the game!');
}, 500);
}
break;
}
}
}
}
// キーボードイベント
document.addEventListener('keydown', function(event) {
if (event.keyCode === 37) { // 左矢印キー
paddle.x -= paddle.speed;
if (paddle.x < 0) {
paddle.x = 0;
}
} else if (event.keyCode === 39) { // 右矢印キー
paddle.x += paddle.speed;
if (paddle.x + paddle.width > canvas.width) {
paddle.x = canvas.width - paddle.width;
}
} else if (event.keyCode === 32) { // スペースキー
shoot();
}
});
// メインループ
function loop() {
// 画面を消去する
context.clearRect(0, 0, canvas.width, canvas.height);
// パドルを描画する
drawPaddle();
// 弾を描画する
drawShots();
// インベーダーを描画する
drawInvaders();
// スコアを描画する
drawScore();
// ゲームオーバーの場合
if (isGameOver) {
drawGameOver();
return;
}
// 弾を移動する
moveShots();
// インベーダーを移動する
moveInvaders();
// 衝突判定を行う
collisionDetection();
// ループする
requestAnimationFrame(loop);
}
// ループ開始
loop();
```
以上でインベーダーゲームが実装できます。パドルを左右に移動して弾を撃ち、インベーダーを倒してスコアを稼ぎましょう!