x3v's picture
MAKE IT MORE MODERN TECH INSPIRED
e7097c7 verified
class SnakeGame extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.game-container {
width: 400px;
height: 400px;
margin: 0 auto;
background-color: rgba(15, 23, 42, 0.8);
border: 2px solid rgba(99, 102, 241, 0.5);
border-radius: 0.75rem;
box-shadow: 0 0 30px rgba(99, 102, 241, 0.3);
position: relative;
overflow: hidden;
}
.game-container::before {
content: "";
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(99, 102, 241, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(99, 102, 241, 0.1) 1px, transparent 1px);
background-size: 20px 20px;
}
position: relative;
overflow: hidden;
}
.snake-body {
position: absolute;
width: 20px;
height: 20px;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
border-radius: 4px;
box-shadow: 0 0 5px rgba(139, 92, 246, 0.7);
z-index: 2;
}
.food {
position: absolute;
width: 16px;
height: 16px;
background: linear-gradient(135deg, #f43f5e, #f97316);
border-radius: 50%;
box-shadow: 0 0 10px rgba(244, 63, 94, 0.7);
z-index: 2;
animation: pulse 1s infinite alternate;
}
@keyframes pulse {
from { transform: scale(1); }
to { transform: scale(1.2); }
}
.controls {
display: flex;
justify-content: center;
gap: 1rem;
margin-top: 1rem;
}
button {
padding: 0.5rem 1.5rem;
background: linear-gradient(90deg, #6366f1, #8b5cf6);
color: white;
border: none;
border-radius: 0.5rem;
cursor: pointer;
font-weight: 600;
transition: all 0.3s;
box-shadow: 0 4px 6px rgba(99, 102, 241, 0.2);
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(99, 102, 241, 0.3);
}
.score {
text-align: center;
margin-top: 1rem;
font-size: 1.2rem;
background: linear-gradient(90deg, #6366f1, #8b5cf6);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-weight: bold;
letter-spacing: 0.05em;
}
</style>
<div class="game-container" id="game-board"></div>
<div class="score">Score: <span id="score">0</span></div>
<div class="controls">
<button id="start-btn">Start Game</button>
<button id="reset-btn">Reset</button>
</div>
`;
this.initGame();
}
initGame() {
const shadow = this.shadowRoot;
const gameBoard = shadow.getElementById('game-board');
const scoreDisplay = shadow.getElementById('score');
const startBtn = shadow.getElementById('start-btn');
const resetBtn = shadow.getElementById('reset-btn');
// Game state
let snake = [{x: 200, y: 200}];
let food = this.generateFood();
let direction = 'right';
let gameInterval;
let score = 0;
let gameSpeed = 150;
let gameStarted = false;
// Draw initial state
this.drawGame();
// Event listeners
startBtn.addEventListener('click', startGame);
resetBtn.addEventListener('click', resetGame);
document.addEventListener('keydown', changeDirection);
function startGame() {
if (gameStarted) return;
gameStarted = true;
gameInterval = setInterval(moveSnake, gameSpeed);
}
function resetGame() {
clearInterval(gameInterval);
snake = [{x: 200, y: 200}];
direction = 'right';
score = 0;
scoreDisplay.textContent = '0';
gameStarted = false;
this.drawGame();
}
function changeDirection(e) {
if (!gameStarted) return;
const key = e.keyCode;
if (key === 37 && direction !== 'right') direction = 'left';
else if (key === 38 && direction !== 'down') direction = 'up';
else if (key === 39 && direction !== 'left') direction = 'right';
else if (key === 40 && direction !== 'up') direction = 'down';
}
function moveSnake() {
const head = {...snake[0]};
switch(direction) {
case 'up': head.y -= 20; break;
case 'down': head.y += 20; break;
case 'left': head.x -= 20; break;
case 'right': head.x += 20; break;
}
// Check for collision with walls or self
if (head.x < 0 || head.x >= 400 || head.y < 0 || head.y >= 400 ||
snake.some(segment => segment.x === head.x && segment.y === head.y)) {
clearInterval(gameInterval);
alert('Game Over! Your score: ' + score);
return;
}
snake.unshift(head);
// Check if snake ate food
if (head.x === food.x && head.y === food.y) {
score += 10;
scoreDisplay.textContent = score;
food = this.generateFood();
// Speed up game
if (score % 50 === 0 && gameSpeed > 50) {
gameSpeed -= 10;
clearInterval(gameInterval);
gameInterval = setInterval(moveSnake, gameSpeed);
}
} else {
snake.pop();
}
this.drawGame();
}
this.generateFood = function() {
const x = Math.floor(Math.random() * 20) * 20;
const y = Math.floor(Math.random() * 20) * 20;
// Make sure food doesn't spawn on snake
if (snake.some(segment => segment.x === x && segment.y === y)) {
return this.generateFood();
}
return {x, y};
}
this.drawGame = function() {
gameBoard.innerHTML = '';
// Draw snake
snake.forEach(segment => {
const snakeElement = document.createElement('div');
snakeElement.className = 'snake-body';
snakeElement.style.left = segment.x + 'px';
snakeElement.style.top = segment.y + 'px';
gameBoard.appendChild(snakeElement);
});
// Draw food
const foodElement = document.createElement('div');
foodElement.className = 'food';
foodElement.style.left = food.x + 'px';
foodElement.style.top = food.y + 'px';
gameBoard.appendChild(foodElement);
}
}
}
customElements.define('snake-game', SnakeGame);