巫女さんシューティングゲーム
スタートボタンをクリックしてゲームを開始してください。
以下が実際のコードになります。セキュリティのために、evalや他のサイトに遷移させるような危険な操作は使用していません。
```html
<!DOCTYPE html>
<html>
<head>
<title>巫女さんシューティングゲーム</title>
<style type="text/css">
canvas {
border: 1px solid black;
background-color: #ffffff;
}
</style>
</head>
<body>
<h1>巫女さんシューティングゲーム</h1>
<p>スタートボタンをクリックしてゲームを開始してください。</p>
<button id="startBtn">スタート</button>
<canvas id="gameCanvas" width="400" height="600"></canvas>
<button id="retryBtn" style="display: none;">リトライ</button>
<script type="text/javascript">
// ゲームオブジェクト
var game = {
// 初期化
init: function() {
// キャンバスの取得
this.canvas = document.getElementById("gameCanvas");
this.ctx = this.canvas.getContext("2d");
// プレイヤーの初期設定
this.player = {
x: this.canvas.width / 2,
y: this.canvas.height - 50,
width: 30,
height: 45,
speed: 5,
shootInterval: 200,
lastShootTime: new Date().getTime(),
bullets: []
};
// 敵の初期設定
this.enemy = {
x: this.canvas.width / 2,
y: 50,
width: 50,
height: 50,
speed: 3,
bullets: []
};
// イベントハンドラの設定
var self = this;
this.canvas.addEventListener("mousemove", function(event) {
self.movePlayer(event);
});
this.canvas.addEventListener("click", function(event) {
self.shoot();
});
document.getElementById("retryBtn").addEventListener("click", function() {
self.retry();
});
},
// メインループ
loop: function() {
this.update();
this.draw();
requestAnimationFrame(this.loop.bind(this));
},
// オブジェクトの更新
update: function() {
// プレイヤーの弾の更新
for (var i = 0; i < this.player.bullets.length; i++) {
this.player.bullets[i].y -= 10;
// 敵に当たった場合
if (this.isCollide(this.player.bullets[i], this.enemy)) {
this.player.bullets.splice(i, 1); // 弾を消す
this.enemy = null; // 敵を消す
}
}
// エネミーの弾の更新
for (var i = 0; i < this.enemy.bullets.length; i++) {
this.enemy.bullets[i].y += 10;
// プレイヤーに当たった場合
if (this.isCollide(this.enemy.bullets[i], this.player)) {
if (--this.player.life <= 0) {
this.gameOver();
return;
}
this.enemy.bullets.splice(i, 1); // 弾を消す
}
}
// エネミーの移動
if (this.enemy) {
this.enemy.y += this.enemy.speed;
// 画面下まで移動した場合
if (this.enemy.y > this.canvas.height) {
this.enemy = null;
}
// 敵の弾を発射
if (new Date().getTime() - this.enemy.lastShootTime > 1000) {
var bullet = {
x: this.enemy.x + this.enemy.width / 2,
y: this.enemy.y + this.enemy.height,
width: 5,
height: 10
};
this.enemy.bullets.push(bullet);
this.enemy.lastShootTime = new Date().getTime();
}
}
// 弾の寿命が切れたら消す
for (var i = 0; i < this.player.bullets.length; i++) {
if (this.player.bullets[i].y < 0) {
this.player.bullets.splice(i, 1);
}
}
for (var i = 0; i < this.enemy.bullets.length; i++) {
if (this.enemy.bullets[i].y > this.canvas.height) {
this.enemy.bullets.splice(i, 1);
}
}
},
// オブジェクトの描画
draw: function() {
// キャンバスをクリア
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// プレイヤーの描画
this.ctx.fillStyle = "#ff0000";
this.ctx.fillRect(this.player.x, this.player.y, this.player.width, this.player.height);
// プレイヤーの残機表示
this.ctx.fillStyle = "#000000";
this.ctx.font = "24px Arial";
this.ctx.fillText("残機: " + this.player.life, 10, 30);
// 敵の描画
if (this.enemy) {
this.ctx.fillStyle = "#0000ff";
this.ctx.fillRect(this.enemy.x, this.enemy.y, this.enemy.width, this.enemy.height);
}
// 弾の描画
this.ctx.fillStyle = "#000000";
for (var i = 0; i < this.player.bullets.length; i++) {
this.ctx.fillRect(this.player.bullets[i].x, this.player.bullets[i].y, this.player.bullets[i].width, this.player.bullets[i].height);
}
for (var i = 0; i < this.enemy.bullets.length; i++) {
this.ctx.fillRect(this.enemy.bullets[i].x, this.enemy.bullets[i].y, this.enemy.bullets[i].width, this.enemy.bullets[i].height);
}
},
// プレイヤーの移動
movePlayer: function(event) {
var rect = this.canvas.getBoundingClientRect();
this.player.x = event.clientX - rect.left - this.player.width / 2;
if (this.player.x < 0) {
this.player.x = 0;
} else if (this.player.x + this.player.width > this.canvas.width) {
this.player.x = this.canvas.width - this.player.width;
}
},
// プレイヤーの弾を発射
shoot: function() {
if (new Date().getTime() - this.player.lastShootTime < this.player.shootInterval) {
return;
}
var bullet = {
x: this.player.x + this.player.width / 2,
y: this.player.y,
width: 5,
height: 10
};
this.player.bullets.push(bullet);
this.player.lastShootTime = new Date().getTime();
},
// 衝突判定
isCollide: function(obj1, obj2) {
if (!obj2) {
return false;
}
return (obj1.x + obj1.width > obj2.x && obj1.x < obj2.x + obj2.width &&
obj1.y + obj1.height > obj2.y && obj1.y < obj2.y + obj2.height);
},
// ゲームオーバー処理
gameOver: function() {
document.getElementById("retryBtn").style.display = "block";
},
// リトライ処理
retry: function() {
document.getElementById("retryBtn").style.display = "none";
this.init();
}
};
// ゲームの開始
document.getElementById("startBtn").addEventListener("click", function() {
game.init();
requestAnimationFrame(game.loop.bind(game));
});
</script>
</body>
</html>
```
面白いジョークとしては、「巫女さんが弾いていると、手裏剣とび火も飛び交っているかもしれません」とか、「巫女さんが結界を張ると、ハッカーからの攻撃もブロックされるかもしれません」とかがあります。