There are often times that you want to create images on the fly without having to design them beforehand. In the case of this example, we will procedurally make a piece of wreckage from a jet. This process is commonly called offscreen rendering.
In Java2D, you would do this by creating a Graphics object from an image. You can do the same in SlickĀ 2D but I’ve found that it creates an unusual drop in frame rate and the results are unusual. Whether this is a result of a bug or an oversight, we may never know. There is, however, a workaround that is efficient and convenient to use.
The trick is to use the default Graphics object available from the container. As long as you access this Graphics object outside of the render method your drawing will not appear on the screen and there will be very little consequence in terms of performance.
Using the following images of a jet and a wreckage cutout…
You will get this result with the following code:
Offscreen Rendering with Slick 2D
import com.ray3k.game.GameController;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
public class CopyAreaTest extends GameController {
public static void main(String[] args) {
startGameWindowed(new CopyAreaTest(), 250, 250);
}
Image baseImage;
Image outputImage;
Image cutoutImage;
@Override
public void init(GameContainer container) throws SlickException {
super.init(container);
container.setVSync(false);
container.setShowFPS(true);
baseImage = new Image("images/jet.png");
cutoutImage = new Image("images/cutout.png");
outputImage = new Image(cutoutImage.getWidth(), cutoutImage.getHeight());
}
@Override
public void update(GameContainer container, int delta) throws SlickException {
super.update(container, delta);
//get default Graphics and generate the image
Graphics g = container.getGraphics();
g.clear();
g.drawImage(cutoutImage, 0.0f, 0.0f);
g.setDrawMode(Graphics.MODE_COLOR_MULTIPLY);
g.drawImage(baseImage, 0.0f, 0.0f);
//save the result to the outputImage
g.copyArea(outputImage, 0, 0);
//reset the graphics
g.setDrawMode(Graphics.MODE_NORMAL);
g.clear();
}
@Override
public void render(GameContainer container, Graphics g) throws SlickException {
super.render(container, g);
g.drawImage(baseImage, 0.0f, 0.0f);
g.drawImage(outputImage, 0.0f, baseImage.getHeight());
}
}
To make this a truly procedural operation, you can change the position, size, and rotation of the cutout. You can even randomly select from multiple cutout images to achieve various effects.


awesome solution, thx!! saved me a lot of time
Excellent! Thanks for commenting.