I want to see if I can make any improvements to the rendering methods that are currently written. I've noticed when profiling this project that the CPU was allocating a fair percentage of the time towards rendering and was wondering if there were any improvements that I can make towards it.
Note: Below is my somewhat simple rendering method. I am rendering an ArrayList of tiles, few of these are transparent. This function (y*map.getMapWidth())+x
) will return the index in the ArrayList to be rendered.
ImageManager
is a class that stores cropped images from a spritesheet as a BufferedImage
.
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
public class Game extends Canvas implements Runnable{
private void renderTiles(Graphics g) {
// the overlay variable determines if I need to render anything off screen
// (True if player is moving)
int overlay = 0;
if (moving) {
overlay = 1;
}
// the four variables below determine the starting/finishing x/y variables
// to begin rendering
int startX = -((xOffset/(Tile.TILESIZE*SCALE))+overlay);
int finishX = -(((xOffset-(WIDTH*SCALE))/(Tile.TILESIZE*SCALE))-overlay);
int startY = -((yOffset/(Tile.TILESIZE*SCALE))+overlay);
int finishY = -(((yOffset-(HEIGHT*SCALE))/(Tile.TILESIZE*SCALE))-overlay);
// to avoid crashes, the variables can't render what isn't there in the list
if (startX < 0) {
startX = 0;
} if (finishX > map.getMapWidth()) {
finishX = map.getMapWidth();
} if (startY < 0) {
startY = 0;
} if (finishY > map.getMapHeight()) {
finishY = map.getMapHeight();
}
// where the tiles are render. tiles are stored in an ArrayList so that
// switching between maps is easier
for (int y = startY; y < finishY; y++) {
for (int x = startX; x < finishX; x++) {
map.tile.get((y*map.getMapWidth())+x).render(g);
}
}
}
public void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
createBufferStrategy(2);
return;
}
Graphics g = bs.getDrawGraphics();
// start rendering
g.fillRect(0, 0, WIDTH * SCALE, HEIGHT * SCALE);
renderTiles(g);
player.render(g);
g.dispose();
bs.show();
}
}
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public abstract class Tile {
public static final int TILESIZE = 16;
protected BufferedImage bi;
protected ImageManager im;
protected int x, y, oX, oY;
protected Game game;
public Tile(int x, int y, ImageManager im, Game game, BufferedImage bi){
this.oX = x;
this.oY = y;
this.im = im;
this.game = game;
this.bi = bi;
}
public abstract void tick();
public abstract void render(Graphics g);
}
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class WalkableTerrainTile extends Tile{
public WalkableTerrainTile(int x, int y, ImageManager im, Game game, BufferedImage bi) {
super(x, y, im, game, bi);
}
public void tick() {
this.game = game;
x = oX + game.xOffset;
y = oY + game.yOffset;
}
public void render(Graphics g) {
g.drawImage(bi, x, y, Tile.TILESIZE * Game.SCALE, Tile.TILESIZE * Game.SCALE, null);
}
}
1 Answer 1
I'm not sure if these would be optimized out by the compiler but
Tile.TILESIZE * SCALE
Tile.TILESIZE * Game.SCALE
are done more than once, why not just keep them as variables and...
for (int y = startY; y < finishY; y++) {
for (int x = startX; x < finishX; x++) {
map.tile.get((y*map.getMapWidth())+x).render(g);
...why do a multiplication for every y
? you could just have a variable and increment it
int yLoc = startY * map.getWidth();
for (int y = startY; y < finishY; y++) {
for (int x = startX; x < finishX; x++) {
map.tile.get(yLoc+x).render(g);
}
yLoc += map.getMapWidth();
}
then you only need to do one multiplication and one addition for each y
step instead of a multiplication for every y
-
\$\begingroup\$ Shouldn't the declaration of
yloc
be inside the first loop? \$\endgroup\$Bobby– Bobby2014年01月16日 09:51:38 +00:00Commented Jan 16, 2014 at 9:51 -
\$\begingroup\$ I think you mean the increment of
yLoc
. If the declaration was inside, then it would always be equal to the map width. I've fixed it \$\endgroup\$Ross Drew– Ross Drew2014年01月16日 09:54:30 +00:00Commented Jan 16, 2014 at 9:54 -
1\$\begingroup\$ Ahh that is some good advice there. Thank you. I want to try and flesh out as much performance as I can. \$\endgroup\$Hayden– Hayden2014年01月16日 10:17:22 +00:00Commented Jan 16, 2014 at 10:17