自動ミサイル迎撃ゲーム。
自動ミサイル追尾ゲームの実装
概要
本研究では、HTMLとJavaScriptを使用して自動ミサイル追尾ゲームを実装した。このゲームでは、画面下部に配置された3つの砲台が、画面上部からランダムに降下してくるミサイルを自動で追尾し、撃ち落とす。ゲームの描画とロジックはすべてクライアントサイドで処理され、2Dグラフィックスを用いたシンプルなゲーム体験を提供する。
-
ゲーム環境の設定
ゲームは要素を利用して描画され、背景色は青 (#0000FF) に設定されている。これにより、ゲームエリアが明確に視覚化され、プレイヤーにとっての視認性が向上する。ゲームタイトルは画面上部に白色 (#FFFFFF) のフォントで表示され、ユーザーにゲームの目的を伝える役割を果たしている。 -
砲台の設計
ゲームには3つの砲台が配置されており、それぞれの砲台は画面下部に固定され、中央を基準に均等に配置されている。砲台の描画には、fillRectメソッドを使用して矩形を描画し、rotateメソッドで角度を調整することで、ミサイルに対する向きを変更する。
const turrets = [
{ x: canvas.width / 4, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 },
{ x: canvas.width / 2, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 },
{ x: (3 * canvas.width) / 4, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 }
];
- ミサイルの生成と管理
ミサイルはランダムな位置から画面上部に降下し、定期的に生成される。ミサイルの速度は一定に設定されており、setInterval関数を用いて一定間隔でミサイルを生成する。
function createMissile() {
const missile = {
x: Math.random() * canvas.width,
y: 0,
speed: 2
};
missiles.push(missile);
}
- 弾の発射と追尾
砲台はミサイルの位置に基づいて自動的にターゲティングし、弾を発射する。弾の発射にはクールダウンタイムが設定されており、これにより過度な発射を防止する。弾は指定された角度と速度で移動し、ミサイルと衝突した場合には削除される。
function shootBullet(turret) {
if (turret.cooldown <= 0) {
const bullet = {
x: turret.x,
y: turret.y,
speed: 5,
angle: turret.angle
};
bullets.push(bullet);
turret.cooldown = 20; // クールダウンタイム
}
}
- 更新と描画のロジック
updateGame関数では、ゲームの各要素(砲台、弾、ミサイル)の位置を更新し、画面上に描画する。ゲームループはrequestAnimationFrameを利用して連続的に実行され、ゲームの状態が常に更新される。これにより、リアルタイムでのゲームプレイが実現される。
function updateGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
aimTurrets();
turrets.forEach(turret => shootBullet(turret));
updateBullets();
updateMissiles();
drawTurrets();
// 各砲台のクールダウン減少
turrets.forEach(turret => {
if (turret.cooldown > 0) {
turret.cooldown--;
}
});
requestAnimationFrame(updateGame);
}
- 結論
本ゲームは、HTML5の要素とJavaScriptを用いて、シンプルでありながらも効果的な2Dゲーム体験を提供する。自動的にミサイルを追尾し撃ち落とす砲台のメカニズムは、ゲームの魅力を引き出し、ユーザーに対して挑戦的な体験を提供する。今後の改善点としては、ミサイルの種類や砲台のカスタマイズ、ゲームの難易度調整などが考えられる。
コード全体。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>自動ミサイル追尾ゲーム</title>
<style>
canvas {
display: block;
margin: 0 auto;
background: #0000FF; /* 背景色を青に設定 */
}
#title {
text-align: center;
color: #FFFFFF;
font-size: 24px;
font-family: Arial, sans-serif;
margin: 20px 0;
}
</style>
</head>
<body>
<div id="title">自動ミサイル追尾ゲーム</div>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 砲台の設定
const turrets = [
{ x: canvas.width / 4, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 },
{ x: canvas.width / 2, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 },
{ x: (3 * canvas.width) / 4, y: canvas.height - 30, width: 20, height: 20, angle: 0, cooldown: 0 }
];
// 弾とミサイルのリスト
const bullets = [];
const missiles = [];
// ミサイルを生成する関数
function createMissile() {
const missile = {
x: Math.random() * canvas.width,
y: 0,
speed: 2
};
missiles.push(missile);
}
// 弾を発射する関数
function shootBullet(turret) {
if (turret.cooldown <= 0) {
const bullet = {
x: turret.x,
y: turret.y,
speed: 5,
angle: turret.angle
};
bullets.push(bullet);
turret.cooldown = 20; // クールダウンタイム
}
}
// 各砲台がミサイルの方向に向ける関数
function aimTurrets() {
turrets.forEach(turret => {
if (missiles.length > 0) {
const target = missiles[0];
const dx = target.x - turret.x;
const dy = target.y - turret.y;
turret.angle = Math.atan2(dy, dx);
}
});
}
// 弾の移動と描画
function updateBullets() {
for (let i = bullets.length - 1; i >= 0; i--) {
const bullet = bullets[i];
bullet.x += bullet.speed * Math.cos(bullet.angle);
bullet.y += bullet.speed * Math.sin(bullet.angle);
// 弾の描画
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(bullet.x, bullet.y, 5, 0, Math.PI * 2);
ctx.fill();
// 弾が画面外に出たら削除
if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
bullets.splice(i, 1);
}
}
}
// ミサイルの移動と描画
function updateMissiles() {
for (let i = missiles.length - 1; i >= 0; i--) {
const missile = missiles[i];
missile.y += missile.speed;
// ミサイルの描画
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(missile.x, missile.y, 10, 0, Math.PI * 2);
ctx.fill();
// ミサイルが画面外に出たら削除
if (missile.y > canvas.height) {
missiles.splice(i, 1);
}
// 弾とミサイルの衝突判定
for (let j = bullets.length - 1; j >= 0; j--) {
const bullet = bullets[j];
const dx = bullet.x - missile.x;
const dy = bullet.y - missile.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) { // 衝突判定
missiles.splice(i, 1);
bullets.splice(j, 1);
break;
}
}
}
}
// 各砲台の描画
function drawTurrets() {
turrets.forEach(turret => {
ctx.save();
ctx.translate(turret.x, turret.y);
ctx.rotate(turret.angle);
ctx.fillStyle = 'white';
ctx.fillRect(-turret.width / 2, -turret.height / 2, turret.width, turret.height);
ctx.restore();
});
}
// ゲームの更新
function updateGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
aimTurrets();
turrets.forEach(turret => shootBullet(turret));
updateBullets();
updateMissiles();
drawTurrets();
// 各砲台のクールダウン減少
turrets.forEach(turret => {
if (turret.cooldown > 0) {
turret.cooldown--;
}
});
requestAnimationFrame(updateGame);
}
// ミサイルを定期的に生成
setInterval(createMissile, 1000);
// ゲームの開始
updateGame();
</script>
</body>
</html>