用Trae自动生成的网页游戏(贪吃蛇)AI自动生成的代码
·
文件名:game3.html
贪吃蛇网页游戏,运行的效果还不错,直接po图和代码。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0f0f1e;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: "Microsoft YaHei", sans-serif;
color: #fff;
}
h1 {
font-size: 36px;
color: #4caf50;
margin-bottom: 6px;
text-shadow: 0 0 20px rgba(76,175,80,0.4);
}
#info {
display: flex;
gap: 40px;
margin-bottom: 12px;
font-size: 20px;
}
#info span { color: #4caf50; font-weight: bold; }
#game-container {
position: relative;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 0 40px rgba(76,175,80,0.15), 0 20px 60px rgba(0,0,0,0.5);
}
canvas { display: block; background: #1a1a2e; }
#controls {
margin-top: 15px;
display: flex;
gap: 12px;
}
.btn {
padding: 10px 28px;
font-size: 16px;
font-weight: bold;
color: #fff;
background: linear-gradient(135deg, #667eea, #764ba2);
border: none;
border-radius: 8px;
cursor: pointer;
transition: transform 0.15s;
}
.btn:hover { transform: scale(1.06); }
.btn.green { background: linear-gradient(135deg, #4caf50, #2e7d32); }
#speed-select {
padding: 10px 18px;
font-size: 16px;
border-radius: 8px;
border: 1px solid #4caf50;
background: #1a1a2e;
color: #fff;
cursor: pointer;
}
#overlay {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.75);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
}
#overlay h2 { font-size: 42px; color: #4caf50; margin-bottom: 12px; }
#overlay p { font-size: 22px; margin-bottom: 8px; color: #ccc; }
#overlay .score { color: #ffd700; font-size: 26px; margin-bottom: 25px; }
#overlay button {
padding: 12px 40px;
font-size: 20px;
font-weight: bold;
color: #fff;
background: linear-gradient(135deg, #4caf50, #2e7d32);
border: none;
border-radius: 30px;
cursor: pointer;
box-shadow: 0 4px 15px rgba(76,175,80,0.4);
transition: transform 0.2s;
}
#overlay button:hover { transform: scale(1.08); }
#hint {
margin-top: 10px;
font-size: 14px;
color: rgba(255,255,255,0.4);
}
/* 移动端方向键 */
#mobile-controls {
display: none;
margin-top: 15px;
grid-template-columns: repeat(3, 60px);
grid-template-rows: repeat(3, 60px);
gap: 6px;
}
#mobile-controls button {
background: rgba(76,175,80,0.2);
border: 1px solid #4caf50;
border-radius: 10px;
color: #4caf50;
font-size: 24px;
cursor: pointer;
}
#mobile-controls .up { grid-column: 2; grid-row: 1; }
#mobile-controls .left { grid-column: 1; grid-row: 2; }
#mobile-controls .right { grid-column: 3; grid-row: 2; }
#mobile-controls .down { grid-column: 2; grid-row: 3; }
@media (max-width: 768px) {
#mobile-controls { display: grid; }
}
</style>
</head>
<body>
<h1>贪吃蛇</h1>
<div id="info">
<div>分数: <span id="score">0</span></div>
<div>最高: <span id="high">0</span></div>
<div>长度: <span id="length">3</span></div>
</div>
<div id="game-container">
<canvas id="game" width="480" height="480"></canvas>
<div id="overlay">
<h2 id="ov-title">贪吃蛇</h2>
<p id="ov-text">吃掉食物变长,不要撞墙或撞到自己</p>
<button onclick="startGame()">开始游戏</button>
</div>
</div>
<div id="controls">
<select id="speed-select">
<option value="150">慢速</option>
<option value="100" selected>中速</option>
<option value="65">快速</option>
<option value="40">极速</option>
</select>
<button class="btn green" onclick="startGame()">重新开始</button>
</div>
<div id="mobile-controls">
<button class="up" onclick="setDir(0,-1)">▲</button>
<button class="left" onclick="setDir(-1,0)">◀</button>
<button class="right" onclick="setDir(1,0)">▶</button>
<button class="down" onclick="setDir(0,1)">▼</button>
</div>
<div id="hint">方向键 / WASD 控制 · 空格暂停 · 选择速度后开始</div>
<script>
var canvas = document.getElementById('game');
var ctx = canvas.getContext('2d');
var GRID = 24;
var COLS = canvas.width / GRID;
var ROWS = canvas.height / GRID;
var snake, dir, nextDir, food, score, highScore, speed, gameLoop, isPaused, state;
highScore = parseInt(localStorage.getItem('snakeHigh') || '0');
document.getElementById('high').textContent = highScore;
function init() {
snake = [
{ x: Math.floor(COLS/2), y: Math.floor(ROWS/2) },
{ x: Math.floor(COLS/2) - 1, y: Math.floor(ROWS/2) },
{ x: Math.floor(COLS/2) - 2, y: Math.floor(ROWS/2) }
];
dir = { x: 1, y: 0 };
nextDir = { x: 1, y: 0 };
score = 0;
isPaused = false;
state = 'playing';
spawnFood();
updateUI();
}
function spawnFood() {
var tries = 0;
while (tries < 200) {
var fx = Math.floor(Math.random() * COLS);
var fy = Math.floor(Math.random() * ROWS);
var onSnake = false;
for (var i = 0; i < snake.length; i++) {
if (snake[i].x === fx && snake[i].y === fy) { onSnake = true; break; }
}
if (!onSnake) {
food = { x: fx, y: fy };
return;
}
tries++;
}
}
function setDir(dx, dy) {
if (state !== 'playing' || isPaused) return;
// 不能180度掉头
if (snake.length > 1 && dx === -dir.x && dy === -dir.y) return;
nextDir = { x: dx, y: dy };
}
function update() {
if (state !== 'playing' || isPaused) return;
dir = nextDir;
var head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };
// 撞墙
if (head.x < 0 || head.x >= COLS || head.y < 0 || head.y >= ROWS) {
gameOver();
return;
}
// 撞自己
for (var i = 0; i < snake.length; i++) {
if (snake[i].x === head.x && snake[i].y === head.y) {
gameOver();
return;
}
}
snake.unshift(head);
// 吃到食物
if (head.x === food.x && head.y === food.y) {
score += 10;
if (score > highScore) {
highScore = score;
localStorage.setItem('snakeHigh', highScore);
}
spawnFood();
} else {
snake.pop();
}
updateUI();
}
function gameOver() {
state = 'gameover';
clearInterval(gameLoop);
showOverlay('游戏结束', '撞到了!', '重新开始');
}
function startGame() {
hideOverlay();
speed = parseInt(document.getElementById('speed-select').value);
init();
clearInterval(gameLoop);
gameLoop = setInterval(function() {
update();
draw();
}, speed);
draw();
}
function togglePause() {
if (state !== 'playing') return;
isPaused = !isPaused;
}
function updateUI() {
document.getElementById('score').textContent = score;
document.getElementById('high').textContent = highScore;
document.getElementById('length').textContent = snake.length;
}
function showOverlay(title, text, btn) {
document.getElementById('ov-title').textContent = title;
document.getElementById('ov-text').textContent = text;
var ov = document.getElementById('overlay');
ov.style.display = 'flex';
// 更新按钮文字
var btnEl = ov.querySelector('button');
btnEl.textContent = btn;
}
function hideOverlay() {
document.getElementById('overlay').style.display = 'none';
}
// ============ 渲染 ============
function draw() {
// 背景
ctx.fillStyle = '#1a1a2e';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 网格
ctx.strokeStyle = 'rgba(255,255,255,0.03)';
ctx.lineWidth = 1;
for (var i = 0; i <= COLS; i++) {
ctx.beginPath();
ctx.moveTo(i * GRID, 0);
ctx.lineTo(i * GRID, canvas.height);
ctx.stroke();
}
for (var j = 0; j <= ROWS; j++) {
ctx.beginPath();
ctx.moveTo(0, j * GRID);
ctx.lineTo(canvas.width, j * GRID);
ctx.stroke();
}
// 食物
drawFood();
// 蛇
for (var k = snake.length - 1; k >= 0; k--) {
drawSnakeSegment(snake[k], k === 0, k);
}
// 暂停提示
if (isPaused && state === 'playing') {
ctx.fillStyle = 'rgba(0,0,0,0.5)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.font = 'bold 32px "Microsoft YaHei"';
ctx.textAlign = 'center';
ctx.fillText('暂停', canvas.width / 2, canvas.height / 2);
}
}
function drawFood() {
var cx = food.x * GRID + GRID / 2;
var cy = food.y * GRID + GRID / 2;
var r = GRID / 2 - 3;
// 光晕
var glow = ctx.createRadialGradient(cx, cy, 0, cx, cy, r + 6);
glow.addColorStop(0, 'rgba(255,82,82,0.4)');
glow.addColorStop(1, 'rgba(255,82,82,0)');
ctx.fillStyle = glow;
ctx.beginPath();
ctx.arc(cx, cy, r + 6, 0, Math.PI * 2);
ctx.fill();
// 苹果
var grad = ctx.createRadialGradient(cx - 3, cy - 3, 0, cx, cy, r);
grad.addColorStop(0, '#ff8a80');
grad.addColorStop(0.5, '#ff5252');
grad.addColorStop(1, '#c62828');
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(cx, cy, r, 0, Math.PI * 2);
ctx.fill();
// 高光
ctx.fillStyle = 'rgba(255,255,255,0.5)';
ctx.beginPath();
ctx.ellipse(cx - r * 0.3, cy - r * 0.3, r * 0.25, r * 0.15, -0.5, 0, Math.PI * 2);
ctx.fill();
// 叶子
ctx.fillStyle = '#4caf50';
ctx.beginPath();
ctx.ellipse(cx + 2, cy - r, 4, 2, -0.8, 0, Math.PI * 2);
ctx.fill();
}
function drawSnakeSegment(seg, isHead, idx) {
var px = seg.x * GRID;
var py = seg.y * GRID;
var pad = 2;
var size = GRID - pad * 2;
// 颜色渐变:头部最亮
var t = idx / Math.max(snake.length, 1);
var r = Math.floor(76 + (129 - 76) * t);
var g = Math.floor(175 + (199 - 175) * t);
var b = Math.floor(80 + (132 - 80) * t);
var color = 'rgb(' + r + ',' + g + ',' + b + ')';
if (isHead) {
// 头部带光晕
ctx.shadowColor = '#4caf50';
ctx.shadowBlur = 10;
}
ctx.fillStyle = color;
roundRect(px + pad, py + pad, size, size, 6);
ctx.fill();
ctx.shadowBlur = 0;
// 高光
ctx.fillStyle = 'rgba(255,255,255,0.15)';
roundRect(px + pad + 2, py + pad + 2, size - 4, 5, 3);
ctx.fill();
// 头部画眼睛
if (isHead) {
ctx.fillStyle = '#fff';
var eyeSize = 3;
var cx = px + GRID / 2;
var cy = py + GRID / 2;
var e1x, e1y, e2x, e2y;
if (dir.x === 1) {
e1x = cx + 4; e1y = cy - 4; e2x = cx + 4; e2y = cy + 4;
} else if (dir.x === -1) {
e1x = cx - 4; e1y = cy - 4; e2x = cx - 4; e2y = cy + 4;
} else if (dir.y === 1) {
e1x = cx - 4; e1y = cy + 4; e2x = cx + 4; e2y = cy + 4;
} else {
e1x = cx - 4; e1y = cy - 4; e2x = cx + 4; e2y = cy - 4;
}
ctx.beginPath();
ctx.arc(e1x, e1y, eyeSize, 0, Math.PI * 2);
ctx.arc(e2x, e2y, eyeSize, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(e1x + dir.x, e1y + dir.y, 1.5, 0, Math.PI * 2);
ctx.arc(e2x + dir.x, e2y + dir.y, 1.5, 0, Math.PI * 2);
ctx.fill();
}
}
function roundRect(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
// ============ 输入 ============
document.addEventListener('keydown', function(e) {
switch(e.code) {
case 'ArrowUp': case 'KeyW': e.preventDefault(); setDir(0, -1); break;
case 'ArrowDown': case 'KeyS': e.preventDefault(); setDir(0, 1); break;
case 'ArrowLeft': case 'KeyA': e.preventDefault(); setDir(-1, 0); break;
case 'ArrowRight': case 'KeyD': e.preventDefault(); setDir(1, 0); break;
case 'Space': e.preventDefault(); togglePause(); break;
}
});
// 触屏滑动
var touchStart = null;
canvas.addEventListener('touchstart', function(e) {
e.preventDefault();
touchStart = { x: e.touches[0].clientX, y: e.touches[0].clientY };
});
canvas.addEventListener('touchend', function(e) {
if (!touchStart) return;
var dx = e.changedTouches[0].clientX - touchStart.x;
var dy = e.changedTouches[0].clientY - touchStart.y;
if (Math.abs(dx) > Math.abs(dy)) {
setDir(dx > 0 ? 1 : -1, 0);
} else {
setDir(0, dy > 0 ? 1 : -1);
}
touchStart = null;
});
// 初始画面
draw();
</script>
</body>
</html>
更多推荐

所有评论(0)