|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Jet Fighter Combat</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<script> |
|
tailwind.config = { |
|
theme: { |
|
extend: { |
|
colors: { |
|
'jet-blue': '#0d47a1', |
|
'combat-orange': '#ff6d00', |
|
'sky-dark': '#1565c0', |
|
'sky-light': '#81d4fa' |
|
} |
|
} |
|
} |
|
} |
|
</script> |
|
<style> |
|
#game-canvas { |
|
background: linear-gradient(to bottom, #81d4fa, #1565c0); |
|
border-radius: 8px; |
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); |
|
} |
|
|
|
#controls { |
|
background: linear-gradient(to right, #0d47a1, #1a237e); |
|
} |
|
|
|
.control-btn { |
|
transition: all 0.2s ease; |
|
} |
|
|
|
.control-btn:hover { |
|
transform: translateY(-3px); |
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); |
|
} |
|
|
|
.explosion { |
|
position: absolute; |
|
width: 100px; |
|
height: 100px; |
|
background: radial-gradient(circle, #ff6d00, #ffab40); |
|
border-radius: 50%; |
|
animation: explode 0.6s ease-out; |
|
pointer-events: none; |
|
} |
|
|
|
@keyframes explode { |
|
0% { |
|
transform: scale(0); |
|
opacity: 1; |
|
} |
|
100% { |
|
transform: scale(2); |
|
opacity: 0; |
|
} |
|
} |
|
|
|
@keyframes float { |
|
0% { transform: translateY(0px); } |
|
50% { transform: translateY(-10px); } |
|
100% { transform: translateY(0px); } |
|
} |
|
|
|
.floating { |
|
animation: float 3s ease-in-out infinite; |
|
} |
|
|
|
.cloud { |
|
position: absolute; |
|
background: rgba(255, 255, 255, 0.7); |
|
border-radius: 50%; |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-900 min-h-screen flex items-center justify-center py-8"> |
|
<div class="w-full max-w-4xl"> |
|
|
|
<div class="text-center mb-8"> |
|
<h1 class="text-4xl md:text-5xl font-bold text-white mb-2">JET COMBAT COMMANDER</h1> |
|
<div class="inline-flex items-center bg-gradient-to-r from-combat-orange to-yellow-500 px-6 py-2 rounded-full"> |
|
<i class="fas fa-fighter-jet text-xl mr-2 text-white"></i> |
|
<p class="text-white font-bold">AIR SUPERIORITY SIMULATION</p> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="flex justify-between items-center mb-4 px-2"> |
|
<div class="flex items-center"> |
|
<div class="bg-gradient-to-b from-sky-dark to-jet-blue px-4 py-2 rounded-lg mr-4"> |
|
<p class="text-white font-semibold flex items-center"> |
|
<i class="fas fa-crosshairs mr-2"></i> SCORE: <span id="score" class="ml-2 text-yellow-400">0</span> |
|
</p> |
|
</div> |
|
<div class="bg-gradient-to-b from-sky-dark to-jet-blue px-4 py-2 rounded-lg"> |
|
<p class="text-white font-semibold flex items-center"> |
|
<i class="fas fa-heart mr-2 text-red-500"></i> HEALTH: <span id="health" class="ml-2 text-green-400">100</span>% |
|
</p> |
|
</div> |
|
</div> |
|
|
|
<div class="flex items-center"> |
|
<div class="bg-gradient-to-b from-sky-dark to-jet-blue px-4 py-2 rounded-lg"> |
|
<p class="text-white font-semibold flex items-center"> |
|
<i class="fas fa-rocket mr-2 text-yellow-400"></i> MISSILES: <span id="missiles" class="ml-2">30</span> |
|
</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="relative rounded-xl overflow-hidden mb-6"> |
|
<canvas id="game-canvas" class="w-full" height="500"></canvas> |
|
|
|
|
|
<div id="start-screen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80"> |
|
<div class="floating mb-8"> |
|
<i class="fas fa-fighter-jet text-7xl text-white"></i> |
|
</div> |
|
<h2 class="text-4xl font-bold text-white mb-6">AIR COMBAT READY</h2> |
|
<button id="start-btn" class="bg-gradient-to-r from-red-600 to-combat-orange px-8 py-4 rounded-full text-white font-bold text-xl hover:scale-105 transition-all"> |
|
ENGAGE ENEMY <i class="fas fa-play ml-2"></i> |
|
</button> |
|
<div class="mt-8 flex flex-wrap justify-center gap-4"> |
|
<div class="bg-gray-800 rounded-lg px-4 py-2"> |
|
<p class="text-white flex items-center"><i class="fas fa-arrow-up mr-2"></i> <i class="fas fa-arrow-down mr-2"></i> <i class="fas fa-arrow-left mr-2"></i> <i class="fas fa-arrow-right mr-2"></i> Move Jet</p> |
|
</div> |
|
<div class="bg-gray-800 rounded-lg px-4 py-2"> |
|
<p class="text-white flex items-center"><i class="fas fa-space-shuttle mr-2 text-yellow-500"></i> SPACE to Fire Missile</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="game-over" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 hidden"> |
|
<div class="mb-8"> |
|
<i class="fas fa-skull-crossbones text-7xl text-red-600"></i> |
|
</div> |
|
<h2 class="text-4xl font-bold text-white mb-2">MISSION FAILED</h2> |
|
<p class="text-white text-xl mb-8">Your Score: <span id="final-score" class="text-yellow-400">0</span></p> |
|
<button id="restart-btn" class="bg-gradient-to-r from-green-600 to-emerald-500 px-8 py-4 rounded-full text-white font-bold text-xl hover:scale-105 transition-all"> |
|
RESTART MISSION <i class="fas fa-redo ml-2"></i> |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="controls" class="rounded-xl p-6"> |
|
<div class="grid grid-cols-3 gap-4 mb-6"> |
|
<div></div> |
|
<button id="up-btn" class="control-btn bg-gradient-to-b from-gray-700 to-gray-900 text-white text-2xl py-6 rounded-lg flex items-center justify-center"> |
|
<i class="fas fa-arrow-up"></i> |
|
</button> |
|
<div></div> |
|
<button id="left-btn" class="control-btn bg-gradient-to-b from-gray-700 to-gray-900 text-white text-2xl py-6 rounded-lg flex items-center justify-center"> |
|
<i class="fas fa-arrow-left"></i> |
|
</button> |
|
<button id="fire-btn" class="control-btn bg-gradient-to-b from-red-700 to-red-900 text-white text-2xl py-6 rounded-lg flex items-center justify-center"> |
|
<i class="fas fa-rocket"></i> |
|
</button> |
|
<button id="right-btn" class="control-btn bg-gradient-to-b from-gray-700 to-gray-900 text-white text-2xl py-6 rounded-lg flex items-center justify-center"> |
|
<i class="fas fa-arrow-right"></i> |
|
</button> |
|
<div></div> |
|
<button id="down-btn" class="control-btn bg-gradient-to-b from-gray-700 to-gray-900 text-white text-2xl py-6 rounded-lg flex items-center justify-center"> |
|
<i class="fas fa-arrow-down"></i> |
|
</button> |
|
<div></div> |
|
</div> |
|
|
|
<p class="text-gray-300 text-center">You can also use ARROW KEYS to move and SPACEBAR to fire</p> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
const canvas = document.getElementById('game-canvas'); |
|
const ctx = canvas.getContext('2d'); |
|
const startScreen = document.getElementById('start-screen'); |
|
const gameOverScreen = document.getElementById('game-over'); |
|
const startBtn = document.getElementById('start-btn'); |
|
const restartBtn = document.getElementById('restart-btn'); |
|
const scoreElement = document.getElementById('score'); |
|
const healthElement = document.getElementById('health'); |
|
const missilesElement = document.getElementById('missiles'); |
|
const finalScoreElement = document.getElementById('final-score'); |
|
|
|
let gameRunning = false; |
|
let score = 0; |
|
let health = 100; |
|
let missiles = 30; |
|
let gameSpeed = 1; |
|
|
|
|
|
function resizeCanvas() { |
|
canvas.width = canvas.clientWidth; |
|
canvas.height = canvas.clientHeight; |
|
} |
|
|
|
window.addEventListener('resize', resizeCanvas); |
|
resizeCanvas(); |
|
|
|
|
|
const player = { |
|
x: 100, |
|
y: canvas.height / 2, |
|
width: 80, |
|
height: 40, |
|
speed: 8, |
|
draw() { |
|
|
|
ctx.fillStyle = '#3498db'; |
|
ctx.fillRect(this.x, this.y, this.width, this.height); |
|
|
|
|
|
ctx.fillStyle = '#85c1e9'; |
|
ctx.beginPath(); |
|
ctx.moveTo(this.x + this.width - 20, this.y + 5); |
|
ctx.lineTo(this.x + this.width - 10, this.y + this.height/2); |
|
ctx.lineTo(this.x + this.width - 20, this.y + this.height - 5); |
|
ctx.closePath(); |
|
ctx.fill(); |
|
|
|
|
|
ctx.fillStyle = '#2980b9'; |
|
ctx.fillRect(this.x + 20, this.y - 10, 40, 10); |
|
ctx.fillRect(this.x + 20, this.y + this.height, 40, 10); |
|
|
|
|
|
ctx.fillStyle = '#1f618d'; |
|
ctx.fillRect(this.x, this.y + 10, 15, 20); |
|
} |
|
}; |
|
|
|
|
|
let enemies = []; |
|
|
|
|
|
let missilesArray = []; |
|
|
|
|
|
function createExplosion(x, y) { |
|
const explosion = document.createElement('div'); |
|
explosion.className = 'explosion'; |
|
explosion.style.left = (x - 50) + 'px'; |
|
explosion.style.top = (y - 50) + 'px'; |
|
document.querySelector('.relative').appendChild(explosion); |
|
|
|
|
|
setTimeout(() => { |
|
explosion.remove(); |
|
}, 600); |
|
} |
|
|
|
|
|
function createCloud() { |
|
const cloud = document.createElement('div'); |
|
cloud.className = 'cloud'; |
|
|
|
|
|
const size = Math.random() * 100 + 50; |
|
cloud.style.width = size + 'px'; |
|
cloud.style.height = size/2 + 'px'; |
|
|
|
|
|
const yPos = Math.random() * canvas.height; |
|
cloud.style.left = canvas.width + 100 + 'px'; |
|
cloud.style.top = yPos + 'px'; |
|
|
|
|
|
cloud.style.opacity = Math.random() * 0.5 + 0.2; |
|
|
|
document.querySelector('.relative').appendChild(cloud); |
|
|
|
|
|
let xPos = canvas.width + 100; |
|
const cloudSpeed = Math.random() * 0.5 + 0.2; |
|
|
|
const moveCloud = setInterval(() => { |
|
if (!gameRunning) { |
|
clearInterval(moveCloud); |
|
cloud.remove(); |
|
return; |
|
} |
|
|
|
xPos -= cloudSpeed; |
|
cloud.style.left = xPos + 'px'; |
|
|
|
if (xPos < -200) { |
|
clearInterval(moveCloud); |
|
cloud.remove(); |
|
} |
|
}, 20); |
|
} |
|
|
|
|
|
setInterval(() => { |
|
if (gameRunning) { |
|
createCloud(); |
|
} |
|
}, 3000); |
|
|
|
|
|
class Enemy { |
|
constructor() { |
|
this.width = 60; |
|
this.height = 30; |
|
this.x = canvas.width + 100; |
|
this.y = Math.random() * (canvas.height - 100) + 50; |
|
this.speed = Math.random() * 3 + 2; |
|
this.color = `hsl(${Math.random() * 60}, 80%, 40%)`; |
|
} |
|
|
|
draw() { |
|
|
|
ctx.fillStyle = this.color; |
|
ctx.fillRect(this.x, this.y, this.width, this.height); |
|
|
|
|
|
ctx.fillStyle = '#e74c3c'; |
|
ctx.beginPath(); |
|
ctx.moveTo(this.x + 10, this.y + 5); |
|
ctx.lineTo(this.x + 20, this.y + this.height/2); |
|
ctx.lineTo(this.x + 10, this.y + this.height - 5); |
|
ctx.closePath(); |
|
ctx.fill(); |
|
|
|
|
|
ctx.fillStyle = '#c0392b'; |
|
ctx.fillRect(this.x + this.width - 40, this.y - 8, 30, 8); |
|
ctx.fillRect(this.x + this.width - 40, this.y + this.height, 30, 8); |
|
} |
|
|
|
update() { |
|
this.x -= this.speed * gameSpeed; |
|
|
|
|
|
this.draw(); |
|
|
|
|
|
if (this.x < player.x + player.width && |
|
this.x + this.width > player.x && |
|
this.y < player.y + player.height && |
|
this.y + this.height > player.y) { |
|
createExplosion(player.x + player.width/2, player.y + player.height/2); |
|
takeDamage(20); |
|
return false; |
|
} |
|
|
|
|
|
return this.x + this.width > 0; |
|
} |
|
} |
|
|
|
|
|
class Missile { |
|
constructor() { |
|
this.x = player.x + player.width; |
|
this.y = player.y + player.height / 2; |
|
this.width = 20; |
|
this.height = 10; |
|
this.speed = 15; |
|
this.color = '#f1c40f'; |
|
} |
|
|
|
draw() { |
|
|
|
ctx.fillStyle = this.color; |
|
ctx.fillRect(this.x, this.y, this.width, this.height); |
|
|
|
|
|
ctx.fillStyle = '#e74c3c'; |
|
ctx.beginPath(); |
|
ctx.moveTo(this.x + this.width, this.y); |
|
ctx.lineTo(this.x + this.width + 10, this.y + this.height/2); |
|
ctx.lineTo(this.x + this.width, this.y + this.height); |
|
ctx.closePath(); |
|
ctx.fill(); |
|
} |
|
|
|
update() { |
|
this.x += this.speed * gameSpeed; |
|
|
|
|
|
this.draw(); |
|
|
|
|
|
for (let i = 0; i < enemies.length; i++) { |
|
const enemy = enemies[i]; |
|
if (this.x < enemy.x + enemy.width && |
|
this.x + this.width > enemy.x && |
|
this.y < enemy.y + enemy.height && |
|
this.y + this.height > enemy.y) { |
|
createExplosion(enemy.x + enemy.width/2, enemy.y + enemy.height/2); |
|
score += 100; |
|
scoreElement.textContent = score; |
|
return false; |
|
} |
|
} |
|
|
|
|
|
return this.x < canvas.width; |
|
} |
|
} |
|
|
|
|
|
function takeDamage(amount) { |
|
health -= amount; |
|
if (health < 0) health = 0; |
|
healthElement.textContent = health; |
|
|
|
if (health <= 0) { |
|
endGame(); |
|
} |
|
} |
|
|
|
|
|
function spawnEnemy() { |
|
if (!gameRunning) return; |
|
|
|
if (Math.random() < 0.03) { |
|
enemies.push(new Enemy()); |
|
} |
|
|
|
|
|
gameSpeed = 1 + score * 0.0001; |
|
} |
|
|
|
|
|
function fireMissile() { |
|
if (!gameRunning || missiles <= 0) return; |
|
|
|
missiles--; |
|
missilesElement.textContent = missiles; |
|
missilesArray.push(new Missile()); |
|
} |
|
|
|
|
|
function endGame() { |
|
gameRunning = false; |
|
finalScoreElement.textContent = score; |
|
gameOverScreen.classList.remove('hidden'); |
|
} |
|
|
|
|
|
function gameLoop() { |
|
if (!gameRunning) return; |
|
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height); |
|
|
|
|
|
player.draw(); |
|
|
|
|
|
spawnEnemy(); |
|
|
|
|
|
enemies = enemies.filter(enemy => enemy.update()); |
|
|
|
|
|
missilesArray = missilesArray.filter(missile => missile.update()); |
|
|
|
requestAnimationFrame(gameLoop); |
|
} |
|
|
|
|
|
startBtn.addEventListener('click', () => { |
|
startScreen.classList.add('hidden'); |
|
gameRunning = true; |
|
score = 0; |
|
health = 100; |
|
missiles = 30; |
|
|
|
scoreElement.textContent = score; |
|
healthElement.textContent = health; |
|
missilesElement.textContent = missiles; |
|
|
|
|
|
player.y = canvas.height / 2; |
|
|
|
|
|
enemies = []; |
|
missilesArray = []; |
|
|
|
gameLoop(); |
|
}); |
|
|
|
|
|
restartBtn.addEventListener('click', () => { |
|
gameOverScreen.classList.add('hidden'); |
|
startScreen.classList.remove('hidden'); |
|
}); |
|
|
|
|
|
const keys = {}; |
|
|
|
window.addEventListener('keydown', (e) => { |
|
keys[e.key] = true; |
|
|
|
if (e.key === ' ' && gameRunning) { |
|
fireMissile(); |
|
} |
|
}); |
|
|
|
window.addEventListener('keyup', (e) => { |
|
keys[e.key] = false; |
|
}); |
|
|
|
|
|
document.getElementById('up-btn').addEventListener('touchstart', (e) => { |
|
e.preventDefault(); |
|
player.y -= player.speed; |
|
}); |
|
|
|
document.getElementById('down-btn').addEventListener('touchstart', (e) => { |
|
e.preventDefault(); |
|
player.y += player.speed; |
|
}); |
|
|
|
document.getElementById('left-btn').addEventListener('touchstart', (e) => { |
|
e.preventDefault(); |
|
player.x -= player.speed; |
|
}); |
|
|
|
document.getElementById('right-btn').addEventListener('touchstart', (e) => { |
|
e.preventDefault(); |
|
player.x += player.speed; |
|
}); |
|
|
|
document.getElementById('fire-btn').addEventListener('touchstart', (e) => { |
|
e.preventDefault(); |
|
if (gameRunning) fireMissile(); |
|
}); |
|
|
|
|
|
function handleMovement() { |
|
if (!gameRunning) return; |
|
|
|
if (keys['ArrowUp'] || keys['w'] || keys['W']) { |
|
player.y -= player.speed; |
|
} |
|
if (keys['ArrowDown'] || keys['s'] || keys['S']) { |
|
player.y += player.speed; |
|
} |
|
if (keys['ArrowLeft'] || keys['a'] || keys['A']) { |
|
player.x -= player.speed; |
|
} |
|
if (keys['ArrowRight'] || keys['d'] || keys['D']) { |
|
player.x += player.speed; |
|
} |
|
|
|
|
|
if (player.y < 10) player.y = 10; |
|
if (player.y > canvas.height - player.height - 10) player.y = canvas.height - player.height - 10; |
|
if (player.x < 10) player.x = 10; |
|
if (player.x > canvas.width - player.width - 10) player.x = canvas.width - player.width - 10; |
|
|
|
requestAnimationFrame(handleMovement); |
|
} |
|
|
|
handleMovement(); |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=aryansrk/trail" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |