2010-06-02 6 views
3

I가 어레이의 각 요소가 "단계"남아 있지 않은 것을 난 (종종 합리적으로) 확인해야 일하고 작은 JS 게임의 부분 배열 또는 "놀이터", 그래서 나는 그들을 제거하고 사람이를 계산하는 빠른/더 효율적인 방법을 알고 있다면 내가 아래 코딩하고 궁금 스크립트로드보다 효율적인 비교

을 절약 할 수 있습니다. 이것은 매 50ms마다 실행됩니다 (움직임을 다룹니다).

여기서 bots[i][1]은 X에서의 움직임이고 bots[i][2]은 Y에서의 움직임 (상호 배타적)입니다.

for (var i in bots) { 
    var left = parseInt($("#" + i).css("left")); 
    var top = parseInt($("#" + i).css("top")); 
    var nextleft = left + bots[i][1]; 
    var nexttop = top + bots[i][2]; 
    if(bots[i][1]>0&&nextleft>=PLAYGROUND_WIDTH) { remove_bot(i); } 
    else if(bots[i][1]<0&&nextleft<=-GRID_SIZE) { remove_bot(i); } 
    else if(bots[i][2]>0&&nexttop>=PLAYGROUND_HEIGHT) { remove_bot(i); } 
    else if(bots[i][2]<0&&nexttop<=-GRID_SIZE) { remove_bot(i); } 
    else { 
     //alert(nextleft + ":" + nexttop); 
     $("#" + i).css("left", ""+(nextleft)+"px"); 
     $("#" + i).css("top", ""+(nexttop)+"px"); 
    } 
} 

