Jump to content

Mobile performance problems related to collision testing in a 20+ member group


jschomay
 Share

Recommended Posts

I have a game where the screen fills up with falling blocks in a grid.  The blocks are rendered by canvas  drawing operations and use arcade physics to test for collisions between the blocks-group and itself, and the the ground.

 

The game runs fine at 60fps on desktop, and it also runs fine on mobile -- until I get about 20 blocks on screen.  Then the framerate drops progressively, down to about 30fps when the screen is filled with blocks.

 

I have done some profiling and debugging and believe the problem is with the physics quadtree operations.  In the profiler, before many blocks stack up, the rendering functions take most of the time.  After a few blocks get stacked up, the heavy operations are all quadtree related.

 

See the attached screenshots (profile1 and profile2 respectively).

 

I have tested rendering simple sprite images instead of canvas drawings, with no difference.

 

I have tried to disable physics on blocks once they land, but only partially succeeded (this.body.enable = false).  I tried switching landed blocks to a different group, but had other problems with that and gave up.  Should that even be necessary?

 

All my code is at https://github.com/jschomay/color-blocks-blitz/commit/0487b02496989e007c032303b9a7d952e069acbf.

 

You can test the game yourself at http://jeffschomay.com/color-blindness-blitz/.

 

Any suggestions on what I am doing wrong, or if I need to be more clever at something?

 

Thank you so much for your help - I'm new to Phaser, but I really like it, and want it to work for me, but it's got to work on mobile.  Everyone tells me to just use Unity, but I want to give this a try.

 

 

post-9646-0-67120200-1407074654.png

post-9646-0-39060400-1407075492.png

post-9646-0-40851400-1407075493.png

Link to comment
Share on other sites

Hi Zoombox, thanks for the reply.  I was considering removing the physics as you suggest, but I think I still need to do collision detections to tell when blocks hit other blocks or the ground.  How do I do that?

 

Is that simply a case of calling overlap manually on each update?  Wouldn't that introduce the same slow down? Or do I need to change my approach (like using some kind of grid based data structure to determine where blocks are?  I'm not sure how I would do that exactely...).

 

Also, in a more general sense, is phaser able to handle groups of 20+ on mobile, or is that a framework limitation?  I thought it could, but if not, for other games, I may need to consider a different framework/platform.

 

Thanks again for your help :)

Link to comment
Share on other sites

I personally wouldn't use physics for this either, it seems like a candidate for a simple grid based system.

 

However your objects are really tightly packed, so are going to throw the QuadTree into recursive hell. I would disable it entirely.

 

If you collide the group against itself, it should internally call World.collideGroupVsSelf, which doesn't use a QuadTree. So that should be fine.

 

However colliding a Sprite outside of the Group will internally call World.collideSpriteVsGroup - which does use a QuadTree. You can do it directly like this instead:

    for (var i = 0, len = group.children.length; i < len; i++)    {        if (group.children[i] && group.children[i].exists)        {            game.physics.arcade.collideSpriteVsSprite(sprite, group.children[i], collideCallback, processCallback, callbackContext, overlapOnly);        }    }

Fill-in the various callbacks as needed, or just remove them. 'group' is your blocks group. Sprite is your floor.

 

BTW good luck using Unity to make a mobile browser game :)

Link to comment
Share on other sites

Thanks for the reply Rich!

 

You gave me two good clues:

 

  • I wasn't doing groupVsSelf right - because I wanted a collision callback, I was doing `this.game.physics.arcade.collide(this.blockPool, this.blockPool, this.blockCollide);` -- I needed to replace the second blockPool with `undefined` to trigger groupVsSelf.
  • I moved the ground object into the same blockPool to avoid the sprite vs group tests, which doesn't affect the rest of the game as long as I test if on the collide objects is the ground.

With those changes in place, it is running better.  Rendering the canvas is the main heavy operation in the profiler now (though it fits in a frame fine for the most part), and quad tree operations don't show up at all.

 

I still need to do some more profiling, because the game still slows as the screen fills up, especially when a block stacks above the top of the screen.  Also, I didn't know about `minBounceVelocity`, so I have some messy hack in place, maybe that will speed things up too.

 

Thanks again for the help, I think the main problems are sorted now.  Properly going groupVsSelf was the biggie.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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