Jump to content

Producing multiple sprites with gravity (best approach)


MichaelD
 Share

Recommended Posts

So I have tried to develop several games where multiple objects are produced and they move from pointA to pointB and then disappear (deleted) and are no longer required.

 

I have tried many approaches tweening, physics with gravity when they need to fall from a point to a point, also I had the objects on recycle so only the alive ones were rendering. But still the performance took a serious hit even with no more than 50 objects (yes all animating or falling at the same time) and settled around 30-40fps (which is horrible for a simple game)

 

So I was wondering what is the most perfomant approach here for something like this. In terms of animation(tweening) vs physics and about recycle approach.

 

Assume that the objects are actually sprites and may play different frames (even while they animate or fall). Also assume that each object is as big as 5%-10% of the total space of the stage.

 

I really appreciate the help on this.

Link to comment
Share on other sites

I'm using simple arcade physics. I have tried profiling but all I can get out of it is that there is a bottleneck when each item is created/recycled and thrown into the game stage and then if more are added and they all animate at the same time the performance drops significantly, if I test this on a mobile device its even worse...

Link to comment
Share on other sites

The images are dynamically generated and they are 217x217 each but scalled down to ~0.5 of their size.

 

 

Here's the code for the main logic

function initDropGroup() {    reg.collectionGroup = game.add.group();    var dropGroup;    for (var i = 0; i < 20; i++) {        dropGroup = game.add.sprite(0, 0);        game.physics.enable(dropGroup, Phaser.Physics.ARCADE);        dropGroup.alive = false;        dropGroup.visible = false;        dropGroup.body.collideWorldBounds = false;        dropGroup.body.immovable = true;        dropGroup.body.allowGravity = true;        dropGroup.body.acceleration.setTo(0, 0);        dropGroup.body.velocity.setTo(0, 0);        dropGroup.checkWorldBounds = true;        dropGroup.outOfBoundsKill = true;        dropGroup.events.onKilled.add(onKilledDG);        reg.collectionGroup.add(dropGroup);    }    window.console.log("collectionGroup created!");}function dropFaces() {    var dropGroup = reg.collectionGroup.getFirstDead();    dropGroup.reset(0, 0);    if (dropGroup.children.length > 0) {        dropGroup.removeChildren();    }    var item;    var colorArr = [];    for (var i = 0; i < 5; i++) {        item = getFace((65.4 * i) + (10 * i));        dropGroup.addChild(item);        colorArr.push(item.colorCode);    }    dropGroup.alive = true;    dropGroup.visible = true;    dropGroup.anchor.setTo(0.5, 0.5);    dropGroup.x = (game.width / 2) - (367 / 2);    dropGroup.body.velocity.y = reg.dropSpeed;    reg.faceGroupColors.push({        'parent': dropGroup,        "colorArr": colorArr    });    if ((reg.currentCheckingIndex === '' && reg.faceGroupColors.length > 0) ||        (reg.currentCheckingIndex < 0) && reg.faceGroupColors.length > 0) {        reg.currentCheckingIndex = (reg.faceGroupColors.length - 1);    }}function getFace(x) {    var colorFill = reg.colors[game.rnd.integerInRange(0, reg.colors.length - 1)];    var colorFillInner = reg.colors[Utils.getRandomInt(0, reg.colors.length - 1)];    var item = reg.facesPool.getFirstDead();    var mainGroup = item.getChildAt(0);    var innerSprite = item.getChildAt(1);    //var posX = Utils.getRandomInt(0, (game.width - (innerSprite.width*item.scale.x)));    item.reset(x, 0);    item.alive = true;    item.visible = true;    item.opacity = 1;    item.scale.setTo(0.3,0.3);    item.anchor.setTo(0.5, 0.5);    //item.outOfBoundsKill = true;    //item.events.onKilled.add(onKilledFace);    //reg.testItem = item;    /*var speed = Utils.getRandomInt(reg.minDropSpeed, reg.dropSpeed);    if(speed > reg.dropSpeed) {        speed = reg.dropSpeed;    }*/    //window.console.log(">>>>>>>>>>>> ", item, posX, game.width, item.width);    //item.body.velocity.y = speed; //Utils.getRandomInt(80, 200);    if (colorFill === mainGroup.fillColor) {        colorFill = reg.colors[game.rnd.integerInRange(0, reg.colors.length - 1)];    }    if (colorFill === mainGroup.fillColor) {        colorFill = reg.colors[game.rnd.integerInRange(0, reg.colors.length - 1)];    }    if (colorFill === mainGroup.fillColor) {        colorFill = reg.colors[game.rnd.integerInRange(0, reg.colors.length - 1)];    }    if (colorFillInner === colorFill) {        colorFillInner = reg.colors[Utils.getRandomInt(0, reg.colors.length - 1)];    }    if (colorFillInner === colorFill) {        colorFillInner = reg.colors[Utils.getRandomInt(0, reg.colors.length - 1)];    }    if (colorFillInner === colorFill) {        colorFillInner = reg.colors[Utils.getRandomInt(0, reg.colors.length - 1)];    }    window.console.log("item width, ", item.width, innerSprite.width);    // color for checking    item.colorCode = colorFillInner;    mainGroup.clear();    mainGroup.beginFill(colorFillInner, 1);    mainGroup.drawRect(-1 * (innerSprite.width / 2) + 15, -1 * (innerSprite.height / 2) + 13, 188, 189);    mainGroup.endFill();    mainGroup.fillColor = colorFillInner;    item.getChildAt(1).tint = colorFill;    return item;}// this repeats the creation intervalfunction initTimer() {    reg.timer = {};    reg.interval = 0;    var _time = 4000;    reg.timer = game.time.events.loop(_time, function () {        reg.interval += 1;        // update or create something based on timer        initDrops();    }, this, []);    return reg.timer;} 
Link to comment
Share on other sites

I've never used it and am only going by the docs, but checkWorldBounds and outOfBoundsKill are supposed to be "relatively expensive operation". Fifty doesn't sound like a lot, though.

 

dropGroup is a sprite; did you mean to make it a group? Again, not sure what the perf implications are there, just checking. Looks like it has its own body and velocity. Is that intentional?

 

It's hard to see what's going on out of context here, unfortunately. Like what calls initTimer, how often? Where's initDrops? When you say "50 objects" are those children of dropGroup? How often does dropFaces get called? Maybe you should try reproducing it with a minimal example on codepen or something?

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...