test-sanke / index.html
hythyt's picture
Add 1 files
4110400 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neon Snake - Futuristic Snake Game</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>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
body {
font-family: 'Orbitron', sans-serif;
background-color: #0f0f1a;
overflow: hidden;
user-select: none;
}
.game-container {
position: relative;
box-shadow: 0 0 30px rgba(0, 255, 255, 0.3);
border: 2px solid rgba(0, 255, 255, 0.5);
}
.grid-cell {
border: 1px solid rgba(255, 255, 255, 0.05);
}
.snake-head {
background: linear-gradient(135deg, #00ffaa, #00aaff);
box-shadow: 0 0 15px rgba(0, 255, 255, 0.7);
}
.snake-body {
background: linear-gradient(135deg, #00aaff, #00ffaa);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}
.food {
background: linear-gradient(135deg, #ff00aa, #ff5500);
box-shadow: 0 0 20px rgba(255, 0, 170, 0.7);
animation: pulse 1.5s infinite alternate;
}
@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.2); }
}
.glow-text {
text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
}
.neon-btn {
transition: all 0.3s;
box-shadow: 0 0 15px rgba(0, 255, 255, 0.5);
}
.neon-btn:hover {
transform: translateY(-2px);
box-shadow: 0 0 25px rgba(0, 255, 255, 0.8);
}
.particle {
position: absolute;
background-color: rgba(0, 255, 255, 0.7);
border-radius: 50%;
pointer-events: none;
}
.game-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(15, 15, 26, 0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
}
</style>
</head>
<body class="min-h-screen flex flex-col items-center justify-center p-4">
<div class="text-center mb-6">
<h1 class="text-5xl font-bold text-cyan-400 glow-text mb-2">NEON SNAKE</h1>
<p class="text-purple-300 text-lg">A futuristic twist on the classic game</p>
</div>
<div class="relative">
<div id="game-board" class="game-container bg-gray-900 rounded-lg"></div>
<div id="game-overlay" class="game-overlay rounded-lg hidden">
<h2 class="text-4xl font-bold text-red-500 glow-text mb-4">GAME OVER</h2>
<p class="text-2xl text-cyan-300 mb-6">Score: <span id="final-score">0</span></p>
<button id="restart-btn" class="neon-btn bg-cyan-600 hover:bg-cyan-500 text-white font-bold py-3 px-6 rounded-full text-lg flex items-center">
<i class="fas fa-redo mr-2"></i> Play Again
</button>
</div>
</div>
<div class="mt-8 flex flex-col md:flex-row items-center justify-center gap-8">
<div class="bg-gray-800 bg-opacity-50 p-4 rounded-lg border border-cyan-500 border-opacity-30">
<h3 class="text-xl text-cyan-300 font-bold mb-2">Controls</h3>
<div class="grid grid-cols-3 gap-2 text-center">
<div></div>
<button class="control-btn bg-gray-700 hover:bg-gray-600 text-cyan-300 p-2 rounded">
<i class="fas fa-arrow-up"></i>
</button>
<div></div>
<button class="control-btn bg-gray-700 hover:bg-gray-600 text-cyan-300 p-2 rounded">
<i class="fas fa-arrow-left"></i>
</button>
<button class="control-btn bg-gray-700 hover:bg-gray-600 text-cyan-300 p-2 rounded">
<i class="fas fa-arrow-down"></i>
</button>
<button class="control-btn bg-gray-700 hover:bg-gray-600 text-cyan-300 p-2 rounded">
<i class="fas fa-arrow-right"></i>
</button>
</div>
</div>
<div class="bg-gray-800 bg-opacity-50 p-4 rounded-lg border border-cyan-500 border-opacity-30">
<h3 class="text-xl text-cyan-300 font-bold mb-2">Stats</h3>
<div class="flex items-center justify-between mb-2">
<span class="text-purple-300">Score:</span>
<span id="score" class="text-cyan-300 font-bold">0</span>
</div>
<div class="flex items-center justify-between mb-2">
<span class="text-purple-300">Speed:</span>
<span id="speed" class="text-cyan-300 font-bold">1x</span>
</div>
<div class="flex items-center justify-between">
<span class="text-purple-300">Length:</span>
<span id="length" class="text-cyan-300 font-bold">3</span>
</div>
</div>
<div class="flex flex-col gap-2">
<button id="pause-btn" class="neon-btn bg-purple-600 hover:bg-purple-500 text-white font-bold py-2 px-4 rounded-full flex items-center justify-center">
<i class="fas fa-pause mr-2"></i> Pause
</button>
<button id="sound-btn" class="neon-btn bg-blue-600 hover:bg-blue-500 text-white font-bold py-2 px-4 rounded-full flex items-center justify-center">
<i class="fas fa-volume-up mr-2"></i> Sound On
</button>
</div>
</div>
<div class="mt-8 text-gray-400 text-sm">
<p>Use arrow keys or on-screen controls to move the snake</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Game constants
const GRID_SIZE = 20;
const CELL_SIZE = 20;
const INITIAL_SPEED = 150;
const SPEED_INCREMENT = 5;
// Game variables
let snake = [{x: 10, y: 10}];
let food = generateFood();
let direction = 'right';
let nextDirection = 'right';
let gameInterval;
let score = 0;
let speed = INITIAL_SPEED;
let gameRunning = false;
let soundEnabled = true;
let gamePaused = false;
// DOM elements
const gameBoard = document.getElementById('game-board');
const scoreElement = document.getElementById('score');
const lengthElement = document.getElementById('length');
const speedElement = document.getElementById('speed');
const gameOverlay = document.getElementById('game-overlay');
const finalScoreElement = document.getElementById('final-score');
const restartBtn = document.getElementById('restart-btn');
const pauseBtn = document.getElementById('pause-btn');
const soundBtn = document.getElementById('sound-btn');
const controlBtns = document.querySelectorAll('.control-btn');
// Initialize game board
function initializeGameBoard() {
gameBoard.innerHTML = '';
gameBoard.style.width = `${GRID_SIZE * CELL_SIZE}px`;
gameBoard.style.height = `${GRID_SIZE * CELL_SIZE}px`;
// Create grid cells
for (let y = 0; y < GRID_SIZE; y++) {
for (let x = 0; x < GRID_SIZE; x++) {
const cell = document.createElement('div');
cell.className = 'grid-cell absolute';
cell.style.width = `${CELL_SIZE}px`;
cell.style.height = `${CELL_SIZE}px`;
cell.style.left = `${x * CELL_SIZE}px`;
cell.style.top = `${y * CELL_SIZE}px`;
cell.dataset.x = x;
cell.dataset.y = y;
gameBoard.appendChild(cell);
}
}
// Add grid pattern overlay
for (let i = 0; i < GRID_SIZE; i++) {
const lineH = document.createElement('div');
lineH.className = 'absolute bg-gray-800 opacity-10';
lineH.style.width = '100%';
lineH.style.height = '1px';
lineH.style.top = `${i * CELL_SIZE}px`;
lineH.style.left = '0';
const lineV = document.createElement('div');
lineV.className = 'absolute bg-gray-800 opacity-10';
lineV.style.width = '1px';
lineV.style.height = '100%';
lineV.style.left = `${i * CELL_SIZE}px`;
lineV.style.top = '0';
gameBoard.appendChild(lineH);
gameBoard.appendChild(lineV);
}
}
// Generate food at random position
function generateFood() {
let newFood;
do {
newFood = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
} while (snake.some(segment => segment.x === newFood.x && segment.y === newFood.y));
return newFood;
}
// Update game state
function updateGame() {
if (gamePaused) return;
// Update direction
direction = nextDirection;
// Move snake
const head = {...snake[0]};
switch (direction) {
case 'up':
head.y--;
break;
case 'down':
head.y++;
break;
case 'left':
head.x--;
break;
case 'right':
head.x++;
break;
}
// Check for collisions
if (
head.x < 0 || head.x >= GRID_SIZE ||
head.y < 0 || head.y >= GRID_SIZE ||
snake.some(segment => segment.x === head.x && segment.y === head.y)
) {
gameOver();
return;
}
// Add new head
snake.unshift(head);
// Check for food
if (head.x === food.x && head.y === food.y) {
// Increase score
score += 10;
scoreElement.textContent = score;
finalScoreElement.textContent = score;
// Update length
lengthElement.textContent = snake.length;
// Increase speed
speed = Math.max(50, speed - SPEED_INCREMENT);
clearInterval(gameInterval);
gameInterval = setInterval(updateGame, speed);
speedElement.textContent = (INITIAL_SPEED / speed).toFixed(1) + 'x';
// Generate new food
food = generateFood();
// Create particles
createParticles(head.x * CELL_SIZE + CELL_SIZE/2, head.y * CELL_SIZE + CELL_SIZE/2, 10);
// Play sound if enabled
if (soundEnabled) {
playEatSound();
}
} else {
// Remove tail if no food eaten
snake.pop();
}
// Render game
renderGame();
}
// Render game
function renderGame() {
// Clear all cells
document.querySelectorAll('.grid-cell').forEach(cell => {
cell.className = 'grid-cell absolute';
cell.style.width = `${CELL_SIZE}px`;
cell.style.height = `${CELL_SIZE}px`;
});
// Render snake
snake.forEach((segment, index) => {
const cell = document.querySelector(`.grid-cell[data-x="${segment.x}"][data-y="${segment.y}"]`);
if (cell) {
if (index === 0) {
cell.classList.add('snake-head');
} else {
cell.classList.add('snake-body');
}
}
});
// Render food
const foodCell = document.querySelector(`.grid-cell[data-x="${food.x}"][data-y="${food.y}"]`);
if (foodCell) {
foodCell.classList.add('food');
}
}
// Game over
function gameOver() {
clearInterval(gameInterval);
gameRunning = false;
gameOverlay.classList.remove('hidden');
// Play sound if enabled
if (soundEnabled) {
playGameOverSound();
}
}
// Start new game
function startGame() {
// Reset game state
snake = [{x: 10, y: 10}];
food = generateFood();
direction = 'right';
nextDirection = 'right';
score = 0;
speed = INITIAL_SPEED;
gameRunning = true;
gamePaused = false;
// Update UI
scoreElement.textContent = score;
lengthElement.textContent = snake.length;
speedElement.textContent = '1x';
gameOverlay.classList.add('hidden');
pauseBtn.innerHTML = '<i class="fas fa-pause mr-2"></i> Pause';
// Start game loop
clearInterval(gameInterval);
gameInterval = setInterval(updateGame, speed);
// Initial render
renderGame();
}
// Create particles effect
function createParticles(x, y, count) {
for (let i = 0; i < count; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
const size = Math.random() * 4 + 2;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.left = `${x}px`;
particle.style.top = `${y}px`;
const angle = Math.random() * Math.PI * 2;
const velocity = Math.random() * 3 + 2;
const vx = Math.cos(angle) * velocity;
const vy = Math.sin(angle) * velocity;
gameBoard.appendChild(particle);
let posX = x;
let posY = y;
let opacity = 1;
const animate = () => {
posX += vx;
posY += vy;
opacity -= 0.03;
particle.style.left = `${posX}px`;
particle.style.top = `${posY}px`;
particle.style.opacity = opacity;
if (opacity > 0) {
requestAnimationFrame(animate);
} else {
particle.remove();
}
};
requestAnimationFrame(animate);
}
}
// Sound effects
function playEatSound() {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.type = 'sine';
oscillator.frequency.value = 800;
gainNode.gain.value = 0.2;
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.start();
gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
oscillator.stop(audioContext.currentTime + 0.3);
}
function playGameOverSound() {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.type = 'sine';
oscillator.frequency.value = 300;
gainNode.gain.value = 0.3;
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.start();
oscillator.frequency.exponentialRampToValueAtTime(100, audioContext.currentTime + 0.5);
gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5);
oscillator.stop(audioContext.currentTime + 0.5);
}
// Event listeners
document.addEventListener('keydown', (e) => {
if (!gameRunning) return;
switch (e.key) {
case 'ArrowUp':
if (direction !== 'down') nextDirection = 'up';
break;
case 'ArrowDown':
if (direction !== 'up') nextDirection = 'down';
break;
case 'ArrowLeft':
if (direction !== 'right') nextDirection = 'left';
break;
case 'ArrowRight':
if (direction !== 'left') nextDirection = 'right';
break;
case ' ':
togglePause();
break;
}
});
controlBtns.forEach(btn => {
btn.addEventListener('click', () => {
if (!gameRunning) return;
const icon = btn.querySelector('i');
if (icon.classList.contains('fa-arrow-up') && direction !== 'down') {
nextDirection = 'up';
} else if (icon.classList.contains('fa-arrow-down') && direction !== 'up') {
nextDirection = 'down';
} else if (icon.classList.contains('fa-arrow-left') && direction !== 'right') {
nextDirection = 'left';
} else if (icon.classList.contains('fa-arrow-right') && direction !== 'left') {
nextDirection = 'right';
}
});
});
restartBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', togglePause);
function togglePause() {
if (!gameRunning) return;
gamePaused = !gamePaused;
if (gamePaused) {
pauseBtn.innerHTML = '<i class="fas fa-play mr-2"></i> Resume';
} else {
pauseBtn.innerHTML = '<i class="fas fa-pause mr-2"></i> Pause';
}
}
soundBtn.addEventListener('click', () => {
soundEnabled = !soundEnabled;
soundBtn.innerHTML = soundEnabled
? '<i class="fas fa-volume-up mr-2"></i> Sound On'
: '<i class="fas fa-volume-mute mr-2"></i> Sound Off';
});
// Initialize game
initializeGameBoard();
startGame();
});
</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=hythyt/test-sanke" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>