JavaScript:一个数组中的子弹和敌人(拼接,重新索引)

JavaScript: Bullets and enemy in one array (splice, re-indexed)

我在制作简单的射击游戏时遇到了问题(有时):

GIF Game problem

3 颗子弹被移除(但只有一颗子弹相撞)。子弹和敌人(蓝色方块)在一个数组中(var objects = [])。有时它只摧毁(拼接)子弹而不是敌人。

当我执行 .splice() 时,正在重新索引数组,我知道我可以使用:

但我想使用 splice() 并且我希望所有对象(子弹、敌人)都在一个数组中,这可能吗?有任何想法吗?我不需要代码(但如果有人有时间请更新我的 jsfiddle ...)。我尝试在 .splice() 之后递减 (i--) 变量 "i"(在循环中)——但这并没有解决问题。

示例:https://jsfiddle.net/uy9okuzv/1/(space == 射击,按键 == 控制)

html

<canvas id="game" width="500" height="400" style="border: 1px red solid;">

javascript

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

var objects = [];
var keys = [];
var shotTime = 30;
var ship = {
    x: 20,
    y: 200,
    w: 50,
    h: 50,
}

setInterval(function(){ 
    // controls 
    if(keys[37]){
        ship.x-=4;
    }   
    if(keys[38]){
        ship.y-=4;
    }       
    if(keys[39]){
        ship.x+=4;
    }   
    if(keys[40]){
        ship.y+=4;
    }

    if(keys[32] && shotTime<=0){
        push(ship.x+ship.w, ship.y, "bullet", "red", "left");
        shotTime = 30;
    }else{
        shotTime--;
    }

    // update
    for(var e=0; e<objects.length; e++){
        var obj = objects[e];

        if(obj.type=="bullet"){
            for (var i = 0; i<objects.length; i++) {
                var enemy = objects[i];
                if(enemy.type=="enemy"){
                    if(collisionObj(obj, enemy)){
                        objects.splice(e,1);

                        objects.splice(i,1);

                    }
                }
            }
        }

        if(obj.dir=="left"){
            obj.x+=5;
        }       

        if(obj.dir=="right"){
            obj.x--;
        }
    }

    // render
    ctx.clearRect(0,0,game.width, game.height);

    for(var e=0; e<objects.length; e++){
        var obj = objects[e];

        ctx.fillStyle=obj.color;
        ctx.fillRect(obj.x, obj.y, obj.w, obj.h);
    }

    ctx.fillStyle="green";
    ctx.fillRect(ship.x, ship.y, ship.w, ship.h);
},1000/60);

// add enemy
setInterval(function(){
    push(game.width, mt_rand(10,game.height-50), "enemy", "blue", "right");
},1000);

// functions
function collisionObj(obj1, obj2, marginX, marginY){
    if(marginX==null){
        marginX = 0;
    }
    if(marginY==null){
        marginY = 0;
    }
    if(obj1.x < obj2.x + obj2.w-marginX
        && obj1.x + obj1.w-marginX > obj2.x &&
        obj1.y < obj2.y + obj2.h-marginY &&
        obj1.h-marginY + obj1.y > obj2.y){
            return true;
    }
    return false;
}

function mt_rand(minimum, maximum) {
    minimum = parseInt(minimum, 10);
    maximum = parseInt(maximum, 10);

    return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
}

function push(x,y, what,color, dir){
    objects.push({
        x: x,
        y: y,
        h: 50,
        w: 50,
        type: what,
        color: color,
        dir: dir,
    });
}

// listeners
window.addEventListener('keydown', function(e){

    keys[e.keyCode] = true;
}, false);

window.addEventListener('keyup', function(e){
    delete keys[e.keyCode];
}, false);

我认为问题是这样的:

if(collisionObj(obj, enemy)){
  objects.splice(e,1);
  objects.splice(i,1);
}

发生碰撞时,您会移除子弹(索引 e)和敌人(索引 i)。每当敌人指数大于子弹时,移除子弹后,敌人指数将不再正确。

您必须先删除最后一个:

if(collisionObj(obj, enemy)){
  if( e > i ){
    objects.splice(e,1);
    objects.splice(i,1);
  }
  else{
    objects.splice(i,1);
    objects.splice(e,1);
  }
}