shootergame / index.html
akhaliq's picture
akhaliq HF Staff
Update index.html
24dc83f verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Space Defender</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: 'Orbitron', sans-serif;
}
canvas {
display: block;
}
#info {
position: absolute;
top: 10px;
width: 100%;
text-align: center;
color: white;
font-size: 20px;
text-shadow: 0 0 5px #00ff00;
pointer-events: none;
}
#gameOver {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
background: rgba(0,0,0,0.8);
padding: 30px;
border-radius: 15px;
text-align: center;
font-size: 24px;
display: none;
border: 2px solid #00ff00;
}
button {
background: #000;
color: #00ff00;
border: 2px solid #00ff00;
padding: 10px 25px;
font-size: 18px;
margin-top: 20px;
font-family: 'Orbitron', sans-serif;
cursor: pointer;
transition: all 0.3s;
}
button:hover {
background: #00ff00;
color: #000;
}
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
</style>
</head>
<body>
<div id="info">
SCORE: <span id="score">0</span> |
HEALTH: <span id="health">100</span>% |
LEVEL: <span id="level">1</span>
</div>
<div id="gameOver">
<h1>MISSION FAILED</h1>
<p>YOUR SCORE: <span id="finalScore">0</span></p>
<button onclick="resetGame()">RETRY MISSION</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// Game variables
let score = 0;
let health = 100;
let level = 1;
let gameOver = false;
let lastSpawnTime = 0;
let enemies = [];
let lasers = [];
// Three.js components
let scene, camera, renderer, ship, space, stars = [];
const clock = new THREE.Clock();
// Initialize game
init();
animate();
function init() {
// Create scene
scene = new THREE.Scene();
// Create camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
// Create renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// Add lighting
const ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight);
const pointLight = new THREE.PointLight(0x00ff00, 5, 50);
pointLight.position.set(0, -5, 0);
scene.add(pointLight);
// Create player ship
const shipGeometry = new THREE.ConeGeometry(2, 5, 4);
const shipMaterial = new THREE.MeshPhongMaterial({
color: 0x00ff00,
emissive: 0x00ff00,
emissiveIntensity: 0.5
});
ship = new THREE.Mesh(shipGeometry, shipMaterial);
ship.position.z = -15;
ship.rotation.x = Math.PI / 2;
scene.add(ship);
// Create space background
const spaceGeometry = new THREE.SphereGeometry(1000, 32, 32);
const spaceMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
side: THREE.BackSide
});
space = new THREE.Mesh(spaceGeometry, spaceMaterial);
scene.add(space);
// Create stars
for (let i = 0; i < 1000; i++) {
const starGeometry = new THREE.SphereGeometry(0.1, 8, 8);
const starMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
const star = new THREE.Mesh(starGeometry, starMaterial);
star.position.x = (Math.random() - 0.5) * 2000;
star.position.y = (Math.random() - 0.5) * 2000;
star.position.z = (Math.random() - 0.5) * 2000;
scene.add(star);
stars.push(star);
}
// Event listeners
window.addEventListener('resize', onWindowResize);
window.addEventListener('keydown', onKeyDown);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('click', fireLaser);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onKeyDown(e) {
const speed = 10;
if (gameOver) return;
switch(e.key) {
case 'ArrowLeft': ship.position.x = Math.max(ship.position.x - speed, -20); break;
case 'ArrowRight': ship.position.x = Math.min(ship.position.x + speed, 20); break;
case 'ArrowUp': ship.position.y = Math.min(ship.position.y + speed, 10); break;
case 'ArrowDown': ship.position.y = Math.max(ship.position.y - speed, -10); break;
case ' ': fireLaser(); break;
}
}
function onMouseMove(e) {
if (gameOver) return;
const x = (e.clientX / window.innerWidth) * 2 - 1;
const y = -(e.clientY / window.innerHeight) * 2 + 1;
ship.position.x = x * 20;
ship.position.y = y * 10;
}
function fireLaser() {
if (gameOver) return;
const laserGeometry = new THREE.CylinderGeometry(0.1, 0.1, 3, 8);
const laserMaterial = new THREE.MeshPhongMaterial({
color: 0x00ffff,
emissive: 0x00ffff,
emissiveIntensity: 1
});
const laser = new THREE.Mesh(laserGeometry, laserMaterial);
laser.position.copy(ship.position);
laser.position.z += 5;
laser.rotation.x = Math.PI / 2;
scene.add(laser);
lasers.push(laser);
// Play sound
const audio = new Audio('https://assets.codepen.io/21542/hit-sound.mp3');
audio.volume = 0.2;
audio.play().catch(e => console.log("Audio error:", e));
}
function createEnemy() {
if (gameOver) return;
const types = ['cube', 'sphere', 'torus'];
const type = types[Math.floor(Math.random() * types.length)];
let geometry;
switch(type) {
case 'cube': geometry = new THREE.BoxGeometry(2, 2, 2); break;
case 'sphere': geometry = new THREE.SphereGeometry(1.5, 16, 16); break;
case 'torus': geometry = new THREE.TorusGeometry(1, 0.5, 16, 32); break;
}
const color = new THREE.Color(
Math.random() * 0.5 + 0.5,
Math.random() * 0.2,
Math.random() * 0.2
);
const material = new THREE.MeshPhongMaterial({
color: color,
emissive: color,
emissiveIntensity: 0.2
});
const enemy = new THREE.Mesh(geometry, material);
enemy.position.x = (Math.random() - 0.5) * 30;
enemy.position.y = (Math.random() * 15) - 5;
enemy.position.z = 50;
scene.add(enemy);
enemies.push({
mesh: enemy,
speed: 5 + Math.random() * level * 0.5,
health: 1 + level * 0.2
});
}
function updateLasers(delta) {
for (let i = lasers.length - 1; i >= 0; i--) {
const laser = lasers[i];
laser.position.z += delta * 100;
if (laser.position.z > 50) {
scene.remove(laser);
lasers.splice(i, 1);
} else {
checkLaserCollision(laser, i);
}
}
}
function checkLaserCollision(laser, laserIndex) {
for (let j = enemies.length - 1; j >= 0; j--) {
const enemy = enemies[j];
if (laser.position.distanceTo(enemy.mesh.position) < 3) {
enemy.health -= 1;
if (enemy.health <= 0) {
score += Math.floor(10 * enemy.speed);
document.getElementById('score').textContent = score;
// Explosion effect
const explosionGeometry = new THREE.SphereGeometry(2, 8, 8);
const explosionMaterial = new THREE.MeshBasicMaterial({
color: 0xff9900,
wireframe: true
});
const explosion = new THREE.Mesh(explosionGeometry, explosionMaterial);
explosion.position.copy(enemy.mesh.position);
scene.add(explosion);
setTimeout(() => scene.remove(explosion), 200);
scene.remove(enemy.mesh);
enemies.splice(j, 1);
}
scene.remove(laser);
lasers.splice(laserIndex, 1);
break;
}
}
}
function updateEnemies(delta) {
for (let i = enemies.length - 1; i >= 0; i--) {
const enemy = enemies[i];
enemy.mesh.position.z -= delta * enemy.speed;
enemy.mesh.rotation.x += delta * 0.5;
enemy.mesh.rotation.y += delta * 0.7;
if (enemy.mesh.position.z < -20) {
scene.remove(enemy.mesh);
enemies.splice(i, 1);
health -= 5 + level;
document.getElementById('health').textContent = health;
if (health <= 0) {
endGame();
}
}
}
}
function updateStars() {
stars.forEach(star => {
star.position.z += 1;
if (star.position.z > 1000) {
star.position.z = -1000;
}
});
}
function checkLevelUp() {
const newLevel = Math.floor(score / 1000) + 1;
if (newLevel > level) {
level = newLevel;
document.getElementById('level').textContent = level;
// Play level up sound
const audio = new Audio('https://assets.codepen.io/21542/level-up.mp3');
audio.volume = 0.2;
audio.play().catch(e => console.log("Audio error:", e));
}
}
function endGame() {
gameOver = true;
document.getElementById('finalScore').textContent = score;
document.getElementById('gameOver').style.display = 'block';
// Remove all enemies and lasers
enemies.forEach(enemy => scene.remove(enemy.mesh));
lasers.forEach(laser => scene.remove(laser));
enemies = [];
lasers = [];
}
function resetGame() {
score = 0;
health = 100;
level = 1;
gameOver = false;
document.getElementById('score').textContent = score;
document.getElementById('health').textContent = health;
document.getElementById('level').textContent = level;
document.getElementById('gameOver').style.display = 'none';
ship.position.set(0, 0, -15);
}
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
const time = clock.getElapsedTime();
if (!gameOver) {
// Spawn enemies with increasing frequency
if (time - lastSpawnTime > 1 / (level * 0.5 + 0.5)) {
createEnemy();
lastSpawnTime = time;
}
updateLasers(delta);
updateEnemies(delta);
updateStars();
checkLevelUp();
// Camera shake when damaged
if (health < 30) {
camera.position.x = (Math.random() - 0.5) * 0.5;
camera.position.y = (Math.random() - 0.5) * 0.5;
} else {
camera.position.x = 0;
camera.position.y = 0;
}
// Ship pulsing effect
ship.material.color.offsetHSL(0, 0, delta * 0.1);
}
renderer.render(scene, camera);
}
</script>
</body>
</html>