简体   繁体   English

Javascript:敌人不在一条直线上

[英]Javascript: enemies are not in a straight line

I am trying to make my first game on javascript, and i ran into this problem... the enemies are not staying a line, after sometime they are starting to separate. 我试图用javascript做我的第一场比赛,但我遇到了这个问题...敌人在某个时候开始分离之后并没有坚持下去。 is there any solution? 有什么解决办法吗? where did I go wrong? 我哪里做错了? thanks! 谢谢!

window.onload = function game() {

    var canvas = document.createElement('canvas'),
    ctx = canvas.getContext("2d");
    document.body.appendChild(canvas);

    canvas.width = 700;
    canvas.height = 500;

    var enemieLeft =
        [{ "id": "enemie1", "x": 660, "y": 75, "w": 40, "h": 40 },
        { "id": "enemie3", "x": 660, "y": 225, "w": 40, "h": 40 },
        { "id": "enemie5", "x": 660, "y": 375, "w": 40, "h": 40 }];

    var enemieRight =
        [{ "id": "enemie2", "x": 10, "y": 150, "w": 40, "h": 40 },
        { "id": "enemie4", "x": 10, "y": 300, "w": 40, "h": 40 },
        { "id": "enemie6", "x": 10, "y": 450, "w": 40, "h": 40 }];

    var velXR = 6;
    var velXL = 6;

    function eRenderR() {
        for (var i = 0; i < enemieRight.length; i++) {
            var EnR = enemieRight[i];
            ctx.fillStyle = "black";
            ctx.fillRect(EnR.x, EnR.y, EnR.w, EnR.h);
            EnR.x += velXR;
            if (EnR.x >= 660) {
                velXR -= 6;
            }
            else if (EnR.x <= 9) {
                velXR += 6;
            }
        }
    }

    function eRenderL() {
        for (var i = 0; i < enemieLeft.length; i++) {
            var EnL = enemieLeft[i];
            ctx.fillStyle = "black";
            ctx.fillRect(EnL.x, EnL.y, EnL.w, EnL.h);
            EnL.x -= velXL;
            if (EnL.x <= 10) {
                velXL -= 6;
            }
            else if (EnL.x >= 661) {
                velXL += 6;
            }
        }
    }

    function run() {
        ctx.save();
        ctx.clearRect(0, 0, 700, 500);
        eRenderL();
        eRenderR();
        ctx.restore();
    }
    var runGame = setInterval(run, 10);

}

The Velocity, is like the position, not a shared property. 速度就像位置,而不是共享属性。 When your first enemieRight hits the right wall, it toggles velXR, but every following enemieRight has not hit the wall yet. 当您的第一个enemieRight碰到右墙时,它会切换velXR, 但是随后的每个enemieRight都还没有碰墙。 but since they shate the velocity-property, they all turn around, and make a step back, although the didn't hit the wall themself. 但是由于它们使速度属性不满意,因此它们都转过身,向后退了一步,尽管它们本身并没有撞墙。

var canvas = document.createElement('canvas');
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

canvas.width = 700;
canvas.height = 500;

var enemies = [
    {"id": "enemie1", "x":660, "y":75,"w":40,"h":40, vx: -6},
    {"id": "enemie3", "x":660, "y":225,"w":40,"h":40, vx: -6},
    {"id": "enemie5", "x":660,"y":375,"w":40,"h":40, vx: -6},
    {"id": "enemie2","x":10,"y":150,"w":40,"h":40, vx: 6},
    {"id": "enemie4","x":10,"y":300,"w":40,"h":40, vx: 6},
    {"id": "enemie6","x":10,"y":450,"w":40,"h":40, vx: 6}
];

function runEnemy(enemy){
    hitTest(enemy);
    move(enemy);
    render(enemy);
}

function move(enemy){
    enemy.x += enemy.vx;
}

function hitTest(enemy){
    if(enemy.x > 660 || enemy.x < 9)
        enemy.vx = -enemy.vx;
}

function render(enemy){
    ctx.fillStyle = "black";
    ctx.fillRect(enemy.x, enemy.y, enemy.w, enemy.h);
}

function run(){ 
    ctx.save();
    ctx.clearRect(0, 0, 700, 500);
    enemies.forEach(runEnemy);
    ctx.restore();
}

var runGame = setInterval(run,10);

I'm assuming that it might have something to do with a possible race conditioning. 我假设它可能与可能的比赛条件有关。 Your code doesn't anticipate a scenario in which run is being executed again before the last execution was complete. 您的代码不会预见在最后一次执行完成之前会再次执行run的情况。

This can be solved by either replacing setInterval with setTimeout in this manner: 可以通过以以下方式用setTimeout替换setInterval来解决此问题:

function run(){
    ctx.save();
    ctx.clearRect(0, 0, 700, 500);
    eRenderL();
    eRenderR();
    ctx.restore();
    runGame = setTimeout(run,10);
}
var runGame = setTimeout(run,10);

Or, the better approach IMO, use requestAnimationFrame which makes sure to run only once per frame, only when the previous frame has finished rendering. 或者,使用IMO更好的方法,请使用requestAnimationFrame ,该方法确保每帧仅在上一帧完成渲染后才运行一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM