Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Call of Duty: Web Ops</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"> | |
<style> | |
@keyframes gunRecoil { | |
0% { transform: translateY(0) translateX(-50%); } | |
50% { transform: translateY(10px) translateX(-50%); } | |
100% { transform: translateY(0) translateX(-50%); } | |
} | |
@keyframes muzzleFlash { | |
0% { opacity: 0; transform: scale(0.5); } | |
50% { opacity: 1; transform: scale(1.2); } | |
100% { opacity: 0; transform: scale(0.5); } | |
} | |
@keyframes bloodSplatter { | |
0% { opacity: 0; transform: scale(0.5); } | |
50% { opacity: 0.8; transform: scale(1); } | |
100% { opacity: 0; transform: scale(1.2); } | |
} | |
@keyframes enemyHit { | |
0% { transform: translateX(0); } | |
25% { transform: translateX(-5px); } | |
50% { transform: translateX(5px); } | |
75% { transform: translateX(-5px); } | |
100% { transform: translateX(0); } | |
} | |
.gun { | |
transition: transform 0.1s ease; | |
} | |
.recoil { | |
animation: gunRecoil 0.1s ease-out; | |
} | |
.muzzle-flash { | |
position: absolute; | |
width: 60px; | |
height: 60px; | |
background: radial-gradient(circle, rgba(255,165,0,0.8) 0%, rgba(255,69,0,0) 70%); | |
border-radius: 50%; | |
pointer-events: none; | |
z-index: 10; | |
animation: muzzleFlash 0.05s ease-out; | |
} | |
.blood-effect { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M30,50 Q40,30 50,50 Q60,70 70,50 Q80,30 50,10 Q20,30 30,50 Z" fill="rgba(139,0,0,0.3)"/></svg>'); | |
background-size: 200px 200px; | |
pointer-events: none; | |
z-index: 5; | |
animation: bloodSplatter 0.5s ease-out; | |
} | |
.hitmarker { | |
position: absolute; | |
width: 30px; | |
height: 30px; | |
border: 2px solid white; | |
pointer-events: none; | |
z-index: 15; | |
opacity: 0; | |
} | |
.hitmarker.active { | |
animation: hitmarkerFade 0.3s ease-out; | |
} | |
@keyframes hitmarkerFade { | |
0% { transform: scale(0.5); opacity: 1; } | |
100% { transform: scale(1.5); opacity: 0; } | |
} | |
.enemy-hit { | |
animation: enemyHit 0.3s ease-out; | |
} | |
.scope-overlay { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
background: radial-gradient(circle, transparent 40%, rgba(0,0,0,0.7) 40.2%); | |
pointer-events: none; | |
z-index: 5; | |
} | |
.health-bar { | |
transition: width 0.3s ease; | |
} | |
.ammo-counter { | |
text-shadow: 0 0 5px rgba(255,255,255,0.7); | |
} | |
.kill-feed { | |
position: absolute; | |
top: 20px; | |
right: 20px; | |
width: 250px; | |
max-height: 200px; | |
overflow: hidden; | |
} | |
.kill-entry { | |
background: rgba(0,0,0,0.7); | |
color: white; | |
padding: 5px 10px; | |
margin-bottom: 5px; | |
border-left: 3px solid #e74c3c; | |
transform: translateX(100%); | |
animation: slideIn 0.3s forwards, fadeOut 0.3s 3s forwards; | |
} | |
@keyframes slideIn { | |
to { transform: translateX(0); } | |
} | |
@keyframes fadeOut { | |
to { opacity: 0; max-height: 0; padding: 0; margin: 0; } | |
} | |
</style> | |
</head> | |
<body class="bg-gray-900 text-white overflow-hidden h-screen"> | |
<!-- Blood effect --> | |
<div id="bloodEffect" class="blood-effect opacity-0"></div> | |
<!-- Hitmarker --> | |
<div id="hitmarker" class="hitmarker"></div> | |
<!-- Scope overlay --> | |
<div id="scopeOverlay" class="scope-overlay hidden"></div> | |
<!-- Kill feed --> | |
<div id="killFeed" class="kill-feed"></div> | |
<!-- Game HUD --> | |
<div class="absolute bottom-0 left-0 right-0 p-4 z-10"> | |
<div class="flex justify-between items-end"> | |
<!-- Health --> | |
<div class="bg-gray-800 rounded-lg p-3 w-40"> | |
<div class="flex items-center mb-1"> | |
<i class="fas fa-heartbeat text-red-500 mr-2"></i> | |
<span class="font-bold">HEALTH</span> | |
</div> | |
<div class="bg-gray-700 h-4 rounded-full overflow-hidden"> | |
<div id="healthBar" class="health-bar bg-red-500 h-full rounded-full" style="width: 100%"></div> | |
</div> | |
</div> | |
<!-- Ammo --> | |
<div class="bg-gray-800 rounded-lg p-3 text-center"> | |
<div id="ammoCounter" class="ammo-counter text-2xl font-bold"> | |
<span id="currentAmmo">30</span> / <span id="totalAmmo">90</span> | |
</div> | |
<div class="text-xs mt-1">M4A1 | 5.56mm</div> | |
</div> | |
<!-- Score --> | |
<div class="bg-gray-800 rounded-lg p-3 w-40 text-right"> | |
<div class="flex justify-end items-center"> | |
<i class="fas fa-skull text-yellow-500 ml-2"></i> | |
<span class="font-bold">KILLS</span> | |
</div> | |
<div id="killCount" class="text-2xl font-bold">0</div> | |
</div> | |
</div> | |
</div> | |
<!-- Gun --> | |
<div id="gun" class="gun absolute bottom-10 left-1/2 transform -translate-x-1/2 w-64 h-64 z-20"> | |
<div class="relative w-full h-full"> | |
<!-- Rifle --> | |
<div class="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-48 h-32 bg-gradient-to-r from-gray-700 to-gray-800 rounded-lg"> | |
<!-- Barrel --> | |
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 w-40 h-6 bg-gray-800 rounded-t-lg"></div> | |
<!-- Stock --> | |
<div class="absolute bottom-0 right-0 w-16 h-24 bg-gray-900 rounded-br-lg"></div> | |
<!-- Magazine --> | |
<div class="absolute bottom-4 left-4 w-8 h-16 bg-gray-600 rounded"></div> | |
<!-- Scope --> | |
<div class="absolute top-2 left-1/2 transform -translate-x-1/2 w-12 h-6 bg-gray-900 rounded-lg flex justify-center items-center"> | |
<div class="w-1 h-1 bg-red-500 rounded-full"></div> | |
</div> | |
<!-- Trigger --> | |
<div class="absolute bottom-8 right-8 w-4 h-2 bg-gray-900 rounded"></div> | |
</div> | |
<!-- Muzzle flash (hidden by default) --> | |
<div id="muzzleFlash" class="muzzle-flash hidden top-10 left-1/2 transform -translate-x-1/2"></div> | |
</div> | |
</div> | |
<!-- Enemies container --> | |
<div id="enemiesContainer" class="absolute top-0 left-0 w-full h-full"></div> | |
<!-- Game Over Screen --> | |
<div id="gameOverScreen" class="absolute inset-0 bg-black bg-opacity-90 flex flex-col items-center justify-center hidden z-30"> | |
<div class="bg-gray-800 p-8 rounded-xl max-w-md w-full text-center border border-red-500"> | |
<h2 class="text-3xl font-bold text-red-500 mb-4">MISSION FAILED</h2> | |
<div class="mb-6"> | |
<p class="text-xl">Total Kills: <span id="finalKills" class="font-bold text-white">0</span></p> | |
<p class="text-xl mt-2">Accuracy: <span id="finalAccuracy" class="font-bold text-white">0%</span></p> | |
</div> | |
<button id="restartBtn" class="bg-gradient-to-r from-red-700 to-gray-900 px-6 py-3 rounded-full font-bold hover:opacity-90 transition border border-red-500 w-full"> | |
<i class="fas fa-redo mr-2"></i> Redeploy | |
</button> | |
</div> | |
</div> | |
<!-- Start Screen --> | |
<div id="startScreen" class="absolute inset-0 bg-black bg-opacity-90 flex flex-col items-center justify-center z-30"> | |
<div class="bg-gray-800 p-8 rounded-xl max-w-md w-full text-center border border-red-500"> | |
<h1 class="text-4xl font-bold bg-gradient-to-r from-red-500 to-yellow-500 bg-clip-text text-transparent mb-6"> | |
CALL OF DUTY: WEB OPS | |
</h1> | |
<div class="mb-8"> | |
<div class="w-full h-40 bg-gray-900 rounded-lg relative overflow-hidden mb-4"> | |
<div class="absolute inset-0 flex items-center justify-center"> | |
<div class="w-24 h-24 bg-red-500 rounded-full animate-pulse"></div> | |
</div> | |
</div> | |
<p class="text-gray-300 mb-2">Eliminate all hostile targets</p> | |
<p class="text-gray-400 text-sm">Watch your ammo and health</p> | |
</div> | |
<button id="startBtn" class="bg-gradient-to-r from-red-700 to-gray-900 px-6 py-3 rounded-full font-bold hover:opacity-90 transition border border-red-500 w-full"> | |
<i class="fas fa-play mr-2"></i> Deploy Now | |
</button> | |
<div class="mt-6 text-sm text-gray-500"> | |
<p>Click to shoot | WASD to move | Space to jump</p> | |
<p class="mt-2">Right click to aim down sights</p> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', () => { | |
// Game elements | |
const gameContainer = document.body; | |
const gun = document.getElementById('gun'); | |
const muzzleFlash = document.getElementById('muzzleFlash'); | |
const healthBar = document.getElementById('healthBar'); | |
const currentAmmo = document.getElementById('currentAmmo'); | |
const totalAmmo = document.getElementById('totalAmmo'); | |
const killCount = document.getElementById('killCount'); | |
const bloodEffect = document.getElementById('bloodEffect'); | |
const hitmarker = document.getElementById('hitmarker'); | |
const scopeOverlay = document.getElementById('scopeOverlay'); | |
const killFeed = document.getElementById('killFeed'); | |
const startScreen = document.getElementById('startScreen'); | |
const gameOverScreen = document.getElementById('gameOverScreen'); | |
const finalKills = document.getElementById('finalKills'); | |
const finalAccuracy = document.getElementById('finalAccuracy'); | |
const startBtn = document.getElementById('startBtn'); | |
const restartBtn = document.getElementById('restartBtn'); | |
const enemiesContainer = document.getElementById('enemiesContainer'); | |
// Game state | |
let gameRunning = false; | |
let health = 100; | |
let ammo = 30; | |
let totalAmmoCount = 90; | |
let kills = 0; | |
let shotsFired = 0; | |
let shotsHit = 0; | |
let enemies = []; | |
let enemySpawnInterval; | |
let gameLoopInterval; | |
let isAiming = false; | |
let playerPosition = { x: 0, y: 0 }; | |
let mouseX = 0; | |
let mouseY = 0; | |
// Initialize game | |
initGame(); | |
// Event listeners | |
startBtn.addEventListener('click', startGame); | |
restartBtn.addEventListener('click', startGame); | |
// Mouse controls | |
gameContainer.addEventListener('mousedown', (e) => { | |
if (!gameRunning) return; | |
if (e.button === 0) { // Left click | |
shoot(); | |
} else if (e.button === 2) { // Right click | |
aimDownSights(true); | |
} | |
}); | |
gameContainer.addEventListener('mouseup', (e) => { | |
if (e.button === 2) { // Right click release | |
aimDownSights(false); | |
} | |
}); | |
gameContainer.addEventListener('mousemove', (e) => { | |
mouseX = e.clientX; | |
mouseY = e.clientY; | |
// Slight gun movement based on mouse position | |
if (gameRunning) { | |
const moveX = (mouseX - window.innerWidth / 2) / 50; | |
const moveY = (mouseY - window.innerHeight / 2) / 50; | |
gun.style.transform = `translateX(-50%) translateY(${moveY}px) translateX(${moveX}px)`; | |
} | |
}); | |
gameContainer.addEventListener('contextmenu', (e) => { | |
e.preventDefault(); // Prevent context menu on right click | |
}); | |
// Keyboard controls | |
document.addEventListener('keydown', (e) => { | |
if (!gameRunning) return; | |
switch (e.key.toLowerCase()) { | |
case 'w': | |
playerPosition.y = -5; | |
break; | |
case 'a': | |
playerPosition.x = -5; | |
break; | |
case 's': | |
playerPosition.y = 5; | |
break; | |
case 'd': | |
playerPosition.x = 5; | |
break; | |
case ' ': | |
// Jump action | |
break; | |
case 'r': | |
reload(); | |
break; | |
} | |
}); | |
document.addEventListener('keyup', (e) => { | |
switch (e.key.toLowerCase()) { | |
case 'w': | |
case 's': | |
playerPosition.y = 0; | |
break; | |
case 'a': | |
case 'd': | |
playerPosition.x = 0; | |
break; | |
} | |
}); | |
// Game functions | |
function initGame() { | |
// Reset game state | |
health = 100; | |
ammo = 30; | |
totalAmmoCount = 90; | |
kills = 0; | |
shotsFired = 0; | |
shotsHit = 0; | |
enemies = []; | |
// Update UI | |
healthBar.style.width = '100%'; | |
currentAmmo.textContent = ammo; | |
totalAmmo.textContent = totalAmmoCount; | |
killCount.textContent = kills; | |
// Clear enemies | |
enemiesContainer.innerHTML = ''; | |
// Show start screen | |
startScreen.classList.remove('hidden'); | |
gameOverScreen.classList.add('hidden'); | |
} | |
function startGame() { | |
initGame(); | |
// Hide screens | |
startScreen.classList.add('hidden'); | |
gameOverScreen.classList.add('hidden'); | |
// Start game | |
gameRunning = true; | |
// Start game loop | |
gameLoopInterval = setInterval(updateGame, 16); // ~60fps | |
// Start spawning enemies | |
enemySpawnInterval = setInterval(spawnEnemy, 2000); | |
// Initial enemy spawn | |
for (let i = 0; i < 3; i++) { | |
setTimeout(spawnEnemy, i * 500); | |
} | |
} | |
function updateGame() { | |
// Move player (simple movement for this demo) | |
// In a full game, this would update the camera position | |
// Move enemies | |
enemies.forEach(enemy => { | |
// Simple movement - in a real game this would be more sophisticated AI | |
enemy.element.style.left = `${enemy.x}px`; | |
enemy.element.style.top = `${enemy.y}px`; | |
// Random movement | |
if (Math.random() < 0.02) { | |
enemy.vx = (Math.random() - 0.5) * 2; | |
} | |
if (Math.random() < 0.02) { | |
enemy.vy = (Math.random() - 0.5) * 2; | |
} | |
enemy.x += enemy.vx; | |
enemy.y += enemy.vy; | |
// Keep enemies in bounds | |
enemy.x = Math.max(0, Math.min(window.innerWidth - 50, enemy.x)); | |
enemy.y = Math.max(0, Math.min(window.innerHeight - 80, enemy.y)); | |
// Random shooting at player | |
if (Math.random() < 0.005) { | |
enemyShoot(enemy); | |
} | |
}); | |
// Check if player is dead | |
if (health <= 0) { | |
endGame(); | |
} | |
} | |
function spawnEnemy() { | |
if (!gameRunning || enemies.length >= 10) return; | |
const enemy = document.createElement('div'); | |
enemy.className = 'absolute w-12 h-20 bg-gray-700 rounded-lg flex flex-col items-center'; | |
// Random position at edges of screen | |
const side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left | |
let x, y; | |
switch (side) { | |
case 0: // top | |
x = Math.random() * window.innerWidth; | |
y = -50; | |
break; | |
case 1: // right | |
x = window.innerWidth; | |
y = Math.random() * window.innerHeight; | |
break; | |
case 2: // bottom | |
x = Math.random() * window.innerWidth; | |
y = window.innerHeight; | |
break; | |
case 3: // left | |
x = -50; | |
y = Math.random() * window.innerHeight; | |
break; | |
} | |
enemy.style.left = `${x}px`; | |
enemy.style.top = `${y}px`; | |
// Enemy appearance | |
enemy.innerHTML = ` | |
<div class="w-10 h-6 bg-gray-800 rounded-t-lg mt-1 flex justify-center items-center"> | |
<div class="w-2 h-2 bg-red-500 rounded-full"></div> | |
</div> | |
<div class="w-full h-12 bg-gray-600 rounded-b-lg flex justify-center items-center"> | |
<i class="fas fa-skull text-gray-400 text-xl"></i> | |
</div> | |
`; | |
enemiesContainer.appendChild(enemy); | |
enemies.push({ | |
element: enemy, | |
x: x, | |
y: y, | |
vx: (Math.random() - 0.5) * 2, | |
vy: (Math.random() - 0.5) * 2, | |
health: 100 | |
}); | |
} | |
function shoot() { | |
if (ammo <= 0) { | |
// Play empty click sound | |
return; | |
} | |
// Deduct ammo | |
ammo--; | |
shotsFired++; | |
currentAmmo.textContent = ammo; | |
// Gun recoil animation | |
gun.classList.add('recoil'); | |
setTimeout(() => { | |
gun.classList.remove('recoil'); | |
}, 100); | |
// Muzzle flash | |
muzzleFlash.classList.remove('hidden'); | |
setTimeout(() => { | |
muzzleFlash.classList.add('hidden'); | |
}, 50); | |
// Check for hits | |
const hitEnemy = checkHit(); | |
if (hitEnemy) { | |
shotsHit++; | |
hitEnemy.health -= 34; // 3 shots to kill | |
// Hitmarker | |
hitmarker.style.left = `${mouseX - 15}px`; | |
hitmarker.style.top = `${mouseY - 15}px`; | |
hitmarker.classList.add('active'); | |
setTimeout(() => { | |
hitmarker.classList.remove('active'); | |
}, 300); | |
// Enemy hit reaction | |
hitEnemy.element.classList.add('enemy-hit'); | |
setTimeout(() => { | |
hitEnemy.element.classList.remove('enemy-hit'); | |
}, 300); | |
// Check if enemy died | |
if (hitEnemy.health <= 0) { | |
killEnemy(hitEnemy); | |
} | |
} | |
// Reload if empty | |
if (ammo === 0 && totalAmmoCount > 0) { | |
setTimeout(reload, 500); | |
} | |
} | |
function checkHit() { | |
// Simple hit detection - in a real game this would use proper raycasting | |
const mousePos = { x: mouseX, y: mouseY }; | |
for (let i = 0; i < enemies.length; i++) { | |
const enemy = enemies[i]; | |
const enemyRect = enemy.element.getBoundingClientRect(); | |
if ( | |
mousePos.x >= enemyRect.left && | |
mousePos.x <= enemyRect.right && | |
mousePos.y >= enemyRect.top && | |
mousePos.y <= enemyRect.bottom | |
) { | |
return enemy; | |
} | |
} | |
return null; | |
} | |
function killEnemy(enemy) { | |
// Remove enemy | |
enemy.element.remove(); | |
enemies = enemies.filter(e => e !== enemy); | |
// Increase kill count | |
kills++; | |
killCount.textContent = kills; | |
// Add to kill feed | |
addKillFeed(); | |
// Spawn new enemy after delay | |
setTimeout(spawnEnemy, 1000); | |
} | |
function addKillFeed() { | |
const killEntry = document.createElement('div'); | |
killEntry.className = 'kill-entry'; | |
killEntry.textContent = `You killed Enemy`; | |
killFeed.appendChild(killEntry); | |
// Auto-remove after animation | |
setTimeout(() => { | |
killEntry.remove(); | |
}, 3500); | |
} | |
function enemyShoot(enemy) { | |
// Simple chance to hit player | |
if (Math.random() < 0.3) { | |
const damage = 10 + Math.floor(Math.random() * 15); | |
health -= damage; | |
healthBar.style.width = `${health}%`; | |
// Blood effect | |
bloodEffect.style.opacity = '0.5'; | |
bloodEffect.classList.add('blood-effect'); | |
setTimeout(() => { | |
bloodEffect.style.opacity = '0'; | |
}, 500); | |
// Check if player died | |
if (health <= 0) { | |
endGame(); | |
} | |
} | |
} | |
function reload() { | |
if (totalAmmoCount <= 0) return; | |
const ammoNeeded = 30 - ammo; | |
const ammoToReload = Math.min(ammoNeeded, totalAmmoCount); | |
totalAmmoCount -= ammoToReload; | |
ammo += ammoToReload; | |
currentAmmo.textContent = ammo; | |
totalAmmo.textContent = totalAmmoCount; | |
// Play reload sound in a real game | |
} | |
function aimDownSights(aiming) { | |
isAiming = aiming; | |
if (aiming) { | |
scopeOverlay.classList.remove('hidden'); | |
gun.style.transform = 'translateX(-50%) scale(1.2)'; | |
} else { | |
scopeOverlay.classList.add('hidden'); | |
gun.style.transform = 'translateX(-50%)'; | |
} | |
} | |
function endGame() { | |
gameRunning = false; | |
// Stop game loops | |
clearInterval(gameLoopInterval); | |
clearInterval(enemySpawnInterval); | |
// Calculate accuracy | |
const accuracy = shotsFired > 0 ? Math.round((shotsHit / shotsFired) * 100) : 0; | |
// Update final stats | |
finalKills.textContent = kills; | |
finalAccuracy.textContent = `${accuracy}%`; | |
// Show game over screen | |
gameOverScreen.classList.remove('hidden'); | |
} | |
}); | |
</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=Amirreza12cv0/call-of-duty" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |