Jump to content

[1.1.6] Huge performance drop; too many sprites?


Recommended Posts

Hey everyone


I have run into severe performance drops in my test code (see below). I render some sprites as ground, one house as collision test and one player I move around with the mouse.


Performance is strongly corrleated with ground sprites. If I create() a map 16x16 (256 sprites; single texture ~5kb), I am usually at 30 fps with max drops at around 24 fps. Once I double the map to 32x32 (1024 sprites) performance breaks down to around 7 fps with max fps at 10 to 12.


Thanks to a forum post I got a relative huge boost by setting the body property for each ground sprite to "null". But it still creeps at around 15 fps.


Something which came to mind was that sprites are rendered even if they are invisble. But is that not what autoCull takes care of? Judging by all the examples I looked at I did not notice any extra code managing stuff not to render. Or am I wrong here?


An anomaly is that the code works on Firefox (v27) but does not load on Opera (some portable version) and latest IE (though thats not an anomaly I guess...). Maybe this points to an error somewhere?


I am not sure if I got the all those sprite, tile, tilemap, tileset, atlas vocabularies straight. Please excuse if I made a terribly obvious mistake somewhere :blink:


Thanks in advance.




function main(){	//var canvas = document.getElementById("game_canvas");	this.game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: this.preload, create: this.create, update: this.update});	this.tiles;	this.actor;	this.keys;	this.text;}	main.prototype.preload = function()	{		this.game.load.image('ground', 'img/ground32.png');		this.game.load.image('player', 'img/player3264.png');		this.game.load.image('house', 'img/house128.png');	}		main.prototype.create = function()	{					var tiles = this.game.add.group();				this.game.world.setBounds(0, 0, 1024, 1024);						var tileSize = 32;	 		x = 0;		y = 0;		for(var i=0; i<1024; i++)		{				if(i%32 == 0 && i != 0)			{				y++;				x=0;			}			var temp = tiles.create(tileSize*x, tileSize*y, 'ground');							temp.body = null;		//this helped a lot already but still only ~15fps  					x++;					}				var staticObject;			staticObject = this.game.add.sprite(50, 50, 'house');		staticObject.body.immovable = true;				var player = this.game.add.sprite(5, 5, 'player');			player.body.bounce.z = 0.2;		player.body.gravity.z = 6;		player.body.collideWorldBounds = true;			this.tiles = tiles;		this.actor = player;		this.staticObject = staticObject;				this.keys = this.game.input.keyboard.createCursorKeys();		this.text = this.game.add.text(40, 20, "test", {font: "24px Arial", fill: "#ff0044",  align: "center" });		this.text.anchor.setTo(0.5, 0.5);			}			main.prototype.update = function()	{		this.game.physics.collide(this.actor, this.staticObject);				this.actor.body.velocity.x = 0;		this.actor.body.velocity.y = 0;				if (this.game.input.mousePointer.isDown)		{			this.game.physics.moveToPointer(this.actor, 400);						if (Phaser.Rectangle.contains(this.actor.body, this.game.input.x, this.game.input.y))				this.actor.body.velocity.setTo(0, 0);		}							if (this.keys.up.isDown) 			this.game.camera.y -= 8;		else if (this.keys.down.isDown)			this.game.camera.y += 8;		if (this.keys.left.isDown)			this.game.camera.x -= 8;		else if (this.keys.right.isDown)			this.game.camera.x += 8;				this.text.setText('fps: '+this.game.time.fps)		}	
Link to comment
Share on other sites

Update: Oh dear, something is really wrong. I replaced my whole ground tile part with the tilemap example in "fill tiles" (the one with the racing car in the desert). This works like a charm while having a bigger map and more textues.


But why? Is the someGroup.create() method so expensive as opposed to

    map = game.add.tilemap('desert');    map.addTilesetImage('Desert', 'tiles');    layer = map.createLayer('Ground');    layer.resizeWorld();
Link to comment
Share on other sites

the rendering pipeline for sprites and tilemaps is completely different. tilemaps are much simpler than sprites and they should be more performant and consume less memory than rendering individual sprites for each tile

Link to comment
Share on other sites


the rendering pipeline for sprites and tilemaps is completely different. tilemaps are much simpler than sprites and they should be more performant and consume less memory than rendering individual sprites for each tile

Oh, I see. It is more about the data structures (is that the right term?) rather than the textures; right? If so, what would that mean more generally? What is the maximum "sprite budget" (round about!) I should set?

Link to comment
Share on other sites

that really depends on a lot of factors - there's no good answer for everyone and every game.


the most important factor is probably your target machines/devices. if you're trying to run on pre-4.0 android devices running the old android browser then you are going to be very constrained - dozens of sprites could be a problem, let alone hundreds. on the other hand, if you're only concerned about running on new desktop machines then you've got lots of room to play (I've got a particle test that runs many tens of thousands of particles/sprites before it starts to slow down too much on my laptop - it's just using Pixi, not Phaser, but Phaser 2 should be comparable). most ppl will fall somewhere in the middle. the only sure way to know is to try it and test it on as many devices as possible.


obviously there are other factors besides just raw numbers. how large they are and how much texture memory is consumed are going to be big factors. if you have lots of sprites that all use the same texture then that is going to perform much better than fewer very large sprites with separate, very large textures.


also, general memory consumption is going to be an issue on phones/mobile devices. I have a pretty simple game (side-scroller) game level that causes iPhone 4 to blow up consistently and I'm pretty sure it comes down to memory usage.


and then there's memory allocations and the garbage collector. the more objects that are needing to be collected during your game loop, the more often the garbage collector will have to run, pausing your game for a few ms and possibly causing its frame rate to "stutter" - which can look worse than just having a slower frame rate. it's best to keep javascript object allocation out of your game loop. note that this (mostly) applies to *objects* (meaning '{}' and '[]') - temporary, local variables are handled better by the JIT compilers in browsers these days, particularly if they are simple, atomic types like numbers. 


anyway, the long and short of it is to test, test, test. it won't take long before you find a "sweet spot" for your game.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

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