通过2个数组javascript画布游戏优化循环

时间:2015-05-02 09:34:58

标签: javascript arrays canvas

我正在制作我的第一个javascript画布游戏,我想知道是否有更好的方法来比较2个阵列中对象之间的碰撞。例如,我有一个带有火箭的数组和带有敌人的数组,代码正常工作,但我认为当数组长度变得更大时,它会对性能产生影响。示例100通过100个敌人的火箭每帧10000次迭代

for (i in rockets){ 
    rockets[i].x+=projectile_speed;
    for (j in enemies){
        if(collision(rockets[i], enemies[j])){ 
            enemies[j].health-=5;
            sound_hit[hit_counter-1].play();
            hit_counter--;
            if (hit_counter==0){
                hit_counter=5;
            }
            rockets.splice(i,1);
            if (enemies[j].health <= 0) {
                score += enemies[j].score;
                sound_explode[Math.floor(Math.random()*25)].play();
                enemies[j].isDead = true;
            }
        } else if(rockets[i].x >= width){
                rockets.splice(i,1);
        }    
    }
}

2 个答案:

答案 0 :(得分:0)

如果你想测试每个球员的每一枚火箭,那么在不了解球员和火箭的位置的情况下,不可能做到不同的事情。

如果你快速保持continue功能,这应该没问题。

我只能想到两个简单的改进:

  • 发现碰撞时使用forEach,因为不需要循环其余玩家(除非允许玩家发生碰撞)
  • 而不是多次拼接火箭阵列,建立一个新的,不包括所有“死”火箭。

您还应该考虑使用mapfilterrockets = rockets.filter(function(rocket) { rocket.x+=projectile_speed; if(rocket.x >= width) { return false; } var enemy = enemies.find(function(enemy) { return collision(rocket, enemy) }); if(enemy) { enemy.health-=5; sound_hit[--hit_counter].play(); if (hit_counter==0){ hit_counter=5; } if (enemy.health <= 0) { score += enemy.score; sound_explode[Math.floor(Math.random()*25)].play(); enemy.isDead = true; } return false; } return true; }); 来使代码更容易阅读:

{{1}}

答案 1 :(得分:0)

你可以尝试做的是通过对敌人和火箭进行分组来减少测试次数,这样你只需要测试同一组中的元素。

这是一个简单的实现,以显示我的意思,这只是在X方向分区,因为你的火箭似乎只是横向移动:

var groupWidth = 100; // do some experiments to find a suitable value
var rocketGroups = [];
var enemyGroups = [];

// initalize groups, not shown (array of array of rocket/enemy),
// but here are some other function examples...

function addToGroups(element, groups) {
  groups[element.x / groupWidth].push(element);
}

function move(element, groups, distance) {
  if (element.x / groupWidth != (element.x + distance) / groupWidth) {
    // remove element from the old group and put it in the new one
  }
  element.x += distance;
}

// Note: this is only to show the idea, see comments about length
function checkCollisions() {
  var i,j,k;
  for (i = 0; i < rocketGroups.length; i++) {
    for (j = 0; j < rocketGroups[i].length; j++) {
      for (k = 0; k < enemyGroups[i].length; k++) {
        // only compares elements in the same group
        checkPossibleCollision(rocketGroups[i], enemyGroups[i], j, k);
      }
    }
  }
}