bomb-defusal / index.html
randt's picture
Add 2 files
e48dbbe verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>8-Bit Bomb Defusal</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
body {
font-family: 'Press Start 2P', cursive;
background-color: #1a1a2e;
overflow: hidden;
user-select: none;
}
.pixel {
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
image-rendering: crisp-edges;
}
.screen-shake {
animation: shake 0.1s infinite;
}
@keyframes shake {
0% { transform: translate(1px, 1px); }
10% { transform: translate(-1px, -2px); }
20% { transform: translate(-2px, 0px); }
30% { transform: translate(2px, 2px); }
40% { transform: translate(1px, -1px); }
50% { transform: translate(-1px, 2px); }
60% { transform: translate(-2px, 1px); }
70% { transform: translate(2px, 1px); }
80% { transform: translate(-1px, -1px); }
90% { transform: translate(1px, 2px); }
100% { transform: translate(0px, 0px); }
}
.wire-cut {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 0.5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
.explosion {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(255,100,0,0.8) 0%, rgba(255,0,0,0.8) 70%, rgba(0,0,0,0.9) 100%);
z-index: 100;
opacity: 0;
pointer-events: none;
}
.success {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(100,255,100,0.6) 0%, rgba(0,200,0,0.8) 70%, rgba(0,100,0,0.9) 100%);
z-index: 100;
opacity: 0;
pointer-events: none;
}
</style>
</head>
<body class="flex items-center justify-center h-screen">
<div id="game-container" class="relative w-full max-w-md h-96 bg-gray-900 border-4 border-gray-700 rounded-lg overflow-hidden">
<!-- Title Screen -->
<div id="title-screen" class="absolute inset-0 flex flex-col items-center justify-center bg-gray-900 z-50">
<h1 class="text-3xl text-green-400 mb-8">BOMB DEFUSAL</h1>
<div class="text-yellow-300 text-center mb-8">
<p class="mb-2">Cut the correct wire</p>
<p>before time runs out!</p>
</div>
<button id="start-btn" class="px-6 py-3 bg-red-500 text-white hover:bg-red-600 transition-all border-b-4 border-red-700 active:border-b-2 active:mt-1">
START MISSION
</button>
<div class="absolute bottom-4 text-gray-500 text-xs">
<p>Difficulty: HARD</p>
<p>Screen will shake!</p>
</div>
</div>
<!-- Game Screen -->
<div id="game-screen" class="absolute inset-0 hidden flex flex-col items-center justify-center">
<div class="relative w-full h-full">
<!-- Bomb -->
<div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div class="relative">
<!-- Bomb body -->
<div class="w-24 h-32 bg-gray-800 rounded-full mx-auto border-4 border-gray-700">
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-6 h-6 bg-red-600 rounded-full"></div>
<div class="absolute top-4 left-1/2 transform -translate-x-1/2 w-16 h-16 bg-gray-700 rounded-full flex items-center justify-center">
<div class="w-12 h-12 bg-gray-800 rounded-full flex items-center justify-center">
<div id="timer" class="text-red-500 text-xl">30</div>
</div>
</div>
</div>
<!-- Wires -->
<svg width="300" height="100" viewBox="0 0 300 100" class="absolute top-24 left-1/2 transform -translate-x-1/2">
<!-- Wire 1 (Red) -->
<path id="wire1" d="M50,50 L150,50" stroke="red" stroke-width="4" stroke-linecap="round" class="cursor-pointer hover:stroke-yellow-300" />
<circle cx="50" cy="50" r="8" fill="#333" />
<circle cx="150" cy="50" r="8" fill="#333" />
<!-- Wire 2 (Blue) -->
<path id="wire2" d="M50,50 L150,50" stroke="blue" stroke-width="4" stroke-linecap="round" class="cursor-pointer hover:stroke-yellow-300" />
<circle cx="50" cy="50" r="8" fill="#333" />
<circle cx="150" cy="50" r="8" fill="#333" />
<!-- Wire 3 (Green) -->
<path id="wire3" d="M50,50 L150,50" stroke="green" stroke-width="4" stroke-linecap="round" class="cursor-pointer hover:stroke-yellow-300" />
<circle cx="50" cy="50" r="8" fill="#333" />
<circle cx="150" cy="50" r="8" fill="#333" />
</svg>
<!-- Boxes -->
<div class="absolute top-32 left-1/2 transform -translate-x-1/2 flex space-x-16">
<div class="w-16 h-16 bg-gray-700 border-2 border-gray-600 flex items-center justify-center">
<div class="w-12 h-12 bg-gray-800"></div>
</div>
<div class="w-16 h-16 bg-gray-700 border-2 border-gray-600 flex items-center justify-center">
<div class="w-12 h-12 bg-gray-800"></div>
</div>
</div>
</div>
</div>
<!-- Timer bar -->
<div class="absolute bottom-4 left-1/2 transform -translate-x-1/2 w-64 h-4 bg-gray-800 border-2 border-gray-700">
<div id="time-bar" class="h-full bg-red-500"></div>
</div>
</div>
</div>
<!-- Explosion effect -->
<div id="explosion" class="explosion"></div>
<!-- Success effect -->
<div id="success" class="success"></div>
<!-- Game Over Screen -->
<div id="game-over" class="absolute inset-0 hidden flex flex-col items-center justify-center bg-gray-900 bg-opacity-90 z-50">
<h1 class="text-3xl text-red-500 mb-4">BOOM!</h1>
<p class="text-white mb-8">Mission failed</p>
<button id="retry-btn" class="px-6 py-3 bg-gray-700 text-white hover:bg-gray-600 transition-all border-b-4 border-gray-800 active:border-b-2 active:mt-1">
TRY AGAIN
</button>
</div>
<!-- Success Screen -->
<div id="success-screen" class="absolute inset-0 hidden flex flex-col items-center justify-center bg-gray-900 bg-opacity-90 z-50">
<h1 class="text-3xl text-green-400 mb-4">DEFUSED!</h1>
<p class="text-white mb-8">Mission accomplished</p>
<button id="next-btn" class="px-6 py-3 bg-green-600 text-white hover:bg-green-500 transition-all border-b-4 border-green-700 active:border-b-2 active:mt-1">
NEXT BOMB
</button>
</div>
</div>
<audio id="tick-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-clock-countdown-bleeps-916.mp3" preload="auto"></audio>
<audio id="cut-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-retro-arcade-game-over-470.mp3" preload="auto"></audio>
<audio id="explosion-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-bomb-explosion-1700.mp3" preload="auto"></audio>
<audio id="success-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3" preload="auto"></audio>
<script>
// Game state
let gameActive = false;
let timeLeft = 30;
let timerInterval;
let correctWire;
let screenShakeInterval;
// DOM elements
const titleScreen = document.getElementById('title-screen');
const gameScreen = document.getElementById('game-screen');
const gameOverScreen = document.getElementById('game-over');
const successScreen = document.getElementById('success-screen');
const startBtn = document.getElementById('start-btn');
const retryBtn = document.getElementById('retry-btn');
const nextBtn = document.getElementById('next-btn');
const timerDisplay = document.getElementById('timer');
const timeBar = document.getElementById('time-bar');
const wire1 = document.getElementById('wire1');
const wire2 = document.getElementById('wire2');
const wire3 = document.getElementById('wire3');
const explosion = document.getElementById('explosion');
const successEffect = document.getElementById('success');
const gameContainer = document.getElementById('game-container');
const tickSound = document.getElementById('tick-sound');
const cutSound = document.getElementById('cut-sound');
const explosionSound = document.getElementById('explosion-sound');
const successSound = document.getElementById('success-sound');
// Start game
startBtn.addEventListener('click', startGame);
retryBtn.addEventListener('click', startGame);
nextBtn.addEventListener('click', startGame);
function startGame() {
// Reset game state
gameActive = true;
timeLeft = 30;
correctWire = Math.floor(Math.random() * 3) + 1; // 1, 2, or 3
// Show game screen
titleScreen.classList.add('hidden');
gameOverScreen.classList.add('hidden');
successScreen.classList.add('hidden');
gameScreen.classList.remove('hidden');
// Reset wires
wire1.classList.remove('wire-cut');
wire2.classList.remove('wire-cut');
wire3.classList.remove('wire-cut');
wire1.style.display = '';
wire2.style.display = '';
wire3.style.display = '';
// Reset effects
explosion.style.opacity = '0';
successEffect.style.opacity = '0';
// Start timer
clearInterval(timerInterval);
timerInterval = setInterval(updateTimer, 1000);
// Start screen shake
clearInterval(screenShakeInterval);
screenShakeInterval = setInterval(toggleShake, 100);
// Update display
timerDisplay.textContent = timeLeft;
timeBar.style.width = '100%';
}
function toggleShake() {
if (gameActive) {
gameContainer.classList.toggle('screen-shake');
}
}
function updateTimer() {
timeLeft--;
timerDisplay.textContent = timeLeft;
// Update timer bar
const percent = (timeLeft / 30) * 100;
timeBar.style.width = `${percent}%`;
// Play tick sound when time is running out
if (timeLeft <= 5 && timeLeft > 0) {
tickSound.currentTime = 0;
tickSound.play();
}
// Change color when time is critical
if (timeLeft <= 10) {
timeBar.classList.remove('bg-red-500');
timeBar.classList.add('bg-red-700');
}
if (timeLeft <= 0) {
gameOver();
}
}
// Wire click handlers
wire1.addEventListener('click', () => handleWireClick(1));
wire2.addEventListener('click', () => handleWireClick(2));
wire3.addEventListener('click', () => handleWireClick(3));
function handleWireClick(wireNumber) {
if (!gameActive) return;
// Play cut sound
cutSound.currentTime = 0;
cutSound.play();
// Animate wire cut
const wire = document.getElementById(`wire${wireNumber}`);
wire.classList.add('wire-cut');
// Check if correct wire
if (wireNumber === correctWire) {
defuseSuccess();
} else {
gameOver();
}
// Disable further clicks
gameActive = false;
clearInterval(timerInterval);
clearInterval(screenShakeInterval);
gameContainer.classList.remove('screen-shake');
}
function defuseSuccess() {
// Show success effect
successEffect.style.opacity = '1';
// Play success sound
successSound.currentTime = 0;
successSound.play();
// Show success screen after delay
setTimeout(() => {
gameScreen.classList.add('hidden');
successScreen.classList.remove('hidden');
}, 1500);
}
function gameOver() {
// Show explosion effect
explosion.style.opacity = '1';
// Play explosion sound
explosionSound.currentTime = 0;
explosionSound.play();
// Show game over screen after delay
setTimeout(() => {
gameScreen.classList.add('hidden');
gameOverScreen.classList.remove('hidden');
}, 1500);
}
</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=randt/bomb-defusal" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
</html>