I am working on a 2D platformer that is in the final stages of optimization. I have a few different devices for testing, and I am trying to get the best possible framerate on the weaker ones.
On a Nexus 5 I get a constant 60fps, with an occasional hiccup.
On a Galaxy S4 I also get a good 55-60fps
On an original Galaxy S (Vibrant) The frames drop to about 20-25
My question is, given the tile system described below, what can I do to increase the FPS on low-end devices? And granted the Galaxy S came out years ago, should I even worry about it?
My background consists of 3 scrolling parallax layers.
The world I am drawing in a viewport of 25x15 tiles, at a size of 32x32px per tile, with 3 layers each (32x32x3px). The camera already culls tiles that are out of view. All tiles are found in one texture, and this is done in a single SpriteBatch call that locates the correct texture location for the tile layer. Code is below:
public void Draw(SpriteBatch spriteBatch, bool upsideDown)
{
int startX = GetCellAtPixelX( (int)Camera.Position.X );
int startY = GetCellAtPixelY( (int)Camera.Position.Y );
int endX = GetCellAtPixelX( (int)Camera.Position.X +
Camera.ViewportWidth );
int endY = GetCellAtPixelY( (int)Camera.Position.Y +
Camera.ViewportHeight );
for (int x = startX; x <= endX; x++)
{
for (int y = startY; y <= endY; y++)
{
for (int z = 0; z < MapLayers; z++)
{
if ((x >= 0) && (y >= 0) &&
(x < MapWidth) && (y < MapHeight))
{
// ...
/// The very last parameter in this draw call is
/// the draw depth. This draw format will arrange
/// layers from front to back (0 = front, 1 = back)
/// so we subtract 1 from the z-index as a decimal
/// to get the appropriate location:
/// Background -> 0.7
/// Middleground -> 0.6
/// Foreground -> 0.5
spriteBatch.Draw(
tileSheet,
CellScreenRectangle(x, y),
TileSourceRectangle(mapCells[x,y].
GetLayerIndex((TileLayers)z)),
Color.White,
0.0f,
Vector2.Zero,
effect,
0.7f - ((float)z * 0.1f)
);
}
}
} /// End y loop
} /// End x loop
}
As you can see, it's not very complex code. I have checked if my Update calls are slowing the game down, but it's very clearly in the Draw function. When I leave out my call to world.Draw(), fps shoot up to about 50 on the Galaxy S. Also, if I draw only a single layer, I get better performance around 42-45 fps.
I can discard one layer if necessary, but I need at least 2 tile layers. How else can I speed up the draw calls?
I am using MonoGame for Android (XNA)