简体   繁体   English

蛇javascript游戏的速度

[英]Speed of snake javascript game

I'm trying to create a simple snake game in JavaScript, so far so good, I have a code that works but there is a behavior I would like to remove.我正在尝试用 JavaScript 创建一个简单的蛇游戏,到目前为止一切顺利,我有一个可以工作的代码,但我想删除一个行为。

Following is my JavaScript code以下是我的 JavaScript 代码

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var W = canvas.width = window.innerWidth;
var H = canvas.height = window.innerHeight;
var width = 10;
var height = 10;
var direction="right";
var snake = {
    length: 5,
    array_length: [],

    draw: function () {
        ctx.clearRect(0,0,W,H);
        this.array_length.forEach(function (x) {
            ctx.beginPath();
            ctx.fillStyle = "blue";
            ctx.fillRect(x.x, x.y, width, height);
        });
        this.update();
    },
    update: function () {
        var first = this.array_length[0];
        var first_x = first.x;
        var first_y = first.y;


        switch (direction) {

            case "right":
                first_x++;
                break;
            case "left":
                first_x-=10;
                break;
            case "up":
                first_y-=10;
                break;
            case "down":
                first_y+=10;
                break;

        }
        var lasat=this.array_length.pop();
       // lasat.x=first_x;
       //lasat.y=first_y;
        this.array_length.unshift({
            x: first_x,
            y: first_y
        });


    },
    update_direction: function (e) {

        var key = e.keyCode;

        if (key == "37" && direction != "right") direction = "left";
        else if (key == "38" && direction != "down")direction = "up";
        else if (key == "39" && direction != "left") direction = "right";
        else if (key == "40" && direction != "up")direction = "down";
       //alert(direction);
    }
};

for (var i = snake.length; i >= 0; i--) {
    snake.array_length.push({
        x: i * width,
        y: 0
    });
}
window.onkeydown=snake.update_direction;
function swag(){
window.requestAnimationFrame(swag);
    snake.draw();
}
swag()

The behavior is in switch statement, when I increment the this first_x or first_y by 1, they became too small due to rect overcovering themselves, but when I increment them by 10, the snake is going too fast, I would like the snake to be at full length (like as incrementing by 10) but much slower.行为在switch语句中,当我将 this first_xfirst_y增加 1 时,由于 rect 覆盖自身,它们变得太小,但是当我将它们增加 10 时,蛇走得太快,我希望蛇是全长(如增加 10)但慢得多。

How can I fix it?我该如何解决? Here is a demo (default direction is right = incremented by 1. Others are incremented by 10, check the difference in length and speed)这里是一个demo(默认方向是右=加1,其他都是加10,看长度和速度的差异)

Your scale (10x10) and your coordinates don't agree.您的比例 (10x10) 和坐标不一致。 Your positions end up looking like (1,1), (1,2), etc, but when you draw a 10x10 square in that location you get massive overlap.您的位置最终看起来像 (1,1)、(1,2) 等,但是当您在该位置绘制一个 10x10 的正方形时,您会得到大量重叠。

Use context save, restore, and scale to fix this - or you can change your coordinate system.使用上下文保存、恢复和缩放来解决这个问题 - 或者您可以更改坐标系。

Here's an example:下面是一个例子:

At the top, when you define your variables:在顶部,当您定义变量时:

 var width = 1;
 var height = 1;

In your draw function:在您的绘图功能中:

ctx.clearRect(0,0,W,H);
ctx.save();
ctx.scale(10,10);
this.array_length.forEach(function (x) {
    ctx.beginPath();
    ctx.fillStyle = "blue";
    ctx.fillRect(x.x, x.y, width, height);
});
ctx.restore();
this.update();

I got the fiddle you provided working using that.我得到了你提供的使用它的小提琴。 Cheers!干杯!

EDIT:编辑:

After a bit of mucking around with it, I got it mostly working by having each element in the chain have it's own direction, and then moving the switch for movement into a foreach.经过一番折腾之后,我主要是通过让链中的每个元素都有自己的方向,然后将移动开关移动到 foreach 来实现它。 Sadly, I refreshed the page on accident and lost the fiddle, but it wasn't much of a modification.可悲的是,我不小心刷新了页面并丢失了小提琴,但这并没有太大的修改。

Basically, the reason why they're overlapping is because each cell isn't moving - you're "leapfrogging" the tail to keep it moving forward - so smooth movement means moving less than a full grid cell's worth, which causes overlap.基本上,它们重叠的原因是因为每个单元格都没有移动——你在“跳跃”尾部以保持它向前移动——所以平滑的移动意味着移动小于一个完整的网格单元格的价值,这会导致重叠。

Removing that overlap means moving by a full grid cell each tick, which means moving extremely quickly.消除重叠意味着每个刻度移动一个完整的网格单元格,这意味着移动速度非常快。 So, you need to move by less than a full grid cell each tick, for each element in the array因此,对于数组中的每个元素,您需要在每个刻度移动不到一个完整的网格单元格

ALSO:还:

DO NOT use setTimeout() like the comment above suggested.不要像上面建议的评论那样使用 setTimeout() 。 Use requestAnimationFrame, and if you want to use a staggered update setup, only call your update if your time between updates exceeds some time delta.使用 requestAnimationFrame,如果您想使用交错更新设置,则仅当更新之间的时间超过某个时间增量时才调用您的更新。

Use the parameter being passed to swag:使用传递给 swag 的参数:

var lasttime=0;
function swag(time){
    window.requestAnimationFrame(swag);
    if (time - lasttime > 200) {
        snake.draw();
        lasttime = time;
    }
}
window.requestAnimationFrame(swag);

I will say, I like vyross solution better.我会说,我更喜欢 vyross 解决方案。 It will look better, but this is a more direct answer to your question.它看起来会更好,但这是对您问题的更直接的回答。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM