【问题标题】:Canvas apparently running multiple threads画布显然运行多个线程
【发布时间】:2015-08-13 23:04:20
【问题描述】:

我有这段代码,其目的是运行经典的诺基亚蛇。代码本身按预期工作,但我的问题是当您再次调用主函数(重新启动游戏)时,画布将产生 2 条蛇,在第三个循环中,4,在第四个,8 等等。仅使用 jQuery 和 JS,here's a working fiddle。玩输一次,重新加载,查看副本。

这是加载游戏的代码:

 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();
            });

问题在于,当第二次调用snakeLoad 时,初始位置所在的代码部分会运行多次,每次重新运行都会运行更多次。那里没有任何类型的循环,知道为什么它会以指数方式增加更多的循环吗?

感谢您的帮助,这几天让我发疯了。

【问题讨论】:

    标签: javascript jquery canvas


    【解决方案1】:

    每次调用 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();
    }
    

    【讨论】:

      【解决方案2】:

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

      最后我刚刚添加了: $(document).off('click', '#startSnake'); $(document).off('click', '#playSnakeAgain');

      每次绑定后,它现在按预期工作。希望这可以帮助其他有类似问题的人。

      【讨论】:

        猜你喜欢
        • 2013-08-13
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多