Браузер зависает всякий раз, когда создается более одного объекта пользовательского класса

#javascript #class #javascript-objects #setinterval

Вопрос:

Я возился с классами JavaScript (в данном случае я создал класс под названием dropCoin), и я пытаюсь сделать «монеты» и заставить их толкать друг друга. однако в тот момент, когда будет создана вторая монета, вкладка зависает. Я нигде не могу найти ответа на этот вопрос, поэтому я надеюсь, что у кого-то есть ответ на вопрос, почему setInterval так ломается?

Примечание: Проблема не связана непосредственно с большим блоком физических вычислений, у меня была эта проблема до того, как я ее добавил. Однако это также может вызывать некоторые проблемы? Еще одно примечание: это не связано с продолжительностью setInterval, я установил ее более чем на 5 секунд раньше, и браузер все еще висит.

 var mCoinArray = [];
var tiers = [{set:'1',val:5}]; //Unused ATM, will be important later
var dropTier = 0;
var CPMachine = $('#CPBox');
var dropTimer = 0;
var dropTime = 40; //This is in frames, game runs ~20FPS
//end variable init
class dropCoin {
    constructor(pos,x,y,tier) {
        this.pos = pos;
        this.x = x   80;
        this.y = y;
        this.physX = this.x   30;
        this.physY = this.y   30;
        this.xAccel = 0;
        this.yAccel = 0;
        this.tier = tier;
        this.visual = $("<div class='coin'></div>");
        this.visual.appendTo(CPMachine);
        this.visual.css('top',this.y);
        this.visual.css('left',this.x);
        setTier(this.pos,dropTier);
    }
    recalc(x,y,ax,ay) {
        this.x = x - 30;
        this.y = x - 30;
        this.physX = x;
        this.physY = y;
        this.xAccel = ax;
        this.yAccel = ay;
        this.visual.css('top',this.y);
        this.visual.css('left',this.x);
    }
    deleteMe() {
        mCoinArray[this.pos] = undefined;
    }
}
function generateCoin(x,y) {//430x, 240y maximum values
    let MApos = 0;
    let whiler = true;
    while(whiler) {
        let i = 0;
        if (mCoinArray[i] == undefined) {
            whiler = false;
            MApos = i;
        } else { i  ; }
    }
    mCoinArray[MApos] = new dropCoin(MApos,x,y,dropTier);
}
function setTier(mIndex, tier) { //{background: "url(CoinSheetT[#]L.png) n60 n60"} n = 0, 1, or 2
    let set = (Math.floor(tier / 9)).toString();
    tier = tier % 9;
    switch(tier) {
        case 0:
            $(mCoinArray[mIndex]).css({background: "url(CoinSheetT"   set   "L.png) 0 0"})
            break;
        case 1:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 60 0"})
            break;
        case 2:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 120 0"})
            break;
        case 3:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 0 60"})
            break;
        case 4:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 60 60"})
            break;
        case 5:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 120 60"})
            break;
        case 6:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 0 120"})
            break;
        case 7:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 60 120"})
            break;
        case 8:
            mCoinArray[mIndex].css({background: "url(CoinSheetT1L.png) 120 120"})
            break;
    }
}
var gameLoop = setInterval(function(){
    dropTimer  ;
    if (dropTimer >= dropTime) {
        dropTimer = 0;
        generateCoin(Math.floor(Math.random() * 431),Math.floor(Math.random() * 241));
    }
    for (i=0;i<mCoinArray.length;i  ) { // PHYSICS
        let targX = mCoinArray[i].physX;
        let targY = mCoinArray[i].physY;
        let targAcX = mCoinArray[i].xAccel;
        let targAcY = mCoinArray[i].yAccel;
        let checkX = [];
        let checkY = [];
        let dist;
        for (j=0;j<mCoinArray.length;j  ) {
            if (j != i) {
                if (j < i) {
                    checkX[j] = mCoinArray[j].physX;
                    checkY[j] = mCoinArray[j].physY;
                } else {
                    checkX[j-1] = mCoinArray[j].physX;
                    checkY[j-1] = mCoinArray[j].physY;
                }
            }
        }//physics equation; y = -4.27494(x)^0.36907   15
        let resAcX = (targAcX * 1)/5;
        let resAcY = ((targAcY * 1)/5) - 5;
        for (j=0;j<checkX.length;j  ) {
            let distance = Math.sqrt(Math.pow(checkX[j] - targX,2)   Math.pow(checkY[j] - targY,2));
            let angle = Math.atan2(checkY[j] - targY, checkX[j] - targX);
            let power = Math.pow(-4.27494 * distance, 0.36907)   15;
            if (power < 0) {
                power = 0;
            }
            resAcX  = Math.cos(angle) * power;
            resAcY  = Math.sin(angle) * power;
        }
        let resX = targX   resAcX;
        let resY = targY   resAcY;
        mCoinArray[i].recalc(resX, resY, resAcX, resAcY);
    } // End Physics
}, 50);
 

Комментарии:

1. Я не могу быть уверен, но, похоже, вы используете jQuery для установки CSS в своей setTier функции… за исключением того , что вы используете jQuery только в case 0 случаях с 1 по 8, вы пытаетесь получить доступ к функции css непосредственно в элементе массива. Держу пари, что этой функции там нет, и исключение останавливает выполнение. ИЗМЕНИТЬ: это станет проблемой после того, как вы устраните проблему, возникшую в ответе @Eric Phillips.

Ответ №1:

Вы повторно инициализируете i до нуля в своем цикле while, поэтому он не будет увеличиваться, как вы ожидаете, и вы попадете в бесконечный цикл.

Убедитесь, что инициализация происходит вне вашего цикла, чтобы вы не сбрасывали ее постоянно.

 // i should be initialized here so the incrementing works
// let i = 0;
while(whiler) {
    let i = 0; // infinite loop caused by reinitializing i to zero every iteration
    if (mCoinArray[i] == undefined) {
        whiler = false;
        MApos = i;
    } else { i  ; }
}
 

Комментарии:

1. Ах, этого было бы достаточно! Спасибо за помощь.