Home > Back-end >  How to properly remove items from PixiJS app
How to properly remove items from PixiJS app

Time:07-28

I am building a game with Pixi.js that features items that fall from the top of the canvas. So far I have been able to spawn the items and have them move down the canvas until they reach the end of the window and are then removed from the app and from the items array.

This seems to work correctly at first, however, after one item has reached the end of the canvas and is removed the newer items that were added later, seem to stop in place on the canvas.

How can I have a smooth continuous flow of items falling?

class Item {
    constructor(color, radius, v) {
      ...
    }

    update() {
        this.item.x = this.v.x;
        this.item.y  = this.v.y;

        if (this.item.y >= (h)   this.radius) {
            this.item.y = 0
            this.remove() 
        }
    }

    remove() {
        items.pop()
        app.stage.removeChild(this.item);
    }
}


function addItem() {
    items.push(new Item(0x79a3b1, Math.random() * 10   10, {x: getRandomNumberBetween(0, w), y: 2 * getRandomNumberBetween(0.5, 1.5)  }));
}


function gameLoop() {
    items.forEach(c => {
        c.update();
    });
}


let spawnInterval = setInterval( () => {
    addItem()
}, 2000);


setInterval(gameLoop, 1000/60);

My code demo can be found here: https://codepen.io/m1-interactive/pen/GRxMYVE

CodePudding user response:

There are mainly two issues with your code.

One is related to how you remove the objects in your remove method. You use items.pop(), but that will always remove the last element of the array. By the time that one object reaches the bottom of the screen, there are newer elements in the array so you have to remove them by index:

    remove() {
        items.splice(items.indexOf(this), 1)
        app.stage.removeChild(this.item);
    }

Secondly, as you iterate through each item in your gameLoop, some objects might get removed from the array. That can result in skipping some elements. Read more about why this happens in this answer.

In your case, it can be easily fixed by cloning the array before splicing it:

    items.slice().forEach(c => {
        c.update();
    });
  • Related