Canvas显然运行多个线程

Canvas apparently running multiple threads

本文关键字:线程 运行 Canvas      更新时间:2023-09-26

我已经得到了这段代码,其目的是运行经典的Nokia snake。代码本身按预期工作,但我的问题是,当你再次调用main函数(重新启动游戏)时,画布将产生2条蛇,在第三个循环中,4条,第四个,8条等等。只使用jQuery和JS,这里是一个工作小提琴。播放丢失一次,重新加载,查看副本。

下面是加载游戏的代码:
 function snakeLoad() {
            loadSnake();
            $(document).on('click', '#startSnake', function () {
                $(this).remove();
                startSnake();
            });
            function loadSnake() {
                //start button
                $('main').append('<div id="snake"><button id="startSnake">Click to start</button><canvas id="snakeCanvas" height="380" width="380">Get a modern browser</canvas><div>');
            }
            ;

这是初始化的函数:

function startSnake() {
                //create grid
                var snakeCanvas = document.getElementById("snakeCanvas");
                var ctx = snakeCanvas.getContext("2d");
                //Global game vars init
                var randomSeed = function (min, max) {
                    return Math.floor(Math.random() * (max - min + 1)) + min;
                };
                var snakeLength = 1;
                var snakePositions = [{x: randomSeed(14, 25) * 10, y: randomSeed(14, 25) * 10}];
                var foodPosition = {x: randomSeed(25, 35) * 10, y: randomSeed(25, 35) * 10};
                var snakeDirection = ['N', 'S', 'E', 'W'][randomSeed(0, 3)];
                var i = 0;
                console.log(snakePositions, foodPosition, snakeDirection);
//Draw initial position
//Snake
                ctx.fillStyle = "green";
                ctx.fillRect(snakePositions[0].x, snakePositions[0].y, 10, 10);
//Food
                ctx.fillStyle = "red";
                ctx.fillRect(foodPosition.x, foodPosition.y, 10, 10);

然后是带有失败条件的主要游戏内循环:

var moveSnake = setInterval(function () {
 //... doing its thing
//On losing:
 clearInterval(moveSnake);
return endSnake();

这是游戏结束脚本和重启按钮的动作:

function endSnake() {
$('#snake').remove();
$('main').html('<br/><input class="endGamer" id="playSnakeAgain" type="button" value="Play&#x00A;Snake&#x00A;Again" data-app="snake">');
            }
 $(document).on('click', '#playSnakeAgain', function (e) {
 $('main').empty();
 snakeLoad();
            });

问题是,当第二次调用snakload时,初始位置所在的代码部分会运行多次,每次运行更多。这里没有任何形式的循环,你知道为什么它会成倍地增加循环吗?

谢谢你的帮助,这几天我都快疯了。

每次调用snakeLoad时,您都在向文档添加一个额外的click处理程序:

$(document).on('click',....

所以当你点击loadSnake中添加的#startSnake按钮时,有多个事件处理程序正在运行,每个调用startSnake()。相反,只需在snakeLoad:

之外注册该事件处理程序一次。
$(document).on('click', '#startSnake', function () {
    $(this).remove();
    startSnake();
});
function loadSnake() {
    //start button
    $('main').append('<div id="snake"><button id="startSnake">Click to start</button><canvas id="snakeCanvas" height="380" width="380">Get a modern browser</canvas><div>');
}
function snakeLoad() {
    loadSnake();
}

@James Thorpe -非常感谢你为我指出了正确的方向。

最后我只是补充了一句:美元(文档)。('点击',' # startSnake ');美元(文档)。('点击',' # playSnakeAgain ');

在每次绑定之后,它现在按预期工作了。