Java Swing Games perform poorly when many sprites are on the screen
I'm making a simple tower defense game in swing. When I try to place many elves (more than 20) on the screen, I encounter a performance problem
The whole game takes place on a JPanel with setignorerepair (true) This is the paintcomponent method (con is the controller):
public void paintComponent(Graphics g){
super.paintComponent(g);
//Draw grid
g.drawImage(background,null);
if (con != null){
//Draw towers
for (Tower t : con.getTowerList()){
t.paintTower(g);
}
//Draw targets
if (con.getTargets().size() != 0){
for (Target t : con.getTargets()){
t.paintTarget(g);
}
//Draw shots
for (Shot s : con.getShots()){
s.paintShot(g);
}
}
}
}
The target class simple draws bufferedimage at its current position The getimage method does not create a new bufferedimage, but only returns an instance of the controller class:
public void paintTarget(Graphics g){
g.drawImage(con.getImage("target"),getPosition().x - 20,getPosition().y - 20,null);
}
Each target runs a swing timer to calculate its position This is the actionlistener it calls:
public void actionPerformed(ActionEvent e) {
if (!waypointReached()){
x += dx;
y += dy;
con.repaintArea((int)x - 25,(int)y - 25,50,50);
}
else{
moving = false;
mover.stop();
}
}
private boolean waypointReached(){
return Math.abs(x - currentWaypoint.x) <= speed && Math.abs(y - currentWaypoint.y) <= speed;
}
In addition, repaint() is called only when a new tower is placed
How to improve performance?
Solution
This may be your problem – let each target / bullet (I assume?) Being responsible for tracking when to update yourself and drawing yourself sounds like a lot of work A more common method is to cycle along the line
while (gameIsRunning) {
int timeElapsed = timeSinceLastUpdate();
for (GameEntity e : entities) {
e.update(timeElapsed);
}
render(); // or simply repaint in your case,I guess
Thread.sleep(???); // You don't want to do this on the main Swing (EDT) thread though
}
Essentially, an object in the chain is responsible for tracking all entities in the game and telling them to update and render them
