以下はセキュリティを考慮し、alertやevalを使わず、他のサイトへの遷移やリダイレクトを行わない、シンプルなシューティングゲームの例です。
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shooting Game</title>
<style>
#space {
width: 1000px;
height: 600px;
background-color: black;
position: relative;
}
#player {
width: 30px;
height: 30px;
background-color: orange;
position: absolute;
left: 485px;
bottom: 0;
}
.bullet {
width: 5px;
height: 20px;
background-color: white;
position: absolute;
}
.enemy {
width: 30px;
height: 30px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="space">
<div id="player"></div>
</div>
<script>
// Player movement
document.addEventListener('keydown', function(event) {
if (event.code === 'ArrowLeft' && player.offsetLeft > 0) {
player.style.left = player.offsetLeft - 10 + 'px';
} else if (event.code === 'ArrowRight' && player.offsetLeft + player.offsetWidth < space.offsetWidth) {
player.style.left = player.offsetLeft + 10 + 'px';
} else if (event.code === 'Space') {
createBullet();
}
});
// Create bullet
function createBullet() {
const bullet = document.createElement('div');
bullet.classList.add('bullet');
bullet.style.left = player.offsetLeft + player.offsetWidth / 2 - bullet.offsetWidth / 2 + 'px';
bullet.style.bottom = player.offsetHeight + 'px';
space.appendChild(bullet);
moveBullet(bullet);
}
// Move bullet
function moveBullet(bullet) {
const id = setInterval(frame, 10);
function frame() {
if (bullet.offsetTop < 0) {
clearInterval(id);
space.removeChild(bullet);
} else {
bullet.style.top = bullet.offsetTop - 5 + 'px';
const hitEnemy = checkCollision(bullet, enemies);
if (hitEnemy) {
clearInterval(id);
space.removeChild(bullet);
space.removeChild(hitEnemy);
const index = enemies.indexOf(hitEnemy);
enemies.splice(index, 1);
}
}
}
}
// Create enemy
const enemies = [];
setInterval(function() {
const enemy = document.createElement('div');
enemy.classList.add('enemy');
enemy.style.left = Math.random() * (space.offsetWidth - enemy.offsetWidth) + 'px';
enemy.style.top = '0px';
space.appendChild(enemy);
enemies.push(enemy);
moveEnemy(enemy);
}, 1000);
// Move enemy
function moveEnemy(enemy) {
const id = setInterval(frame, 50);
function frame() {
if (enemy.offsetTop > space.offsetHeight) {
clearInterval(id);
space.removeChild(enemy);
const index = enemies.indexOf(enemy);
enemies.splice(index, 1);
} else {
enemy.style.top = enemy.offsetTop + 5 + 'px';
if (checkCollision(enemy, [player])) {
clearInterval(id);
space.removeChild(enemy);
space.removeChild(player);
gameOver();
}
}
}
}
// Check collision
function checkCollision(element, elements) {
const rect1 = element.getBoundingClientRect();
for (let i = 0; i < elements.length; i++) {
const rect2 = elements[i].getBoundingClientRect();
if (!(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)) {
return elements[i];
}
}
return null;
}
// Game over
function gameOver() {
const gameOver = document.createElement('h1');
gameOver.innerText = 'Game Over!';
gameOver.style.textAlign = 'center';
gameOver.style.color = 'white';
gameOver.style.position = 'absolute';
gameOver.style.top = '50%';
gameOver.style.left = '50%';
gameOver.style.transform = 'translate(-50%, -50%)';
space.appendChild(gameOver);
}
// Variables
const space = document.querySelector('#space');
const player = document.querySelector('#player');
</script>
</body>
</html>
```
ジョーク要素として、敵が赤くなっているのは、「何もしていないプログラムのバグが黒くなるのに対し、あらゆることをやりつくしたプログラムのバグは赤くなる」という慣習に由来するという設定だとするのはどうでしょうか。