再次更新
R2迟迟未到,昨天DeepSeek再次更新了R1,版本号是R1-0528。
距离上次V3-0324过去差不多两个月。
这次R1-0528更新主要在语义精准性,复杂逻辑推理,长文本处理稳定性方面做了优化。
参数规模在685B左右,是否意味着R2参数规模会超过R1-0528?还不得而知。
那就,写个贪吃蛇把
可以在官网和APP,小程序快速体验。
那就直接在官网试试。
下面是生成过程,效果(不得不说,现在效率确实提升不少,一点都不卡)
提示词:
帮我用Three.js写一个贪吃蛇游戏,要求,界面美观,可进行基本操作
思考过程:
为了用Three.js创建一个贪吃蛇游戏,我们需要以下步骤:
1. 设置场景、相机、渲染器
2. 创建蛇和食物的基本元素(使用立方体)
3. 处理用户输入(键盘控制蛇的方向)
4. 实现游戏循环:移动蛇,检查是否吃到食物,检查碰撞,更新分数等
5. 设计美观的界面(包括材质、灯光、背景等)
我们将使用以下基本结构:
- 蛇身由一系列立方体组成,初始长度为3
- 食物是一个随机位置生成的立方体
- 游戏区域是一个二维网格(比如20x20),蛇和食物都在网格的整数坐标上
注意:为了美观,我们会使用一些材质和灯光效果。
由于代码较长,我将分步骤编写。
步骤:
1. 初始化场景、相机、渲染器
2. 添加灯光
3. 创建蛇和食物
4. 设置游戏循环
5. 处理键盘事件
6. 实现游戏逻辑(移动、吃食物、碰撞检测等)
为了简化,我们设定游戏区域为20x20,网格大小为1,但渲染时每个方块之间留一点空隙,这样看起来更清晰。
我们将使用OrthographicCamera(正交相机)来保持2D效果。
注意:由于Three.js是3D引擎,但我们做的是2D游戏,所以我们将所有物体的z坐标设为0。
游戏区域:从(0,0)到(20,20),但为了居中显示,我们可以将相机对准(10,10)。
下面开始写代码:
输出:
Three.js贪吃蛇游戏
我将使用Three.js创建一个美观且可玩的贪吃蛇游戏,具有现代UI设计和流畅的动画效果。
设计思路
使用3D立方体表示蛇身和食物
实现键盘控制蛇移动
添加碰撞检测和得分系统
设计简洁现代的游戏界面
加入游戏状态控制(开始/暂停/重新开始)
下面是完整的实现代码:
完整代码(可以在DeepSeek官网点击直接预览,也可以本地预览):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js 贪吃蛇游戏</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a1a2e, #16213e);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
overflow: hidden;
}
.container {
max-width: 1000px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
header {
text-align: center;
margin-bottom: 20px;
}
h1 {
font-size: 3rem;
margin-bottom: 10px;
background: linear-gradient(90deg, #ff9a9e, #fad0c4);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.game-stats {
display: flex;
justify-content: center;
gap: 30px;
margin: 15px 0;
font-size: 1.2rem;
background: rgba(255, 255, 255, 0.1);
padding: 12px 30px;
border-radius: 50px;
backdrop-filter: blur(10px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.stat {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-value {
font-weight: bold;
font-size: 1.5rem;
color: #64feda;
}
#game-container {
width: 600px;
height: 450px;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0,0,0,0.4);
position: relative;
}
.controls {
display: flex;
gap: 15px;
margin-top: 25px;
flex-wrap: wrap;
justify-content: center;
}
.btn {
padding: 12px 30px;
border: none;
border-radius: 50px;
background: linear-gradient(90deg, #ff9a9e, #fad0c4);
color: #1a1a2e;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
}
.btn:active {
transform: translateY(1px);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.instructions {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 15px;
margin-top: 25px;
max-width: 600px;
backdrop-filter: blur(10px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.instructions h2 {
text-align: center;
margin-bottom: 15px;
color: #64feda;
}
.instructions ul {
list-style: none;
padding: 0 15px;
}
.instructions li {
margin: 10px 0;
display: flex;
align-items: center;
}
.instructions li::before {
content: "•";
color: #ff9a9e;
font-size: 1.5rem;
margin-right: 10px;
}
.game-over {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s ease;
}
.game-over.show {
opacity: 1;
pointer-events: all;
}
.game-over h2 {
font-size: 3rem;
color: #ff6b6b;
margin-bottom: 20px;
}
.game-over p {
font-size: 1.5rem;
margin-bottom: 30px;
}
@media (max-width: 650px) {
#game-container {
width: 95vw;
height: 70vw;
}
.controls {
flex-direction: column;
align-items: center;
}
.btn {
width: 80%;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Three.js 贪吃蛇</h1>
<p>经典游戏的全新3D体验</p>
</header>
<div class="game-stats">
<div class="stat">
<span>得分</span>
<span id="score" class="stat-value">0</span>
</div>
<div class="stat">
<span>长度</span>
<span id="length" class="stat-value">3</span>
</div>
<div class="stat">
<span>速度</span>
<span id="speed" class="stat-value">1x</span>
</div>
</div>
<div id="game-container">
<div class="game-over">
<h2>游戏结束!</h2>
<p>最终得分: <span id="final-score">0</span></p>
<button id="restart-btn" class="btn">重新开始</button>
</div>
</div>
<div class="controls">
<button id="start-btn" class="btn">开始游戏</button>
<button id="pause-btn" class="btn" disabled>暂停</button>
<button id="reset-btn" class="btn">重置</button>
</div>
<div class="instructions">
<h2>游戏说明</h2>
<ul>
<li>使用键盘 <strong>方向键</strong> 或 <strong>WASD</strong> 控制蛇的移动方向</li>
<li>吃到 <span style="color: #ff9a9e; font-weight: bold">红色食物</span> 可以增加蛇的长度和得分</li>
<li>撞到墙壁或自己的身体会导致游戏结束</li>
<li>随着得分增加,蛇的移动速度会逐渐加快</li>
</ul>
</div>
</div>
<script>
// 游戏变量
let scene, camera, renderer;
let snake = [];
let food = null;
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let gameStarted = false;
let gamePaused = false;
let gameOver = false;
let score = 0;
let snakeLength = 3;
let speed = 150; // 毫秒
let gameInterval;
// 初始化Three.js场景
function init() {
// 创建场景
scene = new THREE.Scene();
scene.background = new THREE.Color(0x0c1e3e);
// 创建相机
camera = new THREE.PerspectiveCamera(75, 600 / 450, 0.1, 1000);
camera.position.set(0, 0, 30);
camera.lookAt(0, 0, 0);
// 创建渲染器
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(600, 450);
document.getElementById('game-container').appendChild(renderer.domElement);
// 添加灯光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 15);
scene.add(directionalLight);
// 创建游戏区域
createGameArea();
// 初始化蛇
initSnake();
// 创建食物
createFood();
// 开始动画循环
animate();
}
// 创建游戏区域
function createGameArea() {
const gridSize = 20;
const gridHelper = new THREE.GridHelper(gridSize, gridSize, 0x2a3b5c, 0x1a2a4a);
gridHelper.position.y = -0.5;
scene.add(gridHelper);
// 添加边界
const boundaryGeometry = new THREE.BoxGeometry(gridSize, 1, 1);
const boundaryMaterial = new THREE.MeshPhongMaterial({ color: 0x64feda, transparent: true, opacity: 0.7 });
// 顶部边界
const topBoundary = new THREE.Mesh(boundaryGeometry, boundaryMaterial);
topBoundary.position.set(0, gridSize/2, 0);
scene.add(topBoundary);
// 底部边界
const bottomBoundary = new THREE.Mesh(boundaryGeometry, boundaryMaterial);
bottomBoundary.position.set(0, -gridSize/2, 0);
scene.add(bottomBoundary);
// 左侧边界
const leftBoundary = new THREE.Mesh(boundaryGeometry, boundaryMaterial);
leftBoundary.rotation.z = Math.PI/2;
leftBoundary.position.set(-gridSize/2, 0, 0);
scene.add(leftBoundary);
// 右侧边界
const rightBoundary = new THREE.Mesh(boundaryGeometry, boundaryMaterial);
rightBoundary.rotation.z = Math.PI/2;
rightBoundary.position.set(gridSize/2, 0, 0);
scene.add(rightBoundary);
}
// 初始化蛇
function initSnake() {
// 移除现有蛇身
snake.forEach(segment => scene.remove(segment));
snake = [];
// 创建蛇头
const headGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
const headMaterial = new THREE.MeshPhongMaterial({ color: 0x64feda });
const head = new THREE.Mesh(headGeometry, headMaterial);
head.position.set(0, 0, 0);
scene.add(head);
snake.push(head);
// 创建蛇身
const bodyMaterial = new THREE.MeshPhongMaterial({ color: 0x4ecdc4 });
for (let i = 1; i < snakeLength; i++) {
const bodyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
body.position.set(-i, 0, 0);
scene.add(body);
snake.push(body);
}
// 重置方向
direction = { x: 1, y: 0 };
nextDirection = { x: 1, y: 0 };
}
// 创建食物
function createFood() {
// 移除现有食物
if (food) scene.remove(food);
// 创建新食物
const foodGeometry = new THREE.SphereGeometry(0.5, 16, 16);
const foodMaterial = new THREE.MeshPhongMaterial({
color: 0xff6b6b,
shininess: 100,
emissive: 0xff0000,
emissiveIntensity: 0.2
});
food = new THREE.Mesh(foodGeometry, foodMaterial);
// 随机位置 (在边界内)
const gridSize = 9; // 20/2 - 0.5 (边界宽度)
food.position.set(
Math.floor(Math.random() * (gridSize * 2 + 1) - gridSize),
Math.floor(Math.random() * (gridSize * 2 + 1) - gridSize),
0
);
// 确保食物不出现在蛇身上
let validPosition = false;
while (!validPosition) {
validPosition = true;
for (let segment of snake) {
if (Math.abs(segment.position.x - food.position.x) < 1 &&
Math.abs(segment.position.y - food.position.y) < 1) {
food.position.set(
Math.floor(Math.random() * (gridSize * 2 + 1) - gridSize),
Math.floor(Math.random() * (gridSize * 2 + 1) - gridSize),
0
);
validPosition = false;
break;
}
}
}
scene.add(food);
}
// 移动蛇
function moveSnake() {
if (gameOver || gamePaused || !gameStarted) return;
// 更新方向
direction = { ...nextDirection };
// 保存蛇尾位置
const tailPosition = {
x: snake[snake.length - 1].position.x,
y: snake[snake.length - 1].position.y
};
// 移动蛇身(从尾部到头部)
for (let i = snake.length - 1; i > 0; i--) {
snake[i].position.x = snake[i - 1].position.x;
snake[i].position.y = snake[i - 1].position.y;
}
// 移动蛇头
snake[0].position.x += direction.x;
snake[0].position.y += direction.y;
// 检查是否吃到食物
if (Math.abs(snake[0].position.x - food.position.x) < 1 &&
Math.abs(snake[0].position.y - food.position.y) < 1) {
// 增加分数
score += 10;
document.getElementById('score').textContent = score;
// 增加蛇的长度
snakeLength++;
document.getElementById('length').textContent = snakeLength;
// 创建新的蛇身
const bodyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
const bodyMaterial = new THREE.MeshPhongMaterial({ color: 0x4ecdc4 });
const newSegment = new THREE.Mesh(bodyGeometry, bodyMaterial);
newSegment.position.set(tailPosition.x, tailPosition.y, 0);
scene.add(newSegment);
snake.push(newSegment);
// 创建新食物
createFood();
// 增加速度(最多增加到4倍)
if (speed > 60 && snakeLength % 5 === 0) {
speed -= 10;
clearInterval(gameInterval);
gameInterval = setInterval(moveSnake, speed);
document.getElementById('speed').textContent = (150/speed).toFixed(1) + 'x';
}
}
// 检查碰撞
checkCollisions();
}
// 检查碰撞
function checkCollisions() {
const head = snake[0];
const gridSize = 9; // 20/2 - 0.5 (边界宽度)
// 检查墙壁碰撞
if (Math.abs(head.position.x) > gridSize || Math.abs(head.position.y) > gridSize) {
endGame();
return;
}
// 检查自身碰撞
for (let i = 1; i < snake.length; i++) {
if (Math.abs(head.position.x - snake[i].position.x) < 0.5 &&
Math.abs(head.position.y - snake[i].position.y) < 0.5) {
endGame();
return;
}
}
}
// 结束游戏
function endGame() {
gameOver = true;
clearInterval(gameInterval);
document.getElementById('final-score').textContent = score;
document.querySelector('.game-over').classList.add('show');
// 蛇头变红色
snake[0].material.color.set(0xff6b6b);
}
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 旋转食物
if (food) {
food.rotation.x += 0.02;
food.rotation.y += 0.03;
}
// 蛇身波动效果
const time = Date.now() * 0.002;
for (let i = 0; i < snake.length; i++) {
const segment = snake[i];
if (i > 0) {
segment.rotation.y = Math.sin(time + i * 0.2) * 0.1;
}
}
renderer.render(scene, camera);
}
// 键盘控制
document.addEventListener('keydown', (event) => {
if (!gameStarted || gamePaused || gameOver) return;
switch(event.key) {
case 'ArrowUp':
case 'w':
case 'W':
if (direction.y === 0) nextDirection = { x: 0, y: 1 };
break;
case 'ArrowDown':
case 's':
case 'S':
if (direction.y === 0) nextDirection = { x: 0, y: -1 };
break;
case 'ArrowLeft':
case 'a':
case 'A':
if (direction.x === 0) nextDirection = { x: -1, y: 0 };
break;
case 'ArrowRight':
case 'd':
case 'D':
if (direction.x === 0) nextDirection = { x: 1, y: 0 };
break;
}
});
// 按钮事件
document.getElementById('start-btn').addEventListener('click', () => {
if (gameStarted && !gamePaused) return;
if (gameOver) {
resetGame();
}
gameStarted = true;
gamePaused = false;
if (!gameInterval) {
gameInterval = setInterval(moveSnake, speed);
}
document.getElementById('start-btn').disabled = true;
document.getElementById('pause-btn').disabled = false;
});
document.getElementById('pause-btn').addEventListener('click', () => {
if (!gameStarted || gameOver) return;
gamePaused = !gamePaused;
if (gamePaused) {
clearInterval(gameInterval);
gameInterval = null;
document.getElementById('pause-btn').textContent = '继续';
} else {
gameInterval = setInterval(moveSnake, speed);
document.getElementById('pause-btn').textContent = '暂停';
}
});
document.getElementById('reset-btn').addEventListener('click', () => {
resetGame();
});
document.getElementById('restart-btn').addEventListener('click', () => {
resetGame();
document.getElementById('start-btn').disabled = true;
document.getElementById('pause-btn').disabled = false;
gameStarted = true;
gamePaused = false;
gameInterval = setInterval(moveSnake, speed);
});
// 重置游戏
function resetGame() {
clearInterval(gameInterval);
gameInterval = null;
gameStarted = false;
gamePaused = false;
gameOver = false;
score = 0;
snakeLength = 3;
speed = 150;
document.getElementById('score').textContent = '0';
document.getElementById('length').textContent = '3';
document.getElementById('speed').textContent = '1x';
document.querySelector('.game-over').classList.remove('show');
document.getElementById('pause-btn').textContent = '暂停';
document.getElementById('start-btn').disabled = false;
document.getElementById('pause-btn').disabled = true;
// 重新初始化游戏
scene.remove(food);
initSnake();
createFood();
}
// 初始化游戏
window.onload = init;
</script>
</body>
</html>
后面还跟了一段功能说明:
功能说明
这个贪吃蛇游戏具有以下特点:
美观的3D效果:
使用Three.js创建的3D蛇和食物
蛇身有波动动画效果
食物有旋转动画
现代UI设计,渐变色和半透明元素
游戏功能:
键盘控制(方向键或WASD)
得分系统(每吃一个食物得10分)
蛇长度显示
速度随分数增加而提高
碰撞检测(墙壁和自身)
游戏控制:
开始/暂停/继续按钮
重置游戏按钮
游戏结束画面和重新开始选项
响应式设计:
适配不同屏幕尺寸
在移动设备上自动调整布局
操作指南
点击"开始游戏"按钮开始
使用键盘方向键或WASD控制蛇的移动方向
吃到红色食物增加蛇的长度和得分
避免撞到墙壁或自己的身体
游戏结束后可点击"重新开始"按钮
您可以直接复制上面的代码到HTML文件中,在浏览器中打开即可开始游戏!
运行效果:
玩了一下:
总结
可以看到效果不错,页面设计比较美观,操作流畅。生成的代码无需任何修改即可上手。
不敢想R2会有多强。