java - 从 BufferedImage 渲染 Sprite 时出现问题

标签 java indexoutofboundsexception bufferedimage

在改编游戏创建教程中的代码后,我遇到了问题,但没有收到错误消息。它告诉我我有一个 OutOfBoundsException 像素[x + y * SIZE] =sheet.pixels[(x + this.x1) + (y + this.y1) *sheet.SIZE]; 但我不明白为什么。这是我的代码,感谢您的每一个帮助。屏幕的渲染是在 main 方法中完成的,这不可能是错误,因为使用教程代码工作得很好。

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];
        }
    }
}

}

最佳答案

问题似乎出自此代码

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];
    }
}

让我们计算一下:

x1 = 1
y1 = 1
x2 = 15
y2 = 15
尺寸 = 14(x2 - x1)

现在让我们看看您的代码

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

现在让我们插入 for 循环以应对最坏的情况(所有值均处于最高值)

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];
    }
}

我们简化表达式

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

正如您所看到的,索引最高只能达到 196,而我们正在尝试访问索引 210。(根据数组的大小,右侧的索引也可能超出范围。)

注意:还要注意,在执行(x + y * SIZE)时,y * SIZE将首先发生,然后根据操作顺序添加x

关于java - 从 BufferedImage 渲染 Sprite 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33885249/

相关文章:

java - SWF - 将输入参数发送到工作流程

java - com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException : Duplicate field 问题

java - 在 .Properties 文件中搜索日语字符串消息

java - 我的数组哪里出界了?

java - 为什么要使用回调方法进行多态

java - 迭代 For 循环、ArrayIndexOutOfBounds

iOS - 奇怪的越界异常

bufferedimage - JCodec 图片转 BufferedImage

java - 如何检查上传的文件是图片还是其他文件?

Java - 图像旋转