Search code examples
javabufferedimagesprite-sheet

Issue loading a sprite sheet


I'm trying to load this spritesheet into an array of buffered image (each sprite into one BufferedImage) :

enter image description here

I opened this file on photoshop. The width is 500 and the height is 666. So according to my calculation, I need to loop 64 times (8 rows and 8 columns) and for each sprite, its width is 500/8 (62.5) and its height is 666/8(83.25). Since getSubImage accepts only int parameters, I was forced to put the width as 62 and the height a 83 (and I think this is why it truncates my images).

Here's the code to load the sprites (I put them in a JFrame to show you the results).

public class Test{  
    public static void main(String [] args){
        BufferedImage[] sprites = null;
        
        int width = 62;
        int height = 83;    

        try {
            BufferedImage buff = ImageIO.read(Test.class.getResourceAsStream("cyclop.gif"));
            sprites = new BufferedImage[64];
            int rows = 8;
            int cols = 8;
            for (int i = 0; i < rows; i++){
                for (int j = 0; j < cols; j++){
                    sprites[(i * cols) + j] = buff.getSubimage(i * width, j * height, width, height);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(new FlowLayout());
        for(BufferedImage bf : sprites)
            frame.getContentPane().add(new JLabel(new ImageIcon(bf)));
        frame.pack();
        frame.setVisible(true);
    }
}

Which outputs :

enter image description here

I'm a bit lost (first time I do this) on how I can load every sprite in a BufferedImage. Any ideas?


Solution

  • Basically the logic in you for-loop is wrong...

    You are multipling the width by the current row (i) and the height by the current col (j)

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            sprites[(i * cols) + j] = buff.getSubimage(i * width, j * height, width, height);
        }
    }
    

    It should be more like...

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            sprites[(i * cols) + j] = buff.getSubimage(j * width, i * height, width, height);
        }
    }
    

    Sprites

    (I increased the height to row 95 for the example)

    Now, obviously, you have an issue, as the sprites are different sizes, yea for you. I would suggest creating a simple look up file which contains the row/column as the key and the width/height of the cell, possibly even the x/y, so you can simply pick the sprite straight out, but that's up to you...