Cyber Grid Link: HTML5-Canvas-Snake-Spiel Prompt
Von Wikiprompt, der freien Prompt-Enzyklopädie
Cyber Grid Link: HTML5-Canvas-Snake-Spiel Prompt Ein detaillierter Prompt zur Generierung eines vollständigen, einteiligen HTML5-Canvas-Spiels mit einer Cyberpunk-Schlangenmechanik, einschließlich Rendering, Steuerung und Spezifikationen des visuellen Stils.
Prompt-InhaltSpeichern
🌐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cyber Grid Link</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0a1a; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; font-family: 'Courier New', monospace; }
canvas { display: block; border: 2px solid #00f7ff; box-shadow: 0 0 30px rgba(0, 247, 255, 0.3); }
#ui { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: #00f7ff; font-size: 18px; text-shadow: 0 0 10px #00f7ff; }
#score { margin-right: 30px; }
#gameover { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #ff0040; font-size: 36px; text-shadow: 0 0 20px #ff0040; display: none; }
#restart { position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%); color: #00f7ff; font-size: 16px; cursor: pointer; text-shadow: 0 0 10px #00f7ff; display: none; }
#restart:hover { color: #ff00ff; }
</style>
</head>
<body>
<div id="ui">
<span id="score">Score: 0</span>
<span id="length">Length: 3</span>
</div>
<div id="gameover">GAME OVER</div>
<div id="restart">[ PRESS SPACE TO RESTART ]</div>
<canvas id="gameCanvas"></canvas>
<script>
(function() {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const lengthDisplay = document.getElementById('length');
const gameoverDiv = document.getElementById('gameover');
const restartDiv = document.getElementById('restart');
// Grid and game settings
const GRID_SIZE = 20;
const CELL_SIZE = 30;
const COLS = Math.floor(window.innerWidth / CELL_SIZE) - 2;
const ROWS = Math.floor(window.innerHeight / CELL_SIZE) - 2;
canvas.width = COLS * CELL_SIZE;
canvas.height = ROWS * CELL_SIZE;
// Snake state
let snake = [];
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let food = { x: 5, y: 5 };
let score = 0;
let gameOver = false;
let gameLoopId = null;
// Firewall barriers
let barriers = [];
const BARRIER_SPEED = 0.5;
const BARRIER_COUNT = 3;
// LERP interpolation
const LERP_FACTOR = 0.15;
// Initialize game
function init() {
snake = [
{ x: 3, y: 3, px: 3, py: 3 },
{ x: 2, y: 3, px: 2, py: 3 },
{ x: 1, y: 3, px: 1, py: 3 }
];
direction = { x: 1, y: 0 };
nextDirection = { x: 1, y: 0 };
score = 0;
gameOver = false;
gameoverDiv.style.display = 'none';
restartDiv.style.display = 'none';
spawnFood();
spawnBarriers();
updateUI();
if (gameLoopId) cancelAnimationFrame(gameLoopId);
gameLoopId = requestAnimationFrame(gameLoop);
}
// Spawn food at random position not on snake
function spawnFood() {
let pos;
do {
pos = { x: Math.floor(Math.random() * COLS), y: Math.floor(Math.random() * ROWS) };
} while (snake.some(seg => seg.x === pos.x && seg.y === pos.y));
food = pos;
}
// Spawn firewall barriers
function spawnBarriers() {
barriers = [];
for (let i = 0; i < BARRIER_COUNT; i++) {
let x, y;
do {
x = Math.floor(Math.random() * COLS);
y = Math.floor(Math.random() * ROWS);
} while (snake.some(seg => seg.x === x && seg.y === y) || (x === food.x && y === food.y));
barriers.push({
x: x,
y: y,
dx: Math.random() > 0.5 ? 1 : -1,
dy: Math.random() > 0.5 ? 1 : -1
});
}
}
// Update UI
function updateUI() {
scoreDisplay.textContent = `Score: ${score}`;
lengthDisplay.textContent = `Length: ${snake.length}`;
}
// Game loop
function gameLoop(timestamp) {
if (gameOver) {
gameoverDiv.style.display = 'block';
restartDiv.style.display = 'block';
return;
}
// Update direction
direction = { ...nextDirection };
// Move snake head
const head = snake[0];
const newHead = {
x: head.x + direction.x,
y: head.y + direction.y,
px: head.x,
py: head.y
};
// Check wall collision
if (newHead.x < 0 || newHead.x >= COLS || newHead.y < 0 || newHead.y >= ROWS) {
gameOver = true;
return;
}
// Check self collision
if (snake.some(seg => seg.x === newHead.x && seg.y === newHead.y)) {
gameOver = true;
return;
}
// Check barrier collision
if (barriers.some(b => b.x === newHead.x && b.y === newHead.y)) {
gameOver = true;
return;
}
// Add new head
snake.unshift(newHead);
// Check food
if (newHead.x === food.x && newHead.y === food.y) {
score += 10;
spawnFood();
updateUI();
} else {
snake.pop();
}
// Move barriers
barriers.forEach(barrier => {
let newX = barrier.x + barrier.dx * BARRIER_SPEED;
let newY = barrier.y + barrier.dy * BARRIER_SPEED;
if (newX < 0 || newX >= COLS) barrier.dx *= -1;
if (newY < 0 || newY >= ROWS) barrier.dy *= -1;
barrier.x = Math.max(0, Math.min(COLS - 1, newX));
barrier.y = Math.max(0, Math.min(ROWS - 1, newY));
});
// Update previous positions for LERP
snake.forEach(seg => {
seg.px = seg.x;
seg.py = seg.y;
});
// Render
render();
updateUI();
gameLoopId = requestAnimationFrame(gameLoop);
}
// Render everything
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw grid with warp near head
const head = snake[0];
for (let i = 0; i < COLS; i++) {
for (let j = 0; j < ROWS; j++) {
let x = i * CELL_SIZE;
let y = j * CELL_SIZE;
// Localized displacement near head
const dx = i - head.x;
const dy = j - head.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 3) {
const warp = (3 - dist) / 3 * 5;
x += dx * warp;
y += dy * warp;
}
ctx.strokeStyle = `rgba(0, 247, 255, ${0.1 + 0.05 * Math.sin(i + j)})`;
ctx.strokeRect(x, y, CELL_SIZE, CELL_SIZE);
}
}
// Draw snake with pulsing gradient
snake.forEach((seg, index) => {
const lerpX = seg.px + (seg.x - seg.px) * LERP_FACTOR;
const lerpY = seg.py + (seg.y - seg.py) * LERP_FACTOR;
const x = lerpX * CELL_SIZE + CELL_SIZE / 2;
const y = lerpY * CELL_SIZE + CELL_SIZE / 2;
const radius = CELL_SIZE / 2 - 2;
const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
const hue = (index * 15 + Date.now() * 0.01) % 360;
gradient.addColorStop(0, `hsl(${hue}, 100%, 70%)`);
gradient.addColorStop(1, `hsl(${hue}, 100%, 30%)`);
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = gradient;
ctx.fill();
ctx.shadowBlur = 15;
ctx.shadowColor = `hsl(${hue}, 100%, 50%)`;
});
ctx.shadowBlur = 0;
// Draw food (energy crystal)
const fx = food.x * CELL_SIZE + CELL_SIZE / 2;
const fy = food.y * CELL_SIZE + CELL_SIZE / 2;
ctx.shadowBlur = 20;
ctx.shadowColor = '#00ff88';
ctx.fillStyle = '#00ff88';
ctx.beginPath();
ctx.arc(fx, fy, 8, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// Draw barriers (firewall)
barriers.forEach(barrier => {
const bx = barrier.x * CELL_SIZE + CELL_SIZE / 2;
const by = barrier.y * CELL_SIZE + CELL_SIZE / 2;
ctx.shadowBlur = 15;
ctx.shadowColor = '#ff0040';
ctx.fillStyle = '#ff0040';
ctx.beginPath();
ctx.arc(bx, by, 10, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
});
}
// Keyboard controls
document.addEventListener('keydown', (e) => {
if (gameOver && e.key === ' ') {
init();
return;
}
if (gameOver) return;
switch(e.key) {
case 'ArrowUp':
case 'w':
case 'W':
if (direction.y !== 1) nextDirection = { x: 0, y: -1 };
break;
case 'ArrowDown':
case 's':
case 'S':
if (direction.y !== -1) nextDirection = { x: 0, y: 1 };
break;
case 'ArrowLeft':
case 'a':
case 'A':
if (direction.x !== 1) nextDirection = { x: -1, y: 0 };
break;
case 'ArrowRight':
case 'd':
case 'D':
if (direction.x !== -1) nextDirection = { x: 1, y: 0 };
break;
}
});
// Start game
init();
})();
</script>
</body>
</html>
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Diskussion
0 Kommentare