画布闪烁

时间:2017-04-17 14:45:14

标签: javascript canvas

我是高中二年级学生,并且有一位钢琴教师教我们使用非常糟糕的代码。如果我不像他教的那样做,他会产生怀疑,这就是为什么它不是很好。对不起。

当按住任何箭头键时,地图会闪烁并闪烁。我必须重新绘制地图,因为需要清除画布,因为否则当我移动它时我将拥有大量的每个角色。我只是想画一个,显然。

按住方向键时,如何使地图不闪烁?

http://gitastudents.com/youngkevin/zelda/ZELDA.html

2 个答案:

答案 0 :(得分:1)

老派和一团糟。

嗯,代码是乱七八糟的(而且我不相信教师正在做的事情),所以在你把它交给之前,甚至在你写它的时候,只需应用代码格式化程序或beautifier源代码。它会看起来更好,更容易阅读和发现问题。

许多代码都是旧学校,所以教师应该获得更新的代码。

仅加载图像

您获得闪烁的原因是每次渲染地图时都会重新创建并重新加载图像。您对linksword图像(BTW图像相同)执行相同的操作。

修复

在标记添加

之后添加到脚本顶部
var canvas; // I put this here because of the mess is too much to clean
var grass = new Image();
var stone = new Image();
var sword = new Image();
var link = sword; // same image 
sword.src = 'http://gitastudents.com/youngkevin/zelda/img/sprites-link.png'
grass.src = 'http://gitastudents.com/youngkevin/zelda/img/grass.png';
stone.src = 'http://gitastudents.com/youngkevin/zelda/img/tree.png';

然后进行以下更改

您的原始格式函数drawLinkdrawSword(以及我的评论)。不知道什么是帆布大小的变化可能是老派明确的方法吗?

你有......

function drawLink(){
    var c = document.getElementById("myCanvas");  // Not needed
    var ctx = c.getContext("2d");                 // Not needed
    // ctx.fillStyle ="#FCD8A8";                  // remove dead code
    // ctx.fillRect(linkx - 20,linky-20, 30, 30); // remove dead code
    ctx.canvas.height = 575 ;                     // ?? only size canvas once
    ctx.canvas.width = 835  ;                     // remove



    link = new Image();                          // remove
    link.src = 'img/sprites-link.png'            // remove

    ctx.drawImage(link,srcX,srcY,srcW,srcH,linkx,linky,linkW,linkH);
    // drawSword();                              // remove dead code
    drawMap();                                   // why is this here???


}
        function drawSword(){
            var c = document.getElementById("myCanvas"); // Not needed
    var ctx = c.getContext("2d");                         // Not needed
    ctx.canvas.width = window.innerHeight +900;           // ???? remove
    ctx.canvas.height = window.innerHeight  ;              // remove

    sword = new Image();                                   // Not needed remove
    sword.src = 'img/sprites-link.png'                      // Not needed remove

    ctx.drawImage(sword,30,200,15,30,200,200,30,30);
        }

...更改为(使用jsbeautifier格式化)

function drawLink() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (link.complete) {
        ctx.drawImage(link, srcX, srcY, srcW, srcH, linkx, linky, linkW, linkH);
    }
    drawMap();  // ??
}

function drawSword() {
    if (sword.complete) { // make sure image has loaded
        ctx.drawImage(sword, 30, 200, 15, 30, 200, 200, 30, 30);
    }
}

然后将drawMap函数更改为

function drawMap() {
    var posX = 0;
    var posY = 0;
    if (stone.complete && grass.complete) {
        for (var i = 0; i < mapArray.length; i++) {
            for (var j = 0; j < mapArray[i].length; j++) {
                if (mapArray[i][j] == 1) {
                    ctx.drawImage(stone, posX, posY, 32, 32);
                } else if (mapArray[i][j] == 2) {
                    ctx.drawImage(grass, 0, 0, 17, 17, posX, posY, 32, 32);
                } else if (mapArray[i][j] == 3) {
                    ctx.drawImage(grass, 20, 0, 17, 17, posX, posY, 32, 32);
                }
                posX += 32;
            }
            posY += 32;
            posX = 0;
        }
    }
}

函数init现在看起来像

function init() {
    document.addEventListener('keydown', doKeyDown, true);
    document.addEventListener('keyup', keyUp, false);
    srcY = 30;
    canvas = document.getElementById("myCanvas");
    c = canvas; // you should change all the vars c to canvas
    canvas.height = 575;
    canvas.width = 835;
    ctx = canvas.getContext("2d");
    setMap7();
}

这将停止闪烁,因为图像现在已在开始时加载,并且在完成之前不会重新加载。

对于其余的代码,如果没有从头开始完全重写,修复太多了。

代码审查。

也许一旦你递交了作业并帮助轻轻推动教师朝着正确的方向前进,请将原始代码(来自老师)提交给Code review,告诉他们这是什么。他们将审核该代码,然后您可以分别向教师展示,然后教师可能需要一些时间来了解Javascript。

答案 1 :(得分:0)

您可以做很多事情来增强此代码。我的第一个想法是摆脱双数组并用xy coords创建树和岩石的对象......你仍然需要在每个渲染上重绘,但是你可以让你摆脱那个嵌套的循环而只有一个一排排的树木/岩石。不是整个地图。

还要研究制作游戏循环。你正在重新按下按键,如果你不打算按下按钮,比如卡片游戏就可以了。