anycoder-e3ffb972 / index.html
koston2025's picture
Upload folder using huggingface_hub
b799010 verified
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>НЕОНОВАЯ ВОЙНА: CYBER DEFENSE</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet">
<style>
:root {
--neon-blue: #00f3ff;
--neon-pink: #ff00ff;
--neon-green: #0aff00;
--neon-yellow: #ffea00;
--bg-color: #050505;
--glass-bg: rgba(255, 255, 255, 0.05);
--glass-border: rgba(255, 255, 255, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
background-color: var(--bg-color);
color: white;
font-family: 'Rajdhani', sans-serif;
overflow: hidden;
height: 100vh;
width: 100vw;
}
/* UI Overlay */
#ui-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none; /* Let clicks pass through to canvas */
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px;
z-index: 10;
}
/* HUD */
.hud-top {
display: flex;
justify-content: space-between;
align-items: center;
}
.score-box {
background: var(--glass-bg);
backdrop-filter: blur(10px);
border: 1px solid var(--glass-border);
padding: 10px 25px;
border-radius: 50px;
font-family: 'Orbitron', sans-serif;
font-size: 1.5rem;
text-shadow: 0 0 10px var(--neon-blue);
box-shadow: 0 0 20px rgba(0, 243, 255, 0.2);
transition: transform 0.1s;
}
.health-container {
width: 200px;
height: 10px;
background: rgba(255,255,255,0.1);
border-radius: 5px;
overflow: hidden;
position: relative;
}
.health-bar {
width: 100%;
height: 100%;
background: linear-gradient(90deg, var(--neon-green), var(--neon-blue));
box-shadow: 0 0 10px var(--neon-green);
transition: width 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/* Menus */
.menu-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(5px);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
pointer-events: auto;
z-index: 20;
transition: opacity 0.5s ease;
}
.hidden {
opacity: 0;
pointer-events: none;
}
h1 {
font-family: 'Orbitron', sans-serif;
font-size: 4rem;
text-transform: uppercase;
background: linear-gradient(to right, var(--neon-blue), var(--neon-pink));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 30px rgba(0, 243, 255, 0.5);
margin-bottom: 10px;
text-align: center;
letter-spacing: 5px;
}
p.subtitle {
font-size: 1.2rem;
color: #aaa;
margin-bottom: 40px;
letter-spacing: 2px;
}
.btn {
background: transparent;
color: var(--neon-blue);
font-family: 'Orbitron', sans-serif;
font-size: 1.5rem;
padding: 15px 50px;
border: 2px solid var(--neon-blue);
border-radius: 5px;
cursor: pointer;
text-transform: uppercase;
transition: all 0.3s ease;
box-shadow: 0 0 15px rgba(0, 243, 255, 0.2);
position: relative;
overflow: hidden;
}
.btn:hover {
background: var(--neon-blue);
color: black;
box-shadow: 0 0 40px rgba(0, 243, 255, 0.8);
transform: scale(1.05);
}
.btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
transition: 0.5s;
}
.btn:hover::before {
left: 100%;
}
/* Stats in Game Over */
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 30px;
text-align: center;
}
.stat-item h3 {
color: #888;
font-size: 0.9rem;
}
.stat-item span {
font-size: 2rem;
font-weight: bold;
color: white;
}
/* AnyCoder Link */
.anycoder-link {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 100;
font-family: 'Rajdhani', sans-serif;
font-weight: 700;
font-size: 0.9rem;
color: rgba(255,255,255,0.5);
text-decoration: none;
background: rgba(0,0,0,0.5);
padding: 5px 10px;
border-radius: 4px;
transition: color 0.3s;
}
.anycoder-link:hover {
color: var(--neon-pink);
}
/* Mobile Adjustments */
@media (max-width: 768px) {
h1 { font-size: 2.5rem; }
.hud-top { flex-direction: column; gap: 10px; }
.health-container { width: 150px; }
}
</style>
</head>
<body>
<!-- Canvas Game Layer -->
<canvas id="gameCanvas"></canvas>
<!-- UI Layer -->
<div id="ui-layer">
<div class="hud-top">
<div class="score-box">СЧЁТ: <span id="scoreEl">0</span></div>
<div class="health-container">
<div class="health-bar" id="healthEl"></div>
</div>
</div>
</div>
<!-- Start Screen -->
<div id="startScreen" class="menu-screen">
<h1>НЕОНОВАЯ<br>ВОЙНА</h1>
<p class="subtitle">ЗАЩИТИ ЯДРО ОТ ВИРУСОВ</p>
<button class="btn" id="startBtn">НАЧАТЬ МИССИЮ</button>
<div style="margin-top: 20px; font-size: 0.8rem; color: #666;">
Управление: Мышь/Тач для прицеливания<br>Клик для стрельбы
</div>
</div>
<!-- Game Over Screen -->
<div id="gameOverScreen" class="menu-screen hidden">
<h1 style="color: var(--neon-pink); -webkit-text-fill-color: var(--neon-pink);">МИССИЯ ПРОВАЛЕНА</h1>
<div class="stats-grid">
<div class="stat-item">
<h3>СЧЁТ</h3>
<span id="finalScore">0</span>
</div>
<div class="stat-item">
<h3>РЕКОРД</h3>
<span id="highScore">0</span>
</div>
</div>
<button class="btn" id="restartBtn">ПОВТОРИТЬ</button>
</div>
<!-- Footer Link -->
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
<script>
/**
* AUDIO SYSTEM (Synthesizer)
* No external files needed.
*/
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playSound(type) {
if (audioCtx.state === 'suspended') audioCtx.resume();
const osc = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
osc.connect(gainNode);
gainNode.connect(audioCtx.destination);
const now = audioCtx.currentTime;
if (type === 'shoot') {
osc.type = 'square';
osc.frequency.setValueAtTime(400, now);
osc.frequency.exponentialRampToValueAtTime(100, now + 0.1);
gainNode.gain.setValueAtTime(0.1, now);
gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.1);
osc.start(now);
osc.stop(now + 0.1);
} else if (type === 'hit') {
osc.type = 'triangle';
osc.frequency.setValueAtTime(100, now);
osc.frequency.linearRampToValueAtTime(50, now + 0.1);
gainNode.gain.setValueAtTime(0.2, now);
gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.2);
osc.start(now);
osc.stop(now + 0.2);
} else if (type === 'explosion') {
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(50, now);
osc.frequency.exponentialRampToValueAtTime(0.01, now + 0.3);
gainNode.gain.setValueAtTime(0.3, now);
gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.3);
osc.start(now);
osc.stop(now + 0.3);
}
}
/**
* GAME ENGINE
*/
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// UI Elements
const scoreEl = document.getElementById('scoreEl');
const healthEl = document.getElementById('healthEl');
const startScreen = document.getElementById('startScreen');
const gameOverScreen = document.getElementById('gameOverScreen');
const finalScoreEl = document.getElementById('finalScore');
const highScoreEl = document.getElementById('highScore');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
// Game State
let gameRunning = false;
let score = 0;
let health = 100;
let animationId;
let spawnInterval;
let difficultyMultiplier = 1;
// Resize Canvas
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Recenter player
player.x = canvas.width / 2;
player.y = canvas.height / 2;
});
// Classes
class Player {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.angle = 0;
}
draw() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
// Glow effect
ctx.shadowBlur = 20;
ctx.shadowColor = this.color;
// Main body
ctx.beginPath();
ctx.arc(0, 0, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
// Turret/Cannon
ctx.fillStyle = 'white';
ctx.fillRect(0, -5, this.radius + 10, 10);
ctx.restore();
}
update(mouse) {
// Calculate angle to mouse
const dx = mouse.x - this.x;
const dy = mouse.y - this.y;
this.angle = Math.atan2(dy, dx);
this.draw();
}
}
class Projectile {
constructor(x, y, radius, color, velocity) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = velocity;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.shadowBlur = 10;
ctx.shadowColor = this.color;
ctx.fill();
}
update() {
this.draw();
this.x = this.x + this.velocity.x;
this.y = this.y + this.velocity.y;
}
}
class Enemy {
constructor(x, y, radius, color, velocity) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = velocity;
this.type = Math.random() > 0.8 ? 'fast' : 'normal';
if (this.type === 'fast') {
this.radius = radius * 0.7;
this.color = '#ff00ff'; // Pink
this.velocity = {
x: velocity.x * 1.5,
y: velocity.y * 1.5
}
}
}
draw() {
ctx.beginPath();
if (this.type === 'fast') {
// Diamond shape for fast enemies
ctx.moveTo(this.x, this.y - this.radius);
ctx.lineTo(this.x + this.radius, this.y);
ctx.lineTo(this.x, this.y + this.radius);
ctx.lineTo(this.x - this.radius, this.y);
} else {
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
}
ctx.fillStyle = this.color;
ctx.shadowBlur = 15;
ctx.shadowColor = this.color;
ctx.fill();
}
update() {
this.draw();
// Move towards player
const angle = Math.atan2(player.y - this.y, player.x - this.x);
this.velocity = {
x: Math.cos(angle) * (1 * difficultyMultiplier),
y: Math.sin(angle) * (1 * difficultyMultiplier)
};
this.x = this.x + this.velocity.x;
this.y = this.y + this.velocity.y;
}
}
const friction = 0.98;
class Particle {
constructor(x, y, radius, color, velocity) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = velocity;
this.alpha = 1;
}
draw() {
ctx.save();
ctx.globalAlpha = this.alpha;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
}
update() {
this.draw();
this.velocity.x *= friction;
this.velocity.y *= friction;
this.x = this.x + this.velocity.x;
this.y = this.y + this.velocity.y;
this.alpha -= 0.01;
}
}
// Game Variables
const x = canvas.width / 2;
const y = canvas.height / 2;
let player = new Player(x, y, 15, '#00f3ff');
let projectiles = [];
let enemies = [];
let particles = [];
let mouse = { x: x, y: y };
// Input Handling
window.addEventListener('mousemove', (event) => {
mouse.x = event.clientX;
mouse.y = event.clientY;
});
window.addEventListener('touchmove', (event) => {
mouse.x = event.touches[0].clientX;
mouse.y = event.touches[0].clientY;
});
window.addEventListener('click', () => {
if (!gameRunning) return;
const angle = Math.atan2(mouse.y - player.y, mouse.x - player.x);
const velocity = {
x: Math.cos(angle) * 8,
y: Math.sin(angle) * 8
};
projectiles.push(new Projectile(player.x, player.y, 5, 'white', velocity));
playSound('shoot');
});
// Core Functions
function spawnEnemies() {
spawnInterval = setInterval(() => {
const radius = Math.random() * (30 - 10) + 10;
let x;
let y;
if (Math.random() < 0.5) {
x = Math.random() < 0.5 ? 0 - radius : canvas.width + radius;
y = Math.random() * canvas.height;
} else {
x = Math.random() * canvas.width;
y = Math.random() < 0.5 ? 0 - radius : canvas.height + radius;
}
const color = `hsl(${Math.random() * 60 + 180}, 100%, 50%)`; // Cyan/Green range
const angle = Math.atan2(canvas.height / 2 - y, canvas.width / 2 - x);
const velocity = {
x: Math.cos(angle),
y: Math.sin(angle)
};
enemies.push(new Enemy(x, y, radius, color, velocity));
}, 1000);
}
function initGame() {
player = new Player(canvas.width / 2, canvas.height / 2, 15, '#00f3ff');
projectiles = [];
enemies = [];
particles = [];
score = 0;
health = 100;
difficultyMultiplier = 1;
scoreEl.innerHTML = score;
healthEl.style.width = '100%';
gameRunning = true;
startScreen.classList.add('hidden');
gameOverScreen.classList.add('hidden');
spawnEnemies();
animate();
}
function endGame() {
gameRunning = false;
cancelAnimationFrame(animationId);
clearInterval(spawnInterval);
// Save High Score
const currentHigh = localStorage.getItem('neonWarHighScore') || 0;
if (score > currentHigh) {
localStorage.setItem('neonWarHighScore', score);
}
finalScoreEl.innerHTML = score;
highScoreEl.innerHTML = Math.max(score, currentHigh);
gameOverScreen.classList.remove('hidden');
}
function animate() {
if (!gameRunning) return;
animationId = requestAnimationFrame(animate);
// Trail effect (clearing with opacity)
ctx.fillStyle = 'rgba(5, 5, 5, 0.2)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
player.update(mouse);
// Particles Logic
particles.forEach((particle, index) => {
if (particle.alpha <= 0) {
particles.splice(index, 1);
} else {
particle.update();
}
});
// Projectiles Logic
projectiles.forEach((projectile, index) => {
projectile.update();
// Remove off-screen projectiles
if (projectile.x + projectile.radius < 0 ||
projectile.x - projectile.radius > canvas.width ||
projectile.y + projectile.radius < 0 ||
projectile.y - projectile.radius > canvas.height) {
setTimeout(() => {
projectiles.splice(index, 1);
}, 0);
}
});
// Enemies Logic
enemies.forEach((enemy, index) => {
enemy.update();
// Collision: Player vs Enemy
const dist = Math.hypot(player.x - enemy.x, player.y - enemy.y);
if (dist - enemy.radius - player.radius < 1) {
// Player Hit
enemies.splice(index, 1);
health -= 20;
healthEl.style.width = `${health}%`;
playSound('explosion');
// Screen Shake Effect
canvas.style.transform = `translate(${Math.random()*10 - 5}px, ${Math.random()*10 - 5}px)`;
setTimeout(() => canvas.style.transform = 'none', 100);
if (health <= 0) {
endGame();
}
}
// Collision: Projectile vs Enemy
projectiles.forEach((projectile, pIndex) => {
const dist = Math.hypot(projectile.x - enemy.x, projectile.y - enemy.y);
if (dist - enemy.radius - projectile.radius < 1) {
// Create Explosion Particles
for (let i = 0; i < enemy.radius * 2; i++) {
particles.push(new Particle(
projectile.x,
projectile.y,
Math.random() * 2,
enemy.color,
{
x: (Math.random() - 0.5) * (Math.random() * 6),
y: (Math.random() - 0.5) * (Math.random() * 6)
}
));
}
// Shrink enemy or destroy
if (enemy.radius - 10 > 10) {
score += 50;
scoreEl.innerHTML = score;
enemy.radius -= 10;
setTimeout(() => {
projectiles.splice(pIndex, 1);
}, 0);
playSound('hit');
} else {
score += 150;
scoreEl.innerHTML = score;
playSound('explosion');
setTimeout(() => {
enemies.splice(index, 1);
projectiles.splice(pIndex, 1);
}, 0);
}
// Increase difficulty slightly
difficultyMultiplier += 0.005;
}
});
});
}
// Event Listeners for Buttons
startBtn.addEventListener('click', () => {
// Initialize Audio Context on user interaction
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
initGame();
});
restartBtn.addEventListener('click', () => {
initGame();
});
</script>
</body>
</html>