Özellikler:
- Dark Mod ve Gelişmiş Grafikler: Yılan, beyaz renkte ve yem yeşil renkte. Gelişmiş gölge efektleri ve yumuşak kenarlar, oyunun daha gerçekçi ve hoş görünmesini sağlıyor.
- Zorluk Seçenekleri: Kolay, orta ve zor zorluk seviyeleri ile oyun deneyimini özelleştirebilirsiniz.
- Skor Tablosu: Kolayca skorunuzu takip edebileceğiniz bir skor tablosu mevcut.
- Duvarlar ve Engeller: Yılan alanı genişletildi ve duvarlarla zorluk eklenerek oyun deneyimi daha da geliştirildi.

Kod:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Yılan Oyunu</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
background-color: #1a202c;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
canvas {
border: 4px solid #2d3748;
margin: auto;
display: block;
background-color: #1a202c;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.7);
}
.game-over {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
padding: 20px;
background-color: rgba(0, 0, 0, 0.8);
border-radius: 10px;
text-align: center;
color: white;
animation: fadeIn 0.5s ease-out;
}
.game-over.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.snake-body {
fill: #FFFFFF;
border-radius: 5px; /* Yumuşak kenarlar */
}
.food {
fill: #48BB78;
border-radius: 5px; /* Yumuşak kenarlar */
}
.walls {
fill: #2d3748;
}
.score-board {
position: absolute;
top: 10px;
left: 10px;
padding: 10px;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 5px;
color: white;
font-size: 18px;
}
</style>
</head>
<body>
<div class="game-over" id="gameOver">
<h2 class="text-3xl font-bold">Oyun Bitti!</h2>
<p class="mt-4">Skorunuz: <span id="finalScore">0</span></p>
<button class="mt-6 p-2 bg-red-500 rounded text-white" onclick="restartGame()">Yeniden Başla</button>
</div>
<h1 class="text-4xl font-bold text-white mb-8">Yılan Oyunu</h1>
<div class="mb-4">
<label for="difficulty" class="text-white text-lg">Zorluk Seçin:</label>
<select id="difficulty" class="ml-2 p-2 rounded bg-gray-700 text-white">
<option value="easy">Kolay</option>
<option value="medium">Orta</option>
<option value="hard">Zor</option>
</select>
</div>
<div class="score-board">
<p>Skor: <span id="score">0</span></p>
</div>
<canvas id="gameCanvas" width="600" height="600"></canvas>
<p class="text-white text-xl mt-4">Skor: <span id="score">0</span></p>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const finalScore = document.getElementById('finalScore');
const gameOver = document.getElementById('gameOver');
const difficultySelect = document.getElementById('difficulty');
let tileSize = 20;
let snake = [{ x: 300, y: 300 }];
let direction = { x: 0, y: 0 };
let food = generateFood();
let score = 0;
let gameSpeed = 200;
function generateFood() {
let x, y;
do {
x = Math.floor(Math.random() * (canvas.width / tileSize)) * tileSize;
y = Math.floor(Math.random() * (canvas.height / tileSize)) * tileSize;
} while (isCollisionWithWalls(x, y) || isCollisionWithSnake(x, y));
return { x, y };
}
function isCollisionWithWalls(x, y) {
return x < tileSize || x >= canvas.width - tileSize || y < tileSize || y >= canvas.height - tileSize;
}
function isCollisionWithSnake(x, y) {
return snake.some(segment => segment.x === x && segment.y === y);
}
const setSpeed = (difficulty) => {
if (difficulty === 'easy') gameSpeed = 200;
else if (difficulty === 'medium') gameSpeed = 150;
else if (difficulty === 'hard') gameSpeed = 100;
};
difficultySelect.addEventListener('change', (e) => {
setSpeed(e.target.value);
});
const drawSnake = () => {
ctx.fillStyle = '#FFFFFF';
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
snake.forEach(segment => {
ctx.fillRect(segment.x, segment.y, tileSize, tileSize);
});
};
const drawFood = () => {
ctx.fillStyle = '#48BB78';
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
ctx.fillRect(food.x, food.y, tileSize, tileSize);
};
const drawWalls = () => {
ctx.fillStyle = '#2d3748';
ctx.fillRect(0, 0, canvas.width, tileSize); // üst duvar
ctx.fillRect(0, canvas.height - tileSize, canvas.width, tileSize); // alt duvar
ctx.fillRect(0, 0, tileSize, canvas.height); // sol duvar
ctx.fillRect(canvas.width - tileSize, 0, tileSize, canvas.height); // sağ duvar
};
const moveSnake = () => {
const head = { x: snake[0].x + direction.x * tileSize, y: snake[0].y + direction.y * tileSize };
snake.unshift(head);
if (head.x === food.x && head.y === food.y) {
score += 10;
scoreDisplay.textContent = score;
food = generateFood();
animateFoodEaten();
} else {
snake.pop();
}
};
const checkCollision = () => {
const head = snake[0];
if (head.x < tileSize || head.x >= canvas.width - tileSize ||
head.y < tileSize || head.y >= canvas.height - tileSize) {
return true;
}
for (let i = 1; i < snake.length; i++) {
if (snake[i].x === head.x && snake[i].y === head.y) {
return true;
}
}
return false;
};
const gameLoop = () => {
if (checkCollision()) {
gameOver.classList.add('active');
finalScore.textContent = score;
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawWalls();
drawFood();
moveSnake();
drawSnake();
setTimeout(gameLoop, gameSpeed);
};
window.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp':
if (direction.y === 0) direction = { x: 0, y: -1 };
break;
case 'ArrowDown':
if (direction.y === 0) direction = { x: 0, y: 1 };
break;
case 'ArrowLeft':
if (direction.x === 0) direction = { x: -1, y: 0 };
break;
case 'ArrowRight':
if (direction.x === 0) direction = { x: 1, y: 0 };
break;
}
});
setSpeed(difficultySelect.value);
gameLoop();
const restartGame = () => {
snake = [{ x: 300, y: 300 }];
direction = { x: 0, y: 0 };
score = 0;
scoreDisplay.textContent = score;
gameOver.classList.remove('active');
gameLoop();
};
const animateFoodEaten = () => {
const foodX = food.x;
const foodY = food.y;
ctx.fillStyle = '#48BB78';
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
ctx.fillRect(food.x, food.y, tileSize, tileSize);
ctx.clearRect(foodX, foodY, tileSize, tileSize);
};
</script>
</body>
</html>

