JS游戏中的画布渲染光学错觉(简要重复的图形) - 修复?

时间:2016-03-31 12:46:44

标签: javascript canvas

我正在用javascript创建一个横向滚动的太空射击游戏。到目前为止,一切似乎都运作良好。但是,画布渲染中有一个奇怪的错误,我无法弄清楚(并且难以描述,所以忍受我!)

我有一个可以通过点击鼠标左键射击弹丸的玩家。当抛射物首先离开玩家时,似乎有两个弹射器短暂停留,直到它们最终合并到一个弹丸中。我不会创造两个,所以这看起来像一个视错觉(如果你快速连续发射一些射弹,这是最明显的。)

真奇怪的是,当我尝试捕捉这种情况的截图时,一切看起来都很好。谁能弄明白发生了什么?

玩家代码包括射弹(小提琴中的完整代码);

var Player = (function () {
    // ------------------------------------------------------------------------------------------------
    // PLAYER VARIABLES
    // ------------------------------------------------------------------------------------------------
    var w = 50;
    var h = 50;
    var x = 0;
    var y = 0;
    var projectiles = [];

    // ------------------------------------------------------------------------------------------------
    // BIND EVENTS TO THE GLOBAL CANVAS
    // ------------------------------------------------------------------------------------------------
    Canvas.bindEvent('mousemove', function (e) {
        y = (e.pageY - Canvas.element.getBoundingClientRect().top) - (h / 2);
    });

    Canvas.bindEvent('click', function () {
        createProjectile(50, (y + (h / 2)) - 10);
    });

    // ------------------------------------------------------------------------------------------------
    // FUNCTIONS
    // ------------------------------------------------------------------------------------------------
    var createProjectile = function (x, y) {
        projectiles.push({
            x: x,
            y: y
        })
    };

    var update = function () {
        for (var p = projectiles.length - 1; p >= 0; p--) {
            projectiles[p].x += 10;

            if (projectiles[p].x > Canvas.element.width)projectiles.splice(p, 1);
        }
    };

    var render = function () {
        Canvas.context.fillStyle = 'white';
        Canvas.context.fillRect(x, y, w, h);

        for (var p = 0; p < projectiles.length; p++) {
            Canvas.context.fillStyle = 'red';
            Canvas.context.fillRect(projectiles[p].x, projectiles[p].y, 5, 5);
        }
    };

    // ------------------------------------------------------------------------------------------------
    // Exposed Variables and Functions
    // ------------------------------------------------------------------------------------------------
    return {
        update: update,
        render: render
    }
})();

Js Fiddle Demo HERE:https://jsfiddle.net/oqz204bj/

修改

基于@Pimskie的答案,它确实看起来像一个视错觉 - 所以我的问题现在成为,我怎么能减少这种影响?我计划在未来实施一项功能,允许玩家切换武器(其中一些实际上*会发射多个射弹)但是我不希望这种效果留下来以免混淆。

2 个答案:

答案 0 :(得分:2)

我最好猜测它确实是一种视错觉。 检查这个更新的小提琴:https://jsfiddle.net/oqz204bj/1/

我删除了一个requestAnimationFrame并用非常慢的setInterval替换了另一个,仅用于演示。您只能看到创建一个项目符号。

答案 1 :(得分:2)

是的,这是一种视错觉。第一次射击时看起来像是多个正方形的原因是因为你的眼睛专注于大的静态船形正方形。一旦你的眼睛开始跟随运动路径,那么它看起来更像是流动的方形移动,而不是每秒重绘60或30次的方形。把一张纸或一只手拿到屏幕上,覆盖它的左半部分。专注于那张纸,开了几枪。你会注意到镜头似乎看起来很多,就像刚开枪一样。这是你的想法,看到3个不同的帧是同一个帧。

requestAnimationFrame取决于浏览器和计算机的帧速率。在大多数情况下,这是60fps。 60到70fps是大多数显示器的限制,因此尝试超越它是没有意义的。然而,你可以通过对你的射弹产生拖尾示踪效果来创造更流畅运动的幻觉。这将涉及在每个射弹后面创建2或3个额外的正方形,这些正方形的不透明度越来越低。