画布闪烁

问题描述 投票:0回答:2

我是高中二年级学生,正在上一门计算机科学课,该课使用(我相信)相当老式的方法来处理事物。我知道我的代码不会很棒

当按住任何箭头键时,地图会发出声音并闪烁。 我必须重新绘制地图,因为需要清除画布,否则当我移动他时,每个角色都会有大量的内容。 显然我只想画一张。

如何才能让按住方向键时地图不闪烁?

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

javascript canvas
2个回答
1
投票

学校老旧,一片混乱。

代码一团糟(我不相信那是老师做的),所以在你提交之前,甚至在你编写代码时,只需在源代码上应用代码格式化程序或美化器。它看起来会更好,并且更容易阅读和发现问题。

很多代码都是老派的,所以老师应该获取更新的代码。

仅加载图像一次

闪烁的原因是每次渲染地图时都会重新创建并重新加载图像。您对

link
sword
图像(顺便说一句,它们是同一图像)执行相同的操作。

修复

添加到脚本顶部,就在标签 add 之后

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';

然后进行以下更改

您的原始格式功能

drawLink
drawSword
(加上我的评论)。不知道画布尺寸的变化是什么,也许是老式的清除方法?

你有..

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

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

对于其余的代码,如果不从头开始完全重写,就很难修复。

代码审查。

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


0
投票

您可以做很多事情来增强此代码。我的第一个想法是摆脱双数组并使用 x y 坐标创建树木和岩石的对象...您仍然需要在每个渲染上重绘,但允许您摆脱嵌套循环并且只拥有一个树木/岩石阵列。不是整个地图。

还要考虑制作游戏循环。 您正在按键上重新渲染,如果您不打算按住按钮(例如纸牌游戏),那么这很好。

© www.soinside.com 2019 - 2024. All rights reserved.