サイバーグリッドリンク:HTML5キャンバススネークゲームプロンプト
フリーのプロンプト百科事典 Wikiprompt より
サイバーグリッドリンク:HTML5キャンバススネークゲームプロンプト サイバーパンク風のスネークメカニクスを備えた完全な単一ファイルHTML5キャンバスゲームを生成するための詳細なプロンプト。レンダリング、コントロール、ビジュアルスタイルの仕様を含む。
プロンプト内容保存
🌐
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Cyber Grid Link</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0a12; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; font-family: 'Courier New', monospace; }
canvas { border: 2px solid #00ffcc; box-shadow: 0 0 30px #00ffcc33; }
#ui { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: #00ffcc; font-size: 20px; text-shadow: 0 0 10px #00ffcc; z-index: 10; }
#gameOver { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #ff0044; font-size: 40px; text-shadow: 0 0 20px #ff0044; display: none; z-index: 20; background: #0a0a12cc; padding: 20px; border: 2px solid #ff0044; }
</style>
</head>
<body>
<div id="ui">SCORE: 0</div>
<div id="gameOver">GAME OVER<br><span style="font-size:20px">PRESS SPACE TO RESTART</span></div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const ui = document.getElementById('ui');
const gameOverDiv = document.getElementById('gameOver');
canvas.width = 800;
canvas.height = 600;
const GRID_SIZE = 40;
const COLS = canvas.width / GRID_SIZE;
const ROWS = canvas.height / GRID_SIZE;
// Snake state
let snake = [];
let snakeLength = 5;
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let speed = 0.15; // interpolation speed
let score = 0;
let gameRunning = true;
// Crystals
let crystals = [];
const CRYSTAL_COUNT = 5;
// Firewalls
let firewalls = [];
const FIREWALL_COUNT = 3;
// Grid warp
const warpRadius = 150;
const warpStrength = 15;
// Initialize snake
function initSnake() {
snake = [];
const startX = Math.floor(COLS / 2) * GRID_SIZE;
const startY = Math.floor(ROWS / 2) * GRID_SIZE;
for (let i = 0; i < snakeLength; i++) {
snake.push({ x: startX - i * GRID_SIZE, y: startY, targetX: startX - i * GRID_SIZE, targetY: startY });
}
}
// Spawn crystals
function spawnCrystals() {
crystals = [];
for (let i = 0; i < CRYSTAL_COUNT; i++) {
let pos = getRandomFreeCell();
crystals.push({ x: pos.x * GRID_SIZE + GRID_SIZE/2, y: pos.y * GRID_SIZE + GRID_SIZE/2, pulse: Math.random() * Math.PI * 2 });
}
}
// Spawn firewalls
function spawnFirewalls() {
firewalls = [];
for (let i = 0; i < FIREWALL_COUNT; i++) {
let dir = Math.random() < 0.5 ? 'vertical' : 'horizontal';
let pos = Math.floor(Math.random() * (dir === 'vertical' ? COLS : ROWS));
let speed = 0.5 + Math.random() * 1.5;
firewalls.push({ dir, pos, speed, offset: Math.random() * 100 });
}
}
// Get random free cell (not on snake)
function getRandomFreeCell() {
let x, y;
do {
x = Math.floor(Math.random() * COLS);
y = Math.floor(Math.random() * ROWS);
} while (snake.some(s => Math.floor(s.targetX / GRID_SIZE) === x && Math.floor(s.targetY / GRID_SIZE) === y));
return { x, y };
}
// Input handling
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') {
if (direction.y !== 1) nextDirection = { x: 0, y: -1 };
} else if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') {
if (direction.y !== -1) nextDirection = { x: 0, y: 1 };
} else if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') {
if (direction.x !== 1) nextDirection = { x: -1, y: 0 };
} else if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') {
if (direction.x !== -1) nextDirection = { x: 1, y: 0 };
} else if (e.key === ' ' && !gameRunning) {
restartGame();
}
});
// Update snake movement
function updateSnake() {
// Apply direction change
direction = { ...nextDirection };
// Move head target
let head = snake[0];
let newTargetX = head.targetX + direction.x * GRID_SIZE;
let newTargetY = head.targetY + direction.y * GRID_SIZE;
// Wrap around edges
if (newTargetX >= canvas.width) newTargetX = 0;
if (newTargetX < 0) newTargetX = canvas.width - GRID_SIZE;
if (newTargetY >= canvas.height) newTargetY = 0;
if (newTargetY < 0) newTargetY = canvas.height - GRID_SIZE;
// Check self collision
for (let i = 1; i < snake.length; i++) {
if (Math.abs(snake[i].targetX - newTargetX) < GRID_SIZE/2 && Math.abs(snake[i].targetY - newTargetY) < GRID_SIZE/2) {
gameOver();
return;
}
}
// Move body (each segment follows the one before)
for (let i = snake.length - 1; i > 0; i--) {
snake[i].targetX = snake[i-1].targetX;
snake[i].targetY = snake[i-1].targetY;
}
// Move head
snake[0].targetX = newTargetX;
snake[0].targetY = newTargetY;
// Check crystal collection
for (let i = crystals.length - 1; i >= 0; i--) {
let c = crystals[i];
if (Math.abs(snake[0].targetX + GRID_SIZE/2 - c.x) < GRID_SIZE && Math.abs(snake[0].targetY + GRID_SIZE/2 - c.y) < GRID_SIZE) {
// Grow snake
let tail = snake[snake.length - 1];
snake.push({ x: tail.x, y: tail.y, targetX: tail.targetX, targetY: tail.targetY });
crystals.splice(i, 1);
score += 10;
ui.textContent = 'SCORE: ' + score;
// Spawn new crystal
let pos = getRandomFreeCell();
crystals.push({ x: pos.x * GRID_SIZE + GRID_SIZE/2, y: pos.y * GRID_SIZE + GRID_SIZE/2, pulse: 0 });
}
}
// Check firewall collision
for (let fw of firewalls) {
let fwX, fwY, fwW, fwH;
if (fw.dir === 'vertical') {
fwX = fw.pos * GRID_SIZE;
fwY = (Math.sin(Date.now() * 0.001 * fw.speed + fw.offset) * 0.5 + 0.5) * (canvas.height - GRID_SIZE);
fwW = GRID_SIZE;
fwH = GRID_SIZE * 2;
} else {
fwX = (Math.sin(Date.now() * 0.001 * fw.speed + fw.offset) * 0.5 + 0.5) * (canvas.width - GRID_SIZE);
fwY = fw.pos * GRID_SIZE;
fwW = GRID_SIZE * 2;
fwH = GRID_SIZE;
}
// Check head collision
let headX = snake[0].targetX + GRID_SIZE/2;
let headY = snake[0].targetY + GRID_SIZE/2;
if (headX > fwX && headX < fwX + fwW && headY > fwY && headY < fwY + fwH) {
gameOver();
return;
}
}
}
// Interpolate snake positions for smooth movement
function interpolateSnake() {
for (let seg of snake) {
seg.x += (seg.targetX - seg.x) * speed;
seg.y += (seg.targetY - seg.y) * speed;
}
}
// Grid warp function
function warpGrid(x, y) {
let head = snake[0];
let dx = x - (head.x + GRID_SIZE/2);
let dy = y - (head.y + GRID_SIZE/2);
let dist = Math.sqrt(dx*dx + dy*dy);
if (dist < warpRadius) {
let factor = (1 - dist / warpRadius) * warpStrength;
return { x: x + dx * factor, y: y + dy * factor };
}
return { x, y };
}
// Draw grid with warp
function drawGrid() {
ctx.strokeStyle = '#1a1a3a';
ctx.lineWidth = 1;
for (let i = 0; i <= COLS; i++) {
let x = i * GRID_SIZE;
ctx.beginPath();
for (let j = 0; j <= ROWS; j++) {
let y = j * GRID_SIZE;
let p = warpGrid(x, y);
if (j === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
}
ctx.stroke();
}
for (let j = 0; j <= ROWS; j++) {
let y = j * GRID_SIZE;
ctx.beginPath();
for (let i = 0; i <= COLS; i++) {
let x = i * GRID_SIZE;
let p = warpGrid(x, y);
if (i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
}
ctx.stroke();
}
}
// Draw snake with pulsing gradient
function drawSnake() {
for (let i = snake.length - 1; i >= 0; i--) {
let seg = snake[i];
let pulse = Math.sin(Date.now() * 0.01 + i * 0.5) * 0.5 + 0.5;
let size = GRID_SIZE * 0.7 * (1 - i * 0.01);
let hue = 180 + i * 2;
let lightness = 50 + pulse * 20;
ctx.fillStyle = `hsl(${hue}, 100%, ${lightness}%)`;
ctx.shadowColor = `hsl(${hue}, 100%, 70%)`;
ctx.shadowBlur = 20;
ctx.beginPath();
ctx.arc(seg.x + GRID_SIZE/2, seg.y + GRID_SIZE/2, size/2, 0, Math.PI * 2);
ctx.fill();
}
ctx.shadowBlur = 0;
}
// Draw crystals
function drawCrystals() {
for (let c of crystals) {
c.pulse += 0.05;
let size = GRID_SIZE * 0.5 + Math.sin(c.pulse) * 5;
ctx.fillStyle = '#00ff88';
ctx.shadowColor = '#00ff88';
ctx.shadowBlur = 30;
ctx.beginPath();
ctx.moveTo(c.x, c.y - size);
ctx.lineTo(c.x + size * 0.7, c.y);
ctx.lineTo(c.x, c.y + size);
ctx.lineTo(c.x - size * 0.7, c.y);
ctx.closePath();
ctx.fill();
}
ctx.shadowBlur = 0;
}
// Draw firewalls
function drawFirewalls() {
ctx.fillStyle = '#ff0044';
ctx.shadowColor = '#ff0044';
ctx.shadowBlur = 20;
for (let fw of firewalls) {
let fwX, fwY, fwW, fwH;
if (fw.dir === 'vertical') {
fwX = fw.pos * GRID_SIZE;
fwY = (Math.sin(Date.now() * 0.001 * fw.speed + fw.offset) * 0.5 + 0.5) * (canvas.height - GRID_SIZE);
fwW = GRID_SIZE;
fwH = GRID_SIZE * 2;
} else {
fwX = (Math.sin(Date.now() * 0.001 * fw.speed + fw.offset) * 0.5 + 0.5) * (canvas.width - GRID_SIZE);
fwY = fw.pos * GRID_SIZE;
fwW = GRID_SIZE * 2;
fwH = GRID_SIZE;
}
ctx.fillRect(fwX, fwY, fwW, fwH);
}
ctx.shadowBlur = 0;
}
// Game over
function gameOver() {
gameRunning = false;
gameOverDiv.style.display = 'block';
}
// Restart
function restartGame() {
gameRunning = true;
gameOverDiv.style.display = 'none';
score = 0;
ui.textContent = 'SCORE: 0';
snakeLength = 5;
direction = { x: 1, y: 0 };
nextDirection = { x: 1, y: 0 };
initSnake();
spawnCrystals();
spawnFirewalls();
}
// Main game loop
let lastTime = 0;
function gameLoop(timestamp) {
let deltaTime = timestamp - lastTime;
lastTime = timestamp;
if (gameRunning) {
updateSnake();
interpolateSnake();
}
// Clear canvas
ctx.fillStyle = '#0a0a12';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw everything
drawGrid();
drawCrystals();
drawFirewalls();
drawSnake();
requestAnimationFrame(gameLoop);
}
// Initialize
initSnake();
spawnCrystals();
spawnFirewalls();
requestAnimationFrame(gameLoop);
</script>
</body>
</html>
ログインして完全なプロンプトを表示
次で続行:
ログインすると、次に同意したことになります: 利用規約 と プライバシーポリシー
使い方
このプロンプトは coding 向けに設計されています。上の内容をコピーして、お好みの AI ツールに貼り付けてください。
最良の結果を得るには、プレースホルダー(角括弧や大文字で示された部分)を具体的な要件に置き換えてください。
ノート
0 件のコメント