비슷한 노트에서 remove_bot (i); 기능은 다음과 같습니다이 (가 배열의 모든 요소는 ID의 변경으로 내가 스플 라이스 수 없습니다. 주어진 어떤 조언을

function remove_bot(i) { 
    $("#" + i).remove(); 
    bots[i] = false; 
} 

많은 감사를!

답변

8
  1. 캐시를 정확 $("#" + i) 변수에, 때마다이 작업을 수행, 새로운 jQuery를 개체가 생성되는

    var self = $('#' + i); 
    var left = parseInt(self.css("left")); 
    var top = parseInt(self.css("top")); 
    
  2. 캐시 bots[i]을 변수에 :

    .
    var current = bots[i]; 
    var nextleft = left + current[1]; 
    var nexttop = top + current[2]; 
    
  3. DOM 요소의 jQuery 객체를 보트 표현에 저장 (캐시)하십시오. 현재 50ms마다 생성됩니다.

    은 내가 이것에 의해 말은 루프의 모든 반복에 대해, 당신은 $('#' + i)을하고있는 것입니다. 이것을 호출 할 때마다 jQuery는 DOM 요소의 jQuery 객체를 작성한다. 이것은 까지에서 JS의 다른 측면에 비해 사소한 것입니다. DOM traversal/manipulation은 JavaScript에서 가장 느린 영역입니다.

    $('#' + i)의 결과가 결코 각 로봇에 대한 변경 없기 때문에

    , 왜 봇 내 결과를 저장하지? 이렇게하면 $('#' + i)은 매 50ms가 아니라 한 번 실행됩니다. 아래에있는 내 예에서

    , 내 봇 개체의 element 속성에서이 참조를 저장 한,하지만 당신은 그것을 당신의 봇을 추가 할 수 있습니다 (예 : bots[i][3])에

  4. 저장소 (캐시)에 DOM의 위치 엘리먼트는 봇 표시 내에서 봇을 나타 내기 때문에 항상 CSS 위치를 계산할 필요가 없습니다.

참고로, for (.. in ..)은 배열이 아닌 객체를 반복하는 데 엄격하게 사용되어야합니다. 배열은 다음을 사용하여 반복되어야합니다. for (..;..;..)

변수는 입니다. JavaScript는 매우입니다. 그들을 학대하십시오.

function Bot (x, y, movementX, movementY, playground) { 
    this.x = x; 
    this.y = y; 
    this.element = $('<div class="bot"/>').appendTo(playground); 
    this.movementX = movementX; 
    this.movementY = movementY; 
}; 

Bot.prototype.update = function() { 
    this.x += this.movementX, 
    this.y += this.movementY; 

    if (this.movementX > 0 && this.x >= PLAYGROUP_WIDTH || 
     this.movementX < 0 && this.x <= -GRID_SIZE || 
     this.movementY > 0 && this.y >= PLAYGROUND_HEIGHT || 
     this.movementY < 0 && this.y <= -GRIDSIZE) { 
     this.remove(); 
    } else { 
     this.element.css({ 
      left: this.x, 
      right: this.y 
     }); 
    }; 
}; 

Bot.prototype.remove = function() { 
    this.element.remove(); 
    // other stuff? 
}; 

var playground = $('#playground'); 
var bots = [new Bot(0, 0, 1, 1, playground), new Bot(0, 0, 5, -5, playground), new Bot(10, 10, 10, -10, playground)]; 

setInterval(function() { 
    var i = bots.length; 

    while (i--) { 
     bots[i].update(); 
    }; 
}, 50); 
+0

정말 유용한 조언, 곧 업데이트 된 코드를 게시 할 것입니다. 그러나 나는 당신이 # 3에 의해 의미하는 것이 당신이 더 조언 할 수 있다는 것을 정말로 이해하지 못합니까? 많은 감사, –

+0

@PezCuckow : # 3에 대한 설명을 확장했습니다. – Matt

1

당신은 parseInt을 사용하고 있습니다 :

여기에 내가 만든 한 제안을 포함하고 내가 선택한 것 구현,입니다.내가 아는 한, 비트 OR 0은 parseInt보다 빠릅니다. 따라서 대신

var left = $("#" + i).css("left") | 0; 

을 쓸 수 있습니다. 사람들을 사용할 때 항상 조금 더 오버 헤드 거기로

또한, 나는이 50ms마다 같은 값을 얻기 위해 jQuery를 기능을 사용하지 것이라고합니다 ($ 기능 등의 인수를 구문 분석 할 수있다). 네이티브 JavaScript 함수를 사용하여 이러한 라인을 최적화하십시오. 또한 코드를 사용하면 id가 i 인 요소를 여러 번 가져와야합니다.

var item = document.getElementById(i); 
var iStyle = item.style; 
var left = iStyle.left; 
… 

이 (내가 jQuery를 전문가가 아니에요 있습니다, 그래서 나는이 같은 않는 100 % 확실하지 않다.) 또한

, while 루프는 감소시키는 : 변수에 이러한 요소를 저장 for 루프 (reference)보다 빠릅니다. 역순으로 요소를 통해 반복에 문제가 없다면, 당신은 자바 스크립트에서 다른 루핑 기술의 모습 here for a great comparison을 가지고

var i = bots.length; 
while (i--) { 
    … 
} 
+0

다시 사용하면서 배열의 요소의 실제 ID를 사용해야합니다. 삭제/제거 할 때 일부만 제거 할 수 있습니다. 증가 또는 감소하는 값을 갖는 루프. 그렇지 않으면 환상적인 조언! –

0

에 코드를 다시 작성할 수 있습니다.

for ... in을 (를) 사용하면 성능이 떨어지며 배열에서는 사용하지 않는 것이 좋습니다. 역순으로 반복하면서 for 루프를 사용하는 대신 길이를 캐시하여 각 반복마다 찾아 보지 않아도됩니다. 이런 식으로 뭔가 :

for(var i, len = bots.length; i < len; i++) { ... } 

그러나 위의 링크에 표시하고 당신이 당신의 경우에 가장 적합한 볼 수있는 실제 응용 프로그램과 함께 몇 가지를 테스트 할 수있는 많은 다른 방법이있다.

0

문서 또는 부모와 관련된 좌표가 필요한지 여부에 따라 offset() 또는 position()을 사용하십시오. position()은 브라우저가 부모를 기준으로 오프셋을 찾는 데 효율적이므로 가장 빠를 가능성이 큽니다. CSS를 파싱 할 필요가 없습니다. 또한 변수를 한 번만 사용하기 때문에 lefttop 변수가 필요하지 않습니다. 그것은 읽을 수 있을지 모르지만 효율을 위해가는 것입니다 :

var left = $("#" + i).position().left + bots[i][1]; 
var top = $("#" + i).position().top + bots[i][2];