前序:前一段时间在都以上看到国内利用ChatGpt 3 做了一个手机软件,今天休息没事就用了一下,看看有没有什么有意思的事情,于是就利用他做了一个贪吃蛇的网页小游戏
有想了解ChatMe的朋友可以通过链接看一下他的抖音账号:ChatMe抖音账号
聊天截图:
当然过程之中忘记截图了,没法让大家直观地感受到他的生成速度,主观来讲的话还是不慢的,怎么形容呢,跟大家平时用小黑窗口运行代码时的输出速度差不多,这里他不仅生成了js代码,也把html页面中的标签在最近下面告诉我们,基本就是无脑cv了,方便大家观看我把他回复的部分一代码形式呈现给大家,也方便大家复制
好的,下面是一份可用的贪吃蛇游戏代码,注释以及简单的关卡和速度设置。
```javascript
// 获取 canvas 元素
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');// 设置 canvas 大小
canvas.width = 400;
canvas.height = 400;// 定义变量和常量
const blockSize = 10; // 块大小
let snake = [{x: 20, y: 20}]; // 蛇的初始位置
let direction = 'right'; // 蛇的初始方向
let food = null; // 食物初始位置
let score = 0; // 初始得分
let interval = null; // 计时器// 画出蛇和食物
function draw() {// 清空画布ctx.clearRect(0, 0, canvas.width, canvas.height);// 画蛇snake.forEach((block) => {ctx.fillStyle = 'green';ctx.fillRect(block.x, block.y, blockSize, blockSize);});// 画食物if (food) {ctx.fillStyle = 'red';ctx.fillRect(food.x, food.y, blockSize, blockSize);}
}// 生成随机食物
function generateFood() {const x = Math.floor(Math.random() * (canvas.width / blockSize)) * blockSize;const y = Math.floor(Math.random() * (canvas.height / blockSize)) * blockSize;// 如果食物与蛇重合,重新生成if (snake.some((block) => block.x === x && block.y === y)) {generateFood();} else {food = {x, y};}
}// 移动蛇
function move() {// 添加一个新的蛇头let x = snake[0].x;let y = snake[0].y;switch (direction) {case 'up':y -= blockSize;break;case 'down':y += blockSize;break;case 'left':x -= blockSize;break;case 'right':x += blockSize;break;}// 如果蛇吃到了食物,长度加一,重新生成食物if (x === food.x && y === food.y) {snake.unshift({x, y});score++;generateFood();} else {// 否则移除最后一个块,添加一个新的块snake.pop();snake.unshift({x, y});}// 如果蛇头撞到了边界或者自己的身体,游戏结束if (x < 0 || x >= canvas.width || y < 0 || y >= canvas.height || snake.some((block, index) => index > 0 && block.x === x && block.y === y)) {clearInterval(interval);alert(`游戏结束!得分:${score}`);}draw();
}// 开始游戏
function start() {// 初始化蛇和食物snake = [{x: 20, y: 20}];direction = 'right';generateFood();score = 0;// 设置速度const speed = document.getElementById('speed').value;interval = setInterval(move, speed);
}// 监听键盘事件
document.addEventListener('keydown', (event) => {switch (event.keyCode) {case 37:if (direction !== 'right') {direction = 'left';}break;case 38:if (direction !== 'down') {direction = 'up';}break;case 39:if (direction !== 'left') {direction = 'right';}break;case 40:if (direction !== 'up') {direction = 'down';}break;}
});// 开始按钮点击事件
document.getElementById('start').addEventListener('click', start);
```在 HTML 中,需要添加一个 canvas 元素和一个开始按钮,并设置速度选择器:
```html
<canvas id="canvas"></canvas>
<button id="start">开始</button>
<label for="speed">速度:</label>
<input type="range" id="speed" min="10" max="100" value="50">
```注意,这个代码只是一个非常简单的贪吃
可能由于软件字数限制的原因这里最下面的部分没有说完就结束了
为了测试他的上下文联系功能这里让他加上css样式,看看是否能够生效
当然可以,以下是一个简单的样式,你可以将其放入 `style` 标签中:
```css
#canvas {border: 2px solid black;background-color: #eee;
}button {font-size: 20px;padding: 10px 20px;margin-top: 20px;background-color: #4CAF50;color: white;border: none;border-radius: 5px;cursor: pointer;transition: all 0.3s;
}button:hover {background-color: #3e8e41;
}label {font-size: 18px;margin-left: 10px;
}input[type="range"] {width: 200px;margin-left: 10px;
}
```这个样式包括了一个有边框和背景色的 canvas,一个带有过渡效果的开始按钮,以及标签和速度选择器的样式。你可以根据自己的需求修改样式。
以上来看的话,他的生成模板应该是md的格式
这个时候代码其实就已经生效了,并且可以跑起来,而且速度也是可以控制的
但同时,这个代码也有问题,无法暂停,而且多次敲击回车会导致贪吃蛇不断加速,直到撞墙后,警示框会不断弹出,并且关不掉,当然代价已经想出了问题,所以这时我提出了优化代码的要求
好的,以下是优化后的代码,其中包含暂停游戏的功能:```javascript
// 获取 canvas 元素
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');// 设置 canvas 大小
canvas.width = 400;
canvas.height = 400;// 定义变量和常量
const blockSize = 10; // 块大小
let snake = [{x: 20, y: 20}]; // 蛇的初始位置
let direction = 'right'; // 蛇的初始方向
let food = null; // 食物初始位置
let score = 0; // 初始得分
let interval = null; // 计时器
let pause = false; // 游戏是否暂停// 画出蛇和食物
function draw() {// 清空画布ctx.clearRect(0, 0, canvas.width, canvas.height);// 画蛇snake.forEach((block) => {ctx.fillStyle = 'green';ctx.fillRect(block.x, block.y, blockSize, blockSize);});// 画食物if (food) {ctx.fillStyle = 'red';ctx.fillRect(food.x, food.y, blockSize, blockSize);}
}// 生成随机食物
function generateFood() {const x = Math.floor(Math.random() * (canvas.width / blockSize)) * blockSize;const y = Math.floor(Math.random() * (canvas.height / blockSize)) * blockSize;// 如果食物与蛇重合,重新生成if (snake.some((block) => block.x === x && block.y === y)) {generateFood();} else {food = {x, y};}
}// 移动蛇
function move() {if (pause) { // 如果游戏暂停,不执行移动操作return;}// 添加一个新的蛇头let x = snake[0].x;let y = snake[0].y;switch (direction) {case 'up':y -= blockSize;break;case 'down':y += blockSize;break;case 'left':x -= blockSize;break;case 'right':x += blockSize;break;}// 如果蛇吃到了食物,长度加一,重新生成食物if (x === food.x && y === food.y) {snake.unshift({x, y});score++;generateFood();} else {// 否则移除最后一个块,添加一个新的块snake.pop();snake.unshift({x, y});}// 如果蛇头撞到了边界或者自己的身体,游戏结束if (x < 0 || x >= canvas.width || y < 0 || y >= canvas.height || snake.some((block, index) => index > 0 && block.x === x && block.y === y)) {clearInterval(interval);alert(`游戏结束!得分:${score}`);}draw();
}// 开始游戏
function start() {// 初始化蛇和食物snake = [{x: 20, y: 20}];direction = 'right';generateFood();score = 0;// 设置速度const speed = document.getElementById('speed').value;interval = setInterval(move, speed);
}// 监听键盘事件
document.addEventListener('keydown', (event) => {switch (event.keyCode) {case 37:if (direction !== 'right') {direction = 'left';}break;case 38:if (direction !== 'down') {direction = 'up';}break;case 39:if (direction !== 'left') {direction = 'right';}break;case 40:if (direction !== 'up') {direction = 'down';}break;case 32: // 空格键pause = !pause;break;}
});// 开始按钮点击事件
document.getElementById('start').addEventListener('click', start);// 暂停按钮点击事件
document.getElementById('pause').addEventListener('click', () => {pause = !pause;
});
```在 HTML 中,需要添加一个暂停按钮:```html
<
但这个时候或许又是因为字符长度限制,信息没有全部加载出来,所以根据程序员的尿性,我又让他重新生成了一遍
好的,以下是完整的 HTML 代码,包括样式和按钮的代码:```html
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>贪吃蛇</title><style>#canvas {border: 1px solid black;}button {background-color: #0077CC;color: white;border: none;border-radius: 3px;padding: 10px 20px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 10px;transition-duration: 0.4s;cursor: pointer;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);}button:hover {background-color: #0051A9;}.wrapper {display: flex;justify-content: center;align-items: center;flex-direction: column;margin-top: 50px;}label {font-size: 20px;margin-right: 10px;}input[type="number"] {width: 50px;}</style>
</head>
<body><div class="wrapper"><canvas id="canvas"></canvas><div><label for="speed">速度:</label><input type="number" id="speed" min="50" max="1000" value="200"><button id="start">开始</button><button id="pause">暂停</button></div></div><script src="snake.js"></script>
</body>
</html>
```修改后的样式包含了一个拥有气泡效果的蓝色渐变色按钮,同时也添加了贪吃蛇游戏的相关样式。
修改之后虽然添加了暂停功能,但是加速问题依旧没有解决
暂停生效
bug依旧存在
所以继续询问
是的,为了解决这个问题,我们可以在每次按下回车键时,检查时间间隔是否足够长,如果足够长,才执行加速操作。我们可以使用一个变量来记录上次按下回车键的时间戳,然后在监听回车键事件时,计算当前时间戳与上一次时间戳的差值,如果时间差值小于某个特定值,就放弃执行加速操作。下面是一个示例代码,实现了在每次按下回车键时加速,但是避免了连续多次按回车键造成的重复加速问题:```javascript
let lastEnterTime = 0; // 用来记录上次按下回车键的时间戳document.addEventListener('keydown', event => {if (event.code === 'Enter') {const now = Date.now();const timeDiff = now - lastEnterTime; // 计算时间间隔if (timeDiff > 500) { // 如果时间间隔足够长(500 毫秒)lastEnterTime = now;// 执行加速操作}}
});
```在上面的代码中,我们使用了 `Date.now()` 方法来获取当前时间戳,然后计算与上一次时间戳的差值来判断时间间隔是否足够长。如果时间间隔足够长,就将当前时间戳赋值给 `lastEnterTime` 变量,以便下一次判断时使用。
但按照正常体验来说,开始按钮只具备开始功能,不会对游戏速度进行加速,回车也是一样,但碍于每日提问次数也就不了了之了
总的来说它具备一定的代码生成能力,并且有良好的编码规范,基本上改由注释的地方都添加注释了,但对于逻辑性的问题来说还是需要进一步加强
如果大家有什么好的想法可以分享在评论区,大家一起讨论一下
当然整体页面看下来也会有很多人还是觉得需要一点点看文章去修改,这里我把正常的格式放在下面,复制就可以Alt+B 啦
<!DOCTYPE HTML>
<html><head><title>贪吃蛇</title><style>#canvas {border: 1px solid black;}button {background-color: #0077CC;color: white;border: none;border-radius: 3px;padding: 10px 20px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 10px;transition-duration: 0.4s;cursor: pointer;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);}button:hover {background-color: #0051A9;}.wrapper {display: flex;justify-content: center;align-items: center;flex-direction: column;margin-top: 50px;}label {font-size: 20px;margin-right: 10px;}input[type="number"] {width: 50px;}</style>
</head><body><body><div class="wrapper"><canvas id="canvas"></canvas><div><label for="speed">速度:</label><input type="number" id="speed" min="50" max="1000" value="200"><button id="start">开始</button><button id="pause">暂停</button></div></div><script src="snake.js"></script></body><script>// 获取 canvas 元素const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 设置 canvas 大小canvas.width = 400;canvas.height = 400;// 定义变量和常量const blockSize = 10; // 块大小let snake = [{x: 20,y: 20}]; // 蛇的初始位置let direction = 'right'; // 蛇的初始方向let food = null; // 食物初始位置let score = 0; // 初始得分let interval = null; // 计时器let pause = false; // 游戏是否暂停// 画出蛇和食物function draw() {// 清空画布ctx.clearRect(0, 0, canvas.width, canvas.height);// 画蛇snake.forEach((block) => {ctx.fillStyle = 'green';ctx.fillRect(block.x, block.y, blockSize, blockSize);});// 画食物if (food) {ctx.fillStyle = 'red';ctx.fillRect(food.x, food.y, blockSize, blockSize);}}// 生成随机食物function generateFood() {const x = Math.floor(Math.random() * (canvas.width / blockSize)) * blockSize;const y = Math.floor(Math.random() * (canvas.height / blockSize)) * blockSize;// 如果食物与蛇重合,重新生成if (snake.some((block) => block.x === x && block.y === y)) {generateFood();} else {food = {x,y};}}// 移动蛇function move() {if (pause) { // 如果游戏暂停,不执行移动操作return;}// 添加一个新的蛇头let x = snake[0].x;let y = snake[0].y;switch (direction) {case 'up':y -= blockSize;break;case 'down':y += blockSize;break;case 'left':x -= blockSize;break;case 'right':x += blockSize;break;}// 如果蛇吃到了食物,长度加一,重新生成食物if (x === food.x && y === food.y) {snake.unshift({x,y});score++;generateFood();} else {// 否则移除最后一个块,添加一个新的块snake.pop();snake.unshift({x,y});}// 如果蛇头撞到了边界或者自己的身体,游戏结束if (x < 0 || x >= canvas.width || y < 0 || y >= canvas.height || snake.some((block, index) => index > 0 && block.x === x && block.y === y)) {clearInterval(interval);alert(`游戏结束!得分:${score}`);}draw();}// 开始游戏function start() {// 初始化蛇和食物snake = [{x: 20,y: 20}];direction = 'right';generateFood();score = 0;// 设置速度const speed = document.getElementById('speed').value;interval = setInterval(move, speed);}// 监听键盘事件document.addEventListener('keydown', (event) => {switch (event.keyCode) {case 37:if (direction !== 'right') {direction = 'left';}break;case 38:if (direction !== 'down') {direction = 'up';}break;case 39:if (direction !== 'left') {direction = 'right';}break;case 40:if (direction !== 'up') {direction = 'down';}break;case 32: // 空格键pause = !pause;break;}});// 开始按钮点击事件document.getElementById('start').addEventListener('click', start);// 暂停按钮点击事件document.getElementById('pause').addEventListener('click', () => {pause = !pause;});</script></body></html>
如果喜欢这篇文章的话记得点赞收藏哦👀