ゲームの概要
ここでは、非常に簡単なインベーダーゲームのような遊びができる、シューティングゲームの作り方をご紹介します。下記のゲーム画面のように、遊ぶことができます。
ゲームのプレイはコチラから
同梱物
- index.html(ゲームのメインプログラムです)
- 背景画像(ゲームの背景となる画像です)
- 敵オブジェクト(牡蠣の画像です)
- Playerオブジェクト(忍者の画像です)
仕様
- 移動:左右の矢印ボタンで移動します(移動は左右のみ)
- 攻撃:スペースで弾を発射します(押しっぱなしで連続発射も可能)
- 得点:牡蠣1体撃破につき、+10点
- 当たり判定:牡蠣との接触では、当たり判定のカウントなし
- ゲームオーバー:設定なし
ソースコードや同梱物は、Githubへ公開中です(下記参照)
ソースコード(html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KAKI-WARS</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #222;
background-image: url("back.png");
background-size: cover;
}
canvas {
border: 1px solid #ffffff;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="480" height="320"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const keys = {};
document.addEventListener('keydown', (e) => {
keys[e.code] = true;
// 追加: スペースキーが押されたときに弾を発射
if (e.code === 'Space') {
player.bullets.push({
x: player.x + player.size / 2 - 2,
y: player.y - 10,
size: 4,
speed: 6
});
}
});
document.addEventListener('keyup', (e) => {
keys[e.code] = false;
});
let player = {
x: canvas.width / 2,
y: canvas.height - 30 - 30, // 上に30px移動
size: 60,
speed: 4,
bullets: [],
ready: false
};
let enemies = [];
let enemySpawnCounter = 0;
let moveDirection = 1;
let moveDownCounter = 0;
let score = 0;
let playerImage = new Image();
playerImage.src = "忍者-ジャンプ4.png";
playerImage.onload = function() {
player.image = playerImage;
player.ready = true;
};
let enemyImage = new Image();
enemyImage.src = "kaki.png";
enemyImage.onload = function() {
for (const enemy of enemies) {
enemy.image = enemyImage;
enemy.ready = true;
}
};
function drawEnemies() {
for (const enemy of enemies) {
if (enemy.ready) {
ctx.drawImage(enemy.image, enemy.x, enemy.y, enemy.size, enemy.size);
}
}
}
function drawBullets() {
ctx.fillStyle = 'green';
for (const bullet of player.bullets) {
ctx.fillRect(bullet.x, bullet.y, bullet.size, bullet.size);
}
}
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (player.ready) {
ctx.drawImage(player.image, player.x, player.y, player.size, player.size);
}
drawEnemies();
drawBullets();
if (keys['ArrowLeft']) {
player.x -= player.speed;
}
if (keys['ArrowRight']) {
player.x += player.speed;
}
for (const bullet of player.bullets) {
bullet.y -= bullet.speed;
}
player.bullets = player.bullets.filter(bullet => bullet.y > 0);
// 弾と敵の衝突判定を追加
player.bullets.forEach((bullet) => {
enemies.forEach((enemy) => {
if (
bullet.x < enemy.x + enemy.size &&
bullet.x + bullet.size > enemy.x &&
bullet.y < enemy.y + enemy.size &&
bullet.y + bullet.size > enemy.y
) {
bullet.toRemove = true;
enemy.toRemove = true;
score += 10;
}
});
});
player.bullets = player.bullets.filter((bullet) => !bullet.toRemove);
enemies = enemies.filter((enemy) => !enemy.toRemove);
enemySpawnCounter++;
if (enemySpawnCounter >= 30) {
let newEnemy = {
x: Math.random() * (canvas.width - 20),
y: 10,
size: 40,
speed: 2,
ready: false
};
newEnemy.image = enemyImage;
newEnemy.ready = true;
enemies.push(newEnemy);
enemySpawnCounter = 0;
}
moveDownCounter++;
if (moveDownCounter >= 60) {
moveDirection = -moveDirection;
for (const enemy of enemies) {
enemy.y += 20;
}
moveDownCounter = 0;
}
for (const enemy of enemies) {
enemy.x += enemy.speed * moveDirection;
}
enemies = enemies.filter(enemy => enemy.y < canvas.height);
ctx.fillStyle = "white";
ctx.font = "16px Arial";
ctx.fillText("Score: " + score, 10, 20);
requestAnimationFrame(update);
}
canvas.addEventListener('click', (e) => {
player.bullets.push({
x: player.x + player.size / 2 - 2,
y: player.y - 10,
size: 4,
speed: 6
});
});
update();
</script>
</body>
</html>
ゲームパッケージ
最後に…「KAKI WARS」ということで、あの懐かしいゲームの外箱っぽいデザインに仕上げてみました。もちろん、パッケージは存在しないので、架空の外箱となります。
この記事は、著者が運営するメディア「ぬるぺでぃあ」でも読むことができます(記事はコチラ)