BdR

How to properly destroy custom objects?

Recommended Posts


I'm working on a game that uses a custom object based on Phaser.Group which represents tetris-like shapes. Each object consists of a number of sprites to make up the different shapes. It's a puzzle game and during a single game blocks will be added and removed (see also this thread)

 

So my question is:

How do I properly destroy a custom object that contains Phaser sprites? Currently I use delete to remove an object but this doesn't remove the sprites from the game so this will cause memory leaks, which I obviously want to prevent. See function removeBlock() in example code below:



var CANVAS_WIDTH = 800;
var CANVAS_HEIGHT = 600;
var SPRITE_SIZE = 60;

var game = new Phaser.Game(CANVAS_WIDTH, CANVAS_HEIGHT, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });

var aryholdobjs;

var blockshape = [ [2,7,0,0],
                   [0,10,3,0],
                   [0,0,0,0],
                   [0,0,0,0] ];

// -------------------------------------
// PHASER GAME FUNCTIONS
// -------------------------------------
function preload() {
    game.load.spritesheet('blocks60x60', '../img/blocks60x60.png', SPRITE_SIZE, SPRITE_SIZE);
}

function create() {
    //  array to hold all blocks
    aryholdobjs = [];
    
    // player input, Z to add and X to remove
    game.input.keyboard.addCallbacks(this, doGameKeyInput, null, null);
}

function doGameKeyInput(key) {
    var kc = key.keyCode;

    // Z to add more
    if (kc == 90) {
        addBlock();
    // cursor down
    } else if (kc == 88) {
        removeBlock();
    };
}

function addBlock() {
    // create new object
    var xpos = game.rnd.integerInRange(0, CANVAS_WIDTH - (3*SPRITE_SIZE));
    var ypos = game.rnd.integerInRange(0, CANVAS_HEIGHT - (3*SPRITE_SIZE));

    var newobj = new BlockObj(game, xpos, ypos, blockshape);

    // add to array
    aryholdobjs.push(newobj);
    console.log('addBlock - aryholdobjs.length=' + aryholdobjs.length);
}

function removeBlock() {
    // remove last item from array
    var index = aryholdobjs.length-1;
    delete aryholdobjs[index];
}

// -------------------------------------
// block object constructor
// -------------------------------------
var BlockObj = function(game, xpos, ypos, ary) {
    // inherits from Phaser.Group
    Phaser.Group.call(this, game);
    this.x = xpos;
    this.y = ypos;
    
    // random color
    var frame = this.game.rnd.integerInRange(0, 3);
    frame = frame * 16;
    
    // find minimum x/y position of block
    for (var y=0; y < ary.length; y++) {
        for (var x=0; x < ary[y].length; x++) {
            // if block part
            var part = ary[y][x];
            if ( part != 0 ) {
                // place block relative to group
                var xrel = x * SPRITE_SIZE;
                var yrel = y * SPRITE_SIZE;
                
                var sprblock = this.game.add.sprite(xrel, yrel, 'blocks60x60', frame+part-1); 
                this.add(sprblock);
            };
        };
    };
};

// game objects are a type of Phaser.Group
BlockObj.prototype = Object.create(Phaser.Group.prototype);
BlockObj.prototype.constructor = BlockObj;


Share this post


Link to post
Share on other sites

Okay I've added the .destroy(true) but it I think it still retains the children sprites, because my custom object inherits the constructor of Phaser.Group but not its destructor(?), although I'm not sure. I've added my test example to github, see here

https://github.com/BdR76/Phaser-memory-test

 

And I'm monitoring the memory usage with the standard Chrome debugger tools (press ctrl+shift+J and goto Profiles). In the timeline after destroying all blocks, you can see there are still some blue bars indicating created/retained memory. If I understand correctly it should be all grey after destroying objects. Also, if any one knows a better tool to find javascript memory leaks please let me know.

 

8vqn8p.png
 
2ljguvq.png

Share this post


Link to post
Share on other sites

Using this methiod below it's even more clear that sprites are indeed being retained.

http://javascript.info/tutorial/memory-leaks

  1. Take a heap snapshot (1st).
  2. Do some stuff to and create new objects
  3. Take another heap snapshot (2nd).
  4. Remove and destroy all objects
  5. Take another heap snapshot (3rd).
No select the 3rd heap snapshot and select "summary" and "Objects allocated between Snapshot 1 and Snapshot 2". If all objects were removed and destroyed correctly the list of Constructors should be empty. But in my case c.Sprite objects are retained.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.