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);
}
}