Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Good day everyone,

I am developing a game and I am using a spritesheet for my image loading, however it seems I have run into a problem somewhere while developing this.

Now I am using a canvas on a JFrame, so if that makes a difference in what I have to do let me know please.

In all of the reading that I have done I came to the conclusion that I need to use a BufferedImage, which I am.

Below is my two classes that have to do with loading images from the sprite sheet.

ImageLoader.java
Java
public class ImageLoader {

	public BufferedImage load(String path) {
		
		try {
			return ImageIO.read(getClass().getResource(path));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
		
	}
	
}


SpriteSheet.java
Java
public class SpriteSheet {

	private BufferedImage sheet;
	
	public SpriteSheet(BufferedImage sheet) {
		
		this.sheet = sheet;
		
	}
	
	public BufferedImage crop(int col, int row, int w, int h) {
		
		return sheet.getSubimage(col * 16, row * 16, w, h);
		
	}
	
}


In my player class I have a render method, which can be seen below.

Player.java (Render Method)
Java
public void render(Graphics g) {
		
		g.drawImage(ss.crop(0, 0, 16, 16), x, y, 16 * OperationXMain.scale, 16 * OperationXMain.scale, null);
		
	}


In my main class, I am calling player.render, and passing g (Graphics). This happens after I render a rectangle that is the full size of the JFrame and Canvas.

Before my gameloop I am calling my init method, which is creating a new instance of the ImageLoader class that I created, then I am setting a BufferedImage variable to the value of ImageLoader.load, in which I am passing the location of my image.
Please note that I have referenced a res folder to my java project, so I know that works.
To make it easier for you to understand, I have included the code for my init method.

Java
public void init() {
		
	ImageLoader imageloader = new ImageLoader();
		
	spriteSheet = imageloader.load("res/spritesheet.png");
		
	SpriteSheet ss = new SpriteSheet(spriteSheet);
		
	player = new Player(0, 0, ss);
		
}


Sorry for the long question, just wanted to make sure I clarified everything well enough so someone can help me out.

Thanks!
Posted

1 solution

You don't want to use BufferedImage.getSubImage for every frame, what you want to do with your sprite sheet is to render a portion of is rather than creating a new Image object.

Something like this can help:

Java
public class SpriteSheet {

    private final BufferedImage image;

    public SpriteSheet(final String filename) throws IOException {
        image = ImageIO.read(new File(filename));
    }

    public void render(final Graphics graphics, final Rectangle source, final Rectangle destination) {

        graphics.drawImage(
                image,
                destination.x,
                destination.y,
                destination.x + destination.width,
                destination.y + destination.height,
                source.x,
                source.y,
                source.x + source.width,
                source.y + source.height,
                null);
    }
}


Java
public class Player {

    private final SpriteSheet sheet;
    private final Rectangle source = new Rectangle(0, 0, 16, 16);
    private final Rectangle destination = new Rectangle(0, 0, 16, 16);

    public Player(final SpriteSheet sheet) {
        this.sheet = sheet;
    }

    public void render(Graphics g) {
        destination.x = x;
        destination.y = y;
        destination.width = 16 * OperationXMain.scale;
        destination.height = 16 * OperationXMain.scale;

        sheet.render(graphics, source, destination);
    }
}


Hope this helps,
Fredrik
 
Share this answer
 
Comments
Gigabyte Giant 26-Sep-13 11:46am    
Hello Fredrik,
Thank you for the answer, this did help. +5

Thank you again!
Fredrik Bornander 26-Sep-13 13:29pm    
No worries, glad I could help.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900