Blog sayfan için harika bir oyun daha! Bu sefer, hem mobil cihazlarda hem de masaüstünde oynaması inanılmaz keyifli, bağımlılık yaratan modern bir retro klasiği hazırladım: Siber Yılan Oyunu (Cyber Snake).
Siber Yılan
Tasarımı yine blogunun hızını etkilemeyecek şekilde harici görsel veya kütüphane barındırmayan, koyu arka plan üzerinde neon yeşil ve mor detaylara sahip şık bir Glassmorphism arayüzüyle oluşturuldu. Dokunmatik ekranlar için altına entegre yön butonları ekledim, böylece mobilden giren ziyaretçilerin de rahatça oynayabilir.
Blogger'da yeni bir sayfada (HTML Görünümü modunda) veya bir HTML/JavaScript Gadget'ı içinde doğrudan kullanabilirsin:
<style>
/* Genel Konteyner ve Cam Efekti */
.snake-game-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #12121a 0%, #08080c 100%);
padding: 25px 15px;
border-radius: 16px;
max-width: 420px;
margin: 20px auto;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.05);
text-align: center;
color: #ffffff;
position: relative;
}
.game-title h2 {
margin: 0 0 15px 0;
font-size: 24px;
letter-spacing: 1.5px;
background: linear-gradient(45deg, #00f2fe, #4facfe);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Skor Tablosu */
.score-board {
display: flex;
justify-content: space-around;
background: rgba(255, 255, 255, 0.02);
padding: 10px;
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.05);
margin-bottom: 15px;
font-size: 16px;
font-weight: bold;
}
.score-board span {
color: #00f2fe;
}
/* Oyun Tuvali */
canvas {
background: #161623;
display: block;
margin: 0 auto;
border-radius: 8px;
border: 2px solid rgba(255, 255, 255, 0.1);
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.6);
max-width: 100%;
height: auto;
}
/* Mobil Kontrol Butonları */
.mobile-controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
max-width: 200px;
margin: 20px auto 0 auto;
}
.control-btn {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
color: white;
padding: 15px;
font-size: 18px;
border-radius: 8px;
cursor: pointer;
user-select: none;
transition: background 0.2s;
}
.control-btn:active {
background: #4facfe;
color: #000;
}
.btn-up { grid-column: 2; }
.btn-left { grid-column: 1; }
.btn-right { grid-column: 3; }
.btn-down { grid-column: 2; }
/* Başlangıç ve Reset Butonu */
.start-btn {
background: linear-gradient(45deg, #00f2fe, #4facfe);
border: none;
color: #050508;
padding: 10px 25px;
font-size: 15px;
font-weight: 700;
border-radius: 50px;
cursor: pointer;
margin-top: 15px;
box-shadow: 0 4px 15px rgba(0, 242, 254, 0.3);
transition: all 0.3s ease;
}
.start-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 242, 254, 0.5);
}
</style>
</head>
<body>
<div class="snake-game-container">
<div class="game-title">
<h2>Siber Yılan</h2>
</div>
<div class="score-board">
<div>Skor: <span id="current-score">0</span></div>
<div>En Yüksek: <span id="high-score">0</span></div>
</div>
<canvas id="snakeCanvas" width="300" height="300"></canvas>
<button class="start-btn" id="action-btn" onclick="toggleGame()">Oyunu Başlat</button>
<div class="mobile-controls">
<button class="control-btn btn-up" onclick="changeDirection('UP')">▲</button>
<button class="control-btn btn-left" onclick="changeDirection('LEFT')">◀</button>
<button class="control-btn btn-right" onclick="changeDirection('RIGHT')">▶</button>
<button class="control-btn btn-down" onclick="changeDirection('DOWN')">▼</button>
</div>
</div>
<script>
const canvas = document.getElementById("snakeCanvas");
const ctx = canvas.getContext("2d");
const scoreElement = document.getElementById("current-score");
const highScoreElement = document.getElementById("high-score");
const actionBtn = document.getElementById("action-btn");
const box = 15; // Izgara boyutu (300/15 = 20x20 kare)
let snake, direction, food, score, gameInterval;
let highScore = localStorage.getItem("snake_high_score") || 0;
let isRunning = false;
highScoreElement.textContent = highScore;
// Oyunu Başlatma / Resetleme Mekanizması
function toggleGame() {
if (isRunning) {
clearInterval(gameInterval);
isRunning = false;
actionBtn.textContent = "Oyunu Başlat";
} else {
initGame();
isRunning = true;
actionBtn.textContent = "Durdur";
}
}
// Oyun Alanını Kurma
function initGame() {
snake = [{ x: 10 * box, y: 10 * box }];
direction = "RIGHT";
score = 0;
scoreElement.textContent = score;
generateFood();
if (gameInterval) clearInterval(gameInterval);
gameInterval = setInterval(draw, 100); // Yılan hızı (100ms)
}
// Rastgele Yem Oluşturma
function generateFood() {
food = {
x: Math.floor(Math.random() * 20) * box,
y: Math.floor(Math.random() * 20) * box
};
// Yemin yılanın üstünde doğmamasını sağlama
for (let cell of snake) {
if (cell.x === food.x && cell.y === food.y) {
generateFood();
}
}
}
// Klavye Kontrolleri (Masaüstü için)
document.addEventListener("keydown", (e) => {
if (e.key === "ArrowUp" || e.key === "w" || e.key === "W") changeDirection("UP");
else if (e.key === "ArrowDown" || e.key === "s" || e.key === "S") changeDirection("DOWN");
else if (e.key === "ArrowLeft" || e.key === "a" || e.key === "A") changeDirection("LEFT");
else if (e.key === "ArrowRight" || e.key === "d" || e.key === "D") changeDirection("RIGHT");
// Ok tuşlarının tarayıcı sayfasını aşağı-yukarı kaydırmasını engelleme
if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.key) > -1) {
e.preventDefault();
}
});
// Yön Değiştirme Mantığı (Ters yöne ani dönüş engeliyle)
function changeDirection(newDir) {
if (!isRunning) return;
if (newDir === "LEFT" && direction !== "RIGHT") direction = "LEFT";
if (newDir === "UP" && direction !== "DOWN") direction = "UP";
if (newDir === "RIGHT" && direction !== "LEFT") direction = "RIGHT";
if (newDir === "DOWN" && direction !== "UP") direction = "DOWN";
}
// Çarpışma Kontrolü
function checkCollision(head, array) {
for (let i = 0; i < array.length; i++) {
if (head.x === array[i].x && head.y === array[i].y) return true;
}
return false;
}
// Ana Çizim ve Güncelleme Döngüsü
function draw() {
// Tuvali Temizle
ctx.fillStyle = "#161623";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Yılanı Çiz
for (let i = 0; i < snake.length; i++) {
// Baş kısmı neon mavi, gövde gradyan tonları
ctx.fillStyle = (i === 0) ? "#00f2fe" : "rgba(79, 172, 254, " + (1 - i/snake.length * 0.6) + ")";
ctx.fillRect(snake[i].x, snake[i].y, box - 1, box - 1);
ctx.borderRadius = "4px";
}
// Yemi Çiz (Neon Mor/Pembe)
ctx.fillStyle = "#ff007f";
ctx.shadowBlur = 10;
ctx.shadowColor = "#ff007f";
ctx.fillRect(food.x, food.y, box - 1, box - 1);
ctx.shadowBlur = 0; // Diğer çizimler için gölgeyi sıfırla
// Mevcut Baş Pozisyonu
let snakeX = snake[0].x;
let snakeY = snake[0].y;
// Yöne Göre Yeni Baş Konumu Hesapla
if (direction === "LEFT") snakeX -= box;
if (direction === "UP") snakeY -= box;
if (direction === "RIGHT") snakeX += box;
if (direction === "DOWN") snakeY += box;
// Yem Yeme Durumu
if (snakeX === food.x && snakeY === food.y) {
score++;
scoreElement.textContent = score;
if (score > highScore) {
highScore = score;
highScoreElement.textContent = highScore;
localStorage.setItem("snake_high_score", highScore);
}
generateFood();
} else {
// Yem yenmediyse kuyruğu sil (hareket hissi)
snake.pop();
}
// Yeni Baş Ekle
let newHead = { x: snakeX, y: snakeY };
// Duvarlara veya Kendine Çarpma Kontrolü (Game Over)
if (
snakeX < 0 || snakeX >= canvas.width ||
snakeY < 0 || snakeY >= canvas.height ||
checkCollision(newHead, snake)
) {
clearInterval(gameInterval);
isRunning = false;
actionBtn.textContent = "Yeniden Başlat";
alert(`Oyun Bitti! Skorunuz: ${score}`);
return;
}
snake.unshift(newHead);
}
// İlk açılışta boş ekran çiz
ctx.fillStyle = "#161623";
ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
Öne Çıkan Özellikleri:
Performans ve Hafiflik:
HTML5 Canvasmimarisiyle yazıldığı için DOM elementlerini yormaz, akıcı (lag olmadan) bir oyun deneyimi sunar.Mobil Entegrasyonu: Alt kısımdaki yön tuşları, dokunmatik ekranlarda sorunsuz çalışacak şekilde tasarlanmıştır.
Kalıcı Skor (Local Storage): Ziyaretçilerin yaptığı en yüksek skorları tarayıcı hafızasında saklar, böylece sayfayı tekrar ziyaret ettiklerinde kendi rekorlarını kırmaya çalışırlar. Bu da kullanıcı bağlılığını artırır.
Hiç yorum yok:
Yorum Gönder