HTML5画布绘制时闪烁问题

7

我正在做一个等轴投影游戏,当绘制地面的所有部分时,我的画布会闪烁(不包括IE)。当我将fps设置为20或更低时,闪烁停止了。有什么解决方法吗?有任何想法吗?

var camerax = 300, cameray = 100;
var fps = 60;

function draw() {
    clearCanvas();
    drawGround();
}

function drawGround() {
    var img = new Image();
    img.onload = function() {
    var width = img.width;
    var height = img.height;
    for (var x = 0; x < 3; x++) {
        for (var y = 3; y >= 0; y--) {
                mx = (x-y)*height + camerax;
                my = (x+y)*height/2 + cameray; 
                ctx.drawImage(img, mx, my);
             }
        }
    }
    img.src = "ground.png";
}

var loop = setInterval(function() {
    update();
    draw();
}, 1000/fps);
2个回答

11

目前您每个帧都在重新加载图像,除非onload回调在16ms的帧内触发,否则您将看到一个空白的画布。

您只需要调用new Imageimg.onload序列一次,即可预加载您的图像。然后onload回调会启动您的第一帧,绘制调用可以自由使用内存中的图像。

类似于:

var camerax = 300, cameray = 100;
var fps = 60;
var img;
var loop;

function init() {
    img = new Image();
    img.onload = function() {
        loop = setInterval(function() {
            update();
            draw();
        }, 1000/fps);
    };
    img.src = "ground.png";
}

function draw() {
    clearCanvas();
    drawGround();
}

function drawGround() {
    var width = img.width;
    var height = img.height;
    for (var x = 0; x < 3; x++) {
        for (var y = 3; y >= 0; y--) {
                mx = (x-y)*height + camerax;
                my = (x+y)*height/2 + cameray; 
                ctx.drawImage(img, mx, my);
             }
        }
    }
}
当然,如果你在等待多张图片加载时,情况会变得更加复杂,因为你需要在所有图片都加载完成后才开始循环。

1

很好的提示,freejosh!谢谢!现在我的屏幕不再闪烁,代码结果如下:

        var canvas = document.getElementById("game");
        var ctx = canvas.getContext("2d");

        var camerax = 300, cameray = 100;
        var fps = 60;
        var img;
        var loop;

        function update() {
        }

        function draw() {
            clearCanvas();
            drawGround();
        }

        function clearCanvas() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }

        function drawGround() {
            var width = img.width;
            var height = img.height;
            for (var x = 0; x < 3; x++) {
                for (var y = 3; y >= 0; y--) {
                    mx = (x-y)*height + camerax;
                    my = (x+y)*height/2 + cameray; 
                    ctx.drawImage(img, mx, my);
                }
            }
        }

        function init() {
            img = new Image();
            img.onload = function() {
                drawGround();
            };
            img.src = "ground.png";
        }

        function keyListener(e){
           e = e || window.event

           if(e.keyCode==37){
              camerax--;
           }
           else if(e.keyCode==39){
              camerax++;
           }
           else if(e.keyCode==38){
              cameray--;
           }
           else if(e.keyCode==40){
              cameray++;
           }                           
        }

        window.onkeypress = function(e) {
            keyListener(e);
        }

        init();
        var loop = setInterval(function() {
            update();
            draw();
        }, 1000/fps);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接