Search code examples
javascriptphaser-frameworktetris

Phaser Tetris Clone, line won't disappear when full


I'm making a game that is part Tetris clone, but I'm having trouble making lines disappear once their full of blocks. The game currently has 11 rows that can be filled, each represented by an array of sprites that is made in the create method.

this.row1 = [null, null, null, null, null, null, null, null, null, null];
this.row2 = [null, null, null, null, null, null, null, null, null, null];
this.row3 = [null, null, null, null, null, null, null, null, null, null];
this.row4 = [null, null, null, null, null, null, null, null, null, null];
this.row5 = [null, null, null, null, null, null, null, null, null, null];
this.row6 = [null, null, null, null, null, null, null, null, null, null];
this.row7 = [null, null, null, null, null, null, null, null, null, null];
this.row8 = [null, null, null, null, null, null, null, null, null, null];
this.row9 = [null, null, null, null, null, null, null, null, null, null];
this.row10 = [null, null, null, null, null, null, null, null, null, null];
this.row11 = [null, null, null, null, null, null, null, null, null, null];

I'm only trying to get the bottom row, row1, working before working on the others. I have the array filled when blocks land with this code in the update method:

if (this.activeBlock.y == 672){
    if(this.activeBlock.x == 352){
        this.row1[0] = this.activeBlock;
    }
    else if(this.activeBlock.x == 416){
        this.row1[1] = this.activeBlock;
    }
    else if(this.activeBlock.x == 480){
        this.row1[2] = this.activeBlock;
    }
    else if(this.activeBlock.x == 544){
        this.row1[3] = this.activeBlock;
    }
    else if(this.activeBlock.x == 608){
        this.row1[4] = this.activeBlock;
    }
    else if(this.activeBlock.x == 672){
        this.row1[5] = this.activeBlock;
    }
    else if(this.activeBlock.x == 736){
        this.row1[6] = this.activeBlock;
    }
    else if(this.activeBlock.x == 800){
        this.row1[7] = this.activeBlock;
    }
    else if(this.activeBlock.x == 864){
        this.row1[8] = this.activeBlock;
    }
    else if(this.activeBlock.x == 928){
        this.row1[9] = this.activeBlock;
    }

When the bottom row is full, this code is triggered to clear it and mover everything above down:

 if (this.isFull(this.row1)){
    this.clearRow(this.row1);
    this.moveDown(this.row1, this.row2);
    this.moveDown(this.row2, this.row3);
    this.moveDown(this.row3, this.row4);
    this.moveDown(this.row4, this.row5);
    this.moveDown(this.row5, this.row6);
    this.moveDown(this.row6, this.row7);
    this.moveDown(this.row7, this.row8);
    this.moveDown(this.row8, this.row9);
    this.moveDown(this.row9, this.row10);
    this.moveDown(this.row10, this.row11);
}

And these are the custom methods I'm using to perform that last part:

isFull(row){
this.result = true;
this.i = 0;
while(this.i < row.length){
    if (row[this.i] == null){
        this.result = false;
    }
    this.i = this.i + 1;
}
return this.result;
}

clearRow(row){
    this.i = 0;
    while(this.i < row.length){
        row[this.i].destroy();
        row[this.i] = null;
    }
}

moveDown(bottRow, topRow){
    this.i = 0;
    while(this.i < bottRow.length()){
        topRow[this.i] = topRow[this.i].y + 64;
        bottRow[this.i] = topRow[this.i];
        topRow[this.i] = null;
        this.i = this.i + 1;
    }
}

For the most part, the code seems to be working, but the game freezes when the bottom row is full, and when checking the inspect screen for errors, it pointed to the destroy() in the clearRow(row) method. The error message reads: Cannot read properties of null (reading 'destroy')

I'm not sure what's wrong. Can anyone tell?

If it helps, I'm using Phaser 3 in VSCode employing arcade physics.


Solution

  • You never increment i in your loop, so after you set row[0] to null, you then try to access it again next time through the loop. Make clearRow more like your isFull function. So it's:

    clearRow(row){
        this.i = 0;
        while(this.i < row.length){
            row[this.i].destroy();
            row[this.i] = null;
            this.i = this.i + 1; // Add this line
        }
    }