Javascript 如何阻止蛇斜行?

Javascript 如何阻止蛇斜行?,javascript,css,html,html5-canvas,Javascript,Css,Html,Html5 Canvas,我正在用JavaScript编写一个蛇游戏,我希望蛇只垂直或水平移动,但它一直沿对角线移动。例如,如果我向上按,它会向上移动,但如果我向右按,它会沿对角线移动,而不仅仅是向右移动 const canvas=document.querySelector'canvas' const ctx=canvas.getContext'2d' 常数长度与宽度=15; 让蛇合作社=[ {x:300,y:150}, {x:315,y:150}, {x:330,y:150}, {x:345,y:150}, {x:

我正在用JavaScript编写一个蛇游戏,我希望蛇只垂直或水平移动,但它一直沿对角线移动。例如,如果我向上按,它会向上移动,但如果我向右按,它会沿对角线移动,而不仅仅是向右移动

const canvas=document.querySelector'canvas' const ctx=canvas.getContext'2d' 常数长度与宽度=15; 让蛇合作社=[ {x:300,y:150}, {x:315,y:150}, {x:330,y:150}, {x:345,y:150}, {x:360,y:150}, {x:375,y:150} ]; 函数DrawSnakePart SnakePart{ ctx.beginPath; ctx.fillRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.strokeRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.closePath; } 功能牵引蛇{ 蛇蝎;蛇蝎; } 函数moveSnakedx,dy{ 警察局长={ x:Snakecord[0].x+dx, y:Snakecord[0]。y+dy }; 蛇头; 毒蛇; ctx.clearRect0,0,canvas.width,canvas.height; 拉丝蛇; setTimeoutfunction{ 移动蛇 }, 100; } 功能按键{ 设key=e.key; 如果键==箭头向上{ 如果蛇坐标[0].y-长度\宽度!==蛇坐标[1].y{ moveSnake0,-长度和宽度; } }否则,如果键==箭头向下{ 如果蛇坐标[0].y+长度\宽度!==蛇坐标[1].y{ 移动蛇0,长度\宽度; } }否则,如果键==箭头左{ 如果蛇坐标[0].x-长度\宽度!==蛇坐标[1].x{ 移动长度×宽度,0; } }否则,如果键==箭头右键{ 如果蛇坐标[0].x+长度\宽度!==蛇坐标[1].x{ 移动蛇的长度和宽度,0; } } } 拉丝蛇; document.addEventListenerkeyup,按键;
在每次按键时,然后递归地设置新的超时setTimeoutfunction{moveSnakedx,dy},100;。您最终会遇到越来越多的控制性moveSnake调用


在调用moveSnake之前,您应该将timeout保存到一个变量中,并在按键上用clearTimeout清除它。

在每个按键上,然后递归地设置新的timeout setTimeoutfunction{moveSnakedx,dy},100;。您最终会遇到越来越多的控制性moveSnake调用


在调用moveSnake之前,您应该将timeout保存到一个变量中,并使用键盘上的clearTimeout清除它。

与其让键盘处理程序调用一个启动自己计时器循环的move方法,不如使用一个更新例程来更新一帧动画的所有内容。还应使用尽可能快的速度驱动渲染,并使每个渲染请求在下一个动画帧中执行。请参见提供的链接中的示例。如果想要较慢的动画,则可以使用单独的计时器逐步更新场景。相信我,总有一天你会想要高帧速率的动画,即使是在你的循序渐进的游戏中

我很无聊,所以我决定对你的代码进行一些修改

const canvas=document.querySelector'canvas' const ctx=canvas.getContext'2d' 常数长度与宽度=15; 让蛇合作社=[ {x:300,y:150}, {x:315,y:150}, {x:330,y:150}, {x:345,y:150}, {x:360,y:150}, {x:375,y:150} ]; 让蛇={ 目录:{dx:-1,dy:0}, nextDir:[],//缓冲方向更改 速度:5,//步/秒 棘轮:0 }; 函数DrawSnakePart SnakePart{ ctx.beginPath; ctx.fillRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.strokeRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.closePath; } 功能牵引蛇{ 蛇蝎;蛇蝎; } 函数移动蛇{ 如果snake.nextDir[0]{ //只有在不会让你加倍努力的情况下才能改变方向 如果蛇坐标[0].x+snake.nextDir[0].dx*长度\宽度!==蛇坐标[1].x &&蛇坐标[0].y+snake.nextDir[0].dy*长度\宽度!==snakeCoord[1].y{ snake.dir=snake.nextDir[0]; } snake.nextDir.shift1; } 警察局长={ x:snakeCoord[0].x+snake.dir.dx*长度×宽度, y:snakeCoord[0]。y+snake.dir.dy*长度\宽度 }; 蛇头; 毒蛇; } 功能按键{ 设key=e.key; 如果键==箭头向上{ 设置方向0,-1; }否则,如果键==箭头向下{ 设置方向0,1; }否则,如果键==箭头左{ 设置方向-1,0; }否则,如果键==箭头右键{ 设置方向1,0; } e、 防止违约; } 拉丝蛇; 让lastTime=新日期; window.requestAnimationFramerender; 函数设置方向dx,dy{ snake.nextDir.push{dx,dy};//覆盖任何挂起的方向更改。 } 功能更新{ 让现在=Date.now; 让经过的时间=现在-上次时间/1000; snake.ratchet+=经过的时间*snake.speed; 而snake.ratchet>=1{ 移动蛇; 蛇形棘轮-=1; } 上次=现在; } 函数渲染{ ctx.clearRect0,0,canvas.width,canvas.height; 使现代化 拉丝蛇; window.requestAnimationFramerender; } document.addEventListenerkeydown,按键; * { 溢出:隐藏 }
而不是让键盘处理程序调用一个move方法来启动它自己的计时器loo p、 您应该有一个更新例程来更新一帧动画的所有内容。还应使用尽可能快的速度驱动渲染,并使每个渲染请求在下一个动画帧中执行。请参见提供的链接中的示例。如果想要较慢的动画,则可以使用单独的计时器逐步更新场景。相信我,总有一天你会想要高帧速率的动画,即使是在你的循序渐进的游戏中

我很无聊,所以我决定对你的代码进行一些修改

const canvas=document.querySelector'canvas' const ctx=canvas.getContext'2d' 常数长度与宽度=15; 让蛇合作社=[ {x:300,y:150}, {x:315,y:150}, {x:330,y:150}, {x:345,y:150}, {x:360,y:150}, {x:375,y:150} ]; 让蛇={ 目录:{dx:-1,dy:0}, nextDir:[],//缓冲方向更改 速度:5,//步/秒 棘轮:0 }; 函数DrawSnakePart SnakePart{ ctx.beginPath; ctx.fillRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.strokeRectsnakePart.x,snakePart.y,长度\宽度,长度\宽度; ctx.closePath; } 功能牵引蛇{ 蛇蝎;蛇蝎; } 函数移动蛇{ 如果snake.nextDir[0]{ //只有在不会让你加倍努力的情况下才能改变方向 如果蛇坐标[0].x+snake.nextDir[0].dx*长度\宽度!==蛇坐标[1].x &&蛇坐标[0].y+snake.nextDir[0].dy*长度\宽度!==snakeCoord[1].y{ snake.dir=snake.nextDir[0]; } snake.nextDir.shift1; } 警察局长={ x:snakeCoord[0].x+snake.dir.dx*长度×宽度, y:snakeCoord[0]。y+snake.dir.dy*长度\宽度 }; 蛇头; 毒蛇; } 功能按键{ 设key=e.key; 如果键==箭头向上{ 设置方向0,-1; }否则,如果键==箭头向下{ 设置方向0,1; }否则,如果键==箭头左{ 设置方向-1,0; }否则,如果键==箭头右键{ 设置方向1,0; } e、 防止违约; } 拉丝蛇; 让lastTime=新日期; window.requestAnimationFramerender; 函数设置方向dx,dy{ snake.nextDir.push{dx,dy};//覆盖任何挂起的方向更改。 } 功能更新{ 让现在=Date.now; 让经过的时间=现在-上次时间/1000; snake.ratchet+=经过的时间*snake.speed; 而snake.ratchet>=1{ 移动蛇; 蛇形棘轮-=1; } 上次=现在; } 函数渲染{ ctx.clearRect0,0,canvas.width,canvas.height; 使现代化 拉丝蛇; window.requestAnimationFramerender; } document.addEventListenerkeydown,按键; * { 溢出:隐藏 }
请分享你的完整JavaScript和HTML代码。请分享完整代码。当我尝试运行代码段时,我得到一个错误,uncaughtreferenceerror:ctx未定义。缺少代码。类似这样的内容:JS:var canvas=$canvas[0];var ctx=canvas.getContext2d;,HTML:。请把完整的密码贴出来。类似的游戏:似乎问题是当你改变方向时,你永远不会停止以前的方向运动。查找请分享您的完整JavaScript和HTML代码。请提供完整代码。当我尝试运行代码段时,我得到一个错误,uncaughtreferenceerror:ctx未定义。缺少代码。类似这样的内容:JS:var canvas=$canvas[0];var ctx=canvas.getContext2d;,HTML:。请把完整的密码贴出来。类似的游戏:似乎问题是当你改变方向时,你永远不会停止以前的方向运动。“查找”在画布接受我相信的关键笔划之前,你必须通过单击它来为画布提供焦点。在画布接受我相信的关键笔划之前,你必须通过单击它来为画布提供焦点。