JavaScript蛇游戏

JavaScript蛇游戏,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我在移动蛇形元素时遇到问题。我在C#桌面应用程序中编写了一个蛇游戏,但在JavaScript中似乎无法使用相同的逻辑 这是我遇到麻烦的部分。基本上我有4个函数,只移动蛇头(数组的第一个元素),我使用这段代码移动身体的其他部分 for (i = snakeBody.length - 1; i > 0 ; i--) { context.rect(snakeBody[i].x,snakeBody[i].y,snakeBody[i].w,snakeBody[i].h); snake

我在移动蛇形元素时遇到问题。我在C#桌面应用程序中编写了一个蛇游戏,但在JavaScript中似乎无法使用相同的逻辑

这是我遇到麻烦的部分。基本上我有4个函数,只移动蛇头(数组的第一个元素),我使用这段代码移动身体的其他部分

for (i = snakeBody.length - 1; i > 0 ; i--) {
    context.rect(snakeBody[i].x,snakeBody[i].y,snakeBody[i].w,snakeBody[i].h);
    snakeBody[i]=snakeBody[i-1];
} 
问题是,它们都聚集在一起。我不明白为什么这在JavaScript中不起作用

这是完整的代码

window.onload= function ()
{
    var canvas=document.getElementById("canvas");
    var context=canvas.getContext("2d");

    var canvasWidth=window.innerWidth;
    var canvasHeight=window.innerHeight;
    canvas.width=canvasWidth;
    canvas.height=canvasHeight;

    var up=false;
    var down=false;
    var left=false;
    var right=true;

       var snake={
        x:20,
        y:0,
        w:20,
        h:20
    };
    var snakeBody=[];
    for (i = 0; i < 5; i++) {
        snakeBody.push({
        x:snake.x ,
        y:snake.y ,
        w:snake.w,
        h:snake.h
    });
    snake.x +=20;
    }

    var food={
        x:Math.random() * canvasWidth,
        y:Math.random() * canvasHeight,
        w:2,
        h:2
    };

    function moveUp()
    {

            snakeBody[0].y -=3;

    }
    function moveDown()
    {

            snakeBody[0].y +=3;

    }
    function moveLeft()
    {

            snakeBody[0].x -=3;

    }
    function moveRight()
    {

            snakeBody[0].x +=3;


    }
    function draw()
    {
        context.clearRect(0,0,canvasWidth,canvasHeight);
        context.fillStyle="rgba(230,230,230,0.1)";
        context.beginPath();

       for (i = snakeBody.length - 1; i > 0 ; i--) {
           context.rect(snakeBody[i].x,snakeBody[i].y,snakeBody[i].w,snakeBody[i].h);
           snakeBody[i]=snakeBody[i-1];
        }
        //context.rect(food.x,food.y,food.w,food.h);

        context.stroke();
        context.fill();

        directions();
        collision();
        update();
    }
    function directions()
    {
        document.onkeydown = function(e)
        {
           var event = window.event ? window.event : e;
             var keycode = event.keyCode;
            if (keycode===37 && right===false) {
                left=true;
                right=false;
                up=false;
                down=false;
            }
            if (keycode===38 && down===false) {
                up=true;
                down=false;
                left=false;
                right=false;
            }
            if (keycode===39 && left===false) {
                right=true;
                left=false;
                up=false;
                down=false;
            }
            if (keycode===40 && up===false) {
                down=true;
                up=false;
                left=false;
                right=false;
            }
        };
    }
    function update()
    {
        if (up) {moveUp();}
        if (down) {moveDown();}
        if (left) {moveLeft();}
        if (right) {moveRight();}
    }
     function collision()
     {
         for (i = 0; i < snakeBody.length; i++) {
            if (snakeBody[i].x >canvasWidth) {
            snakeBody[i].x  = 0;
        }
        if (snakeBody[i].x < 0) {
            snakeBody[i].x=canvasWidth;
        }
        if (snakeBody[i].y>canvasHeight) {
            snakeBody[i].y=0;
        }
        if (snakeBody[i].y <0) {
            snakeBody[i].y=canvasHeight;
        }
        } 
     }
        setInterval(draw,40);
};
window.onload=函数()
{
var canvas=document.getElementById(“canvas”);
var context=canvas.getContext(“2d”);
var canvasWidth=window.innerWidth;
var canvasHeight=window.innerHeight;
canvas.width=画布宽度;
canvas.height=画布高度;
var-up=false;
var-down=false;
var left=false;
var-right=true;
变种蛇={
x:20,
y:0,
w:20,
h:20
};
var蛇体=[];
对于(i=0;i<5;i++){
蛇身({
x:snake.x,
y:蛇,y,
w:蛇,
蛇
});
snake.x+=20;
}
变种食品={
x:Math.random()*画布宽度,
y:Math.random()*画布高度,
w:2,
h:2
};
函数moveUp()
{
蛇体[0],y-=3;
}
函数moveDown()
{
蛇体[0],y+=3;
}
函数moveLeft()
{
蛇体[0].x-=3;
}
函数moveRight()
{
蛇体[0].x+=3;
}
函数绘图()
{
clearRect(0,0,画布宽度,画布高度);
context.fillStyle=“rgba(230230,0.1)”;
context.beginPath();
对于(i=snakeBody.length-1;i>0;i--){
context.rect(蛇体[i].x,蛇体[i].y,蛇体[i].w,蛇体[i].h);
蛇体[i]=蛇体[i-1];
}
//context.rect(food.x,food.y,food.w,food.h);
stroke();
context.fill();
方向();
碰撞();
更新();
}
函数方向()
{
document.onkeydown=函数(e)
{
var事件=window.event?window.event:e;
var keycode=event.keycode;
if(keycode==37&&right==false){
左=真;
右=假;
向上=错误;
向下=假;
}
if(keycode==38&&down==false){
向上=真;
向下=假;
左=假;
右=假;
}
if(keycode==39&&left==false){
右=真;
左=假;
向上=错误;
向下=假;
}
if(keycode==40&&up==false){
向下=真;
向上=错误;
左=假;
右=假;
}
};
}
函数更新()
{
if(up){moveUp();}
如果(向下){moveDown();}
如果(左){moveLeft();}
如果(右){moveRight();}
}
函数冲突()
{
对于(i=0;i画布宽度){
蛇体[i].x=0;
}
if(蛇体[i].x<0){
蛇身[i].x=画布宽度;
}
if(蛇身[i].y>画布高度){
蛇体[i].y=0;
}

如果(snakeBody[i].y我相信你的问题是你想把snake[i]的值设置为snake[i-1],但实际上你把snake[i]设置为snake[i-1]的引用。你把所有数组都设置为同一个对象。你可以这样做来解决这个问题

snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;

你还会遇到另一个问题,因为你只移动了蛇的3个部分,而不是它身体部分的宽度。

看不出你的推理:你将第一个单元格移动了3个像素,然后用前面的单元格替换其他单元格?我移动了第一个元素,然后在后面迭代其他元素。你不明白什么nd?同样的逻辑也适用于C#。当你将每个线段设置为它前面的线段,然后将第一个线段移动3个像素,因为每个线段都有20个像素宽,最终每个线段重叠17个像素。我看到了。你有解决方案吗?如果我将它们移动20个像素,它会移动得很粗。做得好!还有@Peter,The你提供的代码没有画出头部谢谢,这就解决了它。我有点修复了它,但它不是一个真正的修复,这是一个解决办法。我把它填充成黑色,你看不到元素彼此重叠的一半。我建议让蛇每次移动20像素,但只是让它移动的频率降低,并随着时间的延长而加快,我建议我相信这就是游戏通常的工作原理。如果我将它们移动20像素,它会移动得很粗,一点也不平滑。@graeme,我记得不久前我写过一个控制台蛇,它使用一个带有排队和出列的队列。你认为它比这个更好吗?