A simple slick2D game running at ~5 FPS. Why?

Hi, I just started trying to code up a simple game to use a training project. The first milestone is a small field on which a player-controlled sheep will move around. I have been following thenewboston’s tutorials and I’m using slick2D.

The idea behind the code is to represent the game world as a 2D array of Tiles in which all the internal logic will happen and from which all the information on what to display will be drawn. For now, I’m using a simple placeholder world generation algorithm and two test terrain types to see of the whole thing is working.

The game executes fine, but I noticed that for some reason or the other, a simple 20x20 grid of 16x16 sprites is playing merry hell on the FPS, dragging it down from ~2000(the performance on an empty window) to ~5. I’m sure it’s the tiles graphics doing it because a 10x10 map will leave it at whopping ~20 and a 3x3 one at about ~200.

I’m sure I did some bummer there and I’m calculating something unnecessary over and over because I don’t actually understand how all the stuff in the libraries works. I don’t want to proceed any further until this is resolved, lest I build a game on faulty foundations and will have to redo it because it will run at 0.34 FPS on a good computer.

So, where is this extremely low FPS coming from? I’d be grateful for any answer.

Here’s the code of the Play state:

package FFGame;

import java.util.Hashtable;
import java.util.Random;
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;

public class Play extends BasicGameState {
	
	Tile[][] world;
	int x, y;
	Random random;
	String[] terrain;
	Image steppe;
	Image grassland;
	
	public Play(int state) {		
	}
	
	public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {	
		
		//Images
		terrain = new String[32];
		terrain[0] = "res/terrain/steppe.png";
		terrain[1] = "res/terrain/grassland.png";
		
		
		//TODO World generation. Provisional, revise this.
		
		Random random = new Random();
		x = 3;
		y = 3;
		world = new Tile[x][y];
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y; j++) {
				world[i][j] = new Tile(random.nextInt(2));				
			}		
		}
		
	}
	
	public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {		
		
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y; j++) {
				Image toDraw = new Image(terrain[world[i][j].getTerrain()]);
				g.drawImage(toDraw, 16*i, 16*j);
			}
			
		}
		
		g.drawString("Play state", 150, 50);
		
	}
	
	public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {		
	}
	
	public int getID() {
		return 1;
	}
}

And the Tile class, as of yet a mere shadow of things to come:

package FFGame;

public class Tile {
	
	int terrain;
	int entities;	
	
	Tile(int terrain) {
		this.terrain = terrain;
	}
	
	int getTerrain() {
		return this.terrain;
	}
}

Image for better reference:
[spoiler]—
http://imageshack.com/a/img903/3177/W81J4l.png
[/spoiler]

public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {      
      
      for (int i = 0; i < x; i++) {
         for (int j = 0; j < y; j++) {
@@            Image toDraw = new Image(terrain[world[i][j].getTerrain()]);
            g.drawImage(toDraw, 16*i, 16*j);
         }
         
      }
      
      g.drawString("Play state", 150, 50);
      
   }

You seem to be reading an image file for each tile each frame.
terrain[] should be an array of images, not an array of paths to images.

Seems to have worked, it’s about 420 now. Thanks!