Lucas Romier
Lucas Romier

Reputation: 1367

Problems rendering a sprite out of a BufferedImage

I have a problem, after adapting code from a game creation tutorial, and I don't get the error. It tells me I've got an OutOfBoundsException at pixels[x + y * SIZE] = sheet.pixels[(x + this.x1) + (y + this.y1) * sheet.SIZE]; but I don't understand why. Here's my code, thanks for every help. The rendering of the screen is done in the main method, this can't be the error because using the tutorial code worked fine.

public class Sprite {

public static final Sprite GRASS = new Sprite(1, 1, 15, 15, SpriteSheet.ENVIRONMENT_SHEET);

public final int SIZE;
private int x1, y1, x2, y2;
private SpriteSheet sheet;
public int[] pixels;

public Sprite(int x1, int y1, int x2, int y2, SpriteSheet sheet){
    this.sheet = sheet;
    this.SIZE = x2 - x1;
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.pixels = new int[SIZE * SIZE];
    load();
}

private void load(){
    for (int y = this.y1; y < this.y2; y++) {
        for (int x = this.x1; y < this.x2; x++) {
            pixels[x + y * SIZE] = sheet.pixels[(x + this.x1) + (y + this.y1) * sheet.SIZE];
        }
    }
}

}

public class SpriteSheet {

public static final SpriteSheet ARCHER_SHEET = new SpriteSheet("/textures/Archer_Sheet.png", 1024);
public static final SpriteSheet ENVIRONMENT_SHEET = new SpriteSheet("/textures/Environment_Sheet.png", 128);


private String path;
public final int SIZE;
public int[] pixels;

public SpriteSheet(String path, int size){
    this.path = path;
    this.SIZE = size;
    this.pixels = new int[SIZE * SIZE];
    load();
}

private void load(){
    try {
        BufferedImage image = ImageIO.read(SpriteSheet.class.getResource(path));
        int width = image.getWidth();
        int height = image.getHeight();
        image.getRGB(0, 0, width, height, pixels, 0, width);
        System.out.println("Loading image from path: " + SpriteSheet.class.getResource(path));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

public class Screen {

private int width, height;
public int[] pixels;

public int[] tiles =  new int[GameData.mapSize * GameData.mapSize];

private Random random = new Random();

public Screen(int width, int height){
    this.width = width;
    this.height = height;
    this.pixels = new int[width * height];

    for (int i = 0; i < GameData.mapSize * GameData.mapSize; i++) {
        tiles[i] = random.nextInt(0xFFFFFF);
    }
}

public void clearScreen(){
    for (int i = 0; i < pixels.length; i++) {
        pixels[i] = 0;
    }
}

public void render(int xOffset, int yOffset){

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            pixels[x + y * width] = Sprite.GRASS.pixels[(x & (Sprite.GRASS.SIZE - 1)) + (y & (Sprite.GRASS.SIZE - 1)) * Sprite.GRASS.SIZE];
        }
    }
}

}

Upvotes: 0

Views: 25

Answers (1)

yitzih
yitzih

Reputation: 3118

The issue appear to be from this code

for (int y = this.y1; y < this.y2; y++) {
    for (int x = this.x1; y < this.x2; x++) {
        pixels[x + y * SIZE] = sheet.pixels[(x + this.x1) + (y + this.y1) * sheet.SIZE];
    }
}

Lets do the math for:

x1 = 1
y1 = 1
x2 = 15
y2 = 15
SIZE = 14 (x2 - x1)

now lets look at your code

this.pixels = new int[SIZE * SIZE];
//creates an array of size 196
//so pixels.length == 196

now lets plug in the for loop for a worst case scenario (all values are at their highest)

for (int y = (1); y < (15); y++) {
    for (int x = (1); y < (15); x++) {
        pixels[14 + 14 * 14] = sheet.pixels[(14 + 1) + (14 + 1) * sheet.SIZE];
    }
}

we simplify the expressions

pixels[210] = sheet.pixels[(15) + (15) * sheet.SIZE];

as you can see the index only goes as high as 196 and and we are trying to access index 210. (The one on the right may also be out of bounds depending on the size of the array.)

NOTE: Also be aware that when doing (x + y * SIZE) the y * SIZE will happen first then x will be added in due to order of operations

Upvotes: 1

Related Questions