BufferedImage 到 BufferedImage 数组,图块消失

BufferedImage to BufferedImage Array, Tiles Disapear

好的 Whosebug,你是我现在的最后一行。

如果你看一下下面的代码和图片,你会注意到有两个文件被及时命名

Tile.java

TileMap.java

有关这些 classes 的更多信息,Google "ForeignGuyMike Dragon Tale Tutorial Part 8" 本项目的下载文件。 我现在正在使用他的 class 阅读磁贴,因为它对我的努力似乎非常有效。切换到 BufferedImage 数组的原因是允许每个图块都有动画,截至目前它确实适用于包含超过 1 帧的图像。

现在这两个 classes: 它们被特意设置为不通过图像进行动画处理,只是为了展示它们为这个程序而中断,而不是结合我的成像动画功能。

他们在这里

Code/Imagery 休息之前

public class TileMap {

// position
private double x;
private double y;

// bounds
private int xmin;
private int ymin;
private int xmax;
private int ymax;

private double tween;

// map
private int[][] map;
private int tileSize;
private int numRows;
private int numCols;
private int width;
private int height;

// tileset
private BufferedImage[] tileset;
private int numTilesAcross;
private Tile[][] tiles;

private Animation an;

// drawing
private int rowOffset;
private int colOffset;
private int numRowsToDraw;
private int numColsToDraw;

public TileMap(int tileSize) {
    this.tileSize = tileSize;
    numRowsToDraw = GamePanel.HEIGHT / tileSize + 2;
    numColsToDraw = GamePanel.WIDTH / tileSize + 2;
    tween = 0.07;
    an = new Animation();
}

public void loadTiles(BufferedImage[] s, int delay) {

    an.setDelay(delay);
    an.setFrames(s);

    try {

        tileset = s;

        numTilesAcross = tileset[0].getWidth() / tileSize;
        tiles = new Tile[2][numTilesAcross];

        BufferedImage[] subimage = new BufferedImage[s.length];
        for(int col = 0; col < numTilesAcross; col++) {
            subimage[0] = tileset[0].getSubimage(
                        col * tileSize,
                        0,
                        tileSize,
                        tileSize
                    );
            tiles[0][col] = new Tile(subimage[0], Tile.NORMAL);
            subimage[0] = tileset[0].getSubimage(
                        col * tileSize,
                        tileSize,
                        tileSize,
                        tileSize
                    );
            tiles[1][col] = new Tile(subimage[0], Tile.BLOCKED);
        }

    }
    catch(Exception e) {
        e.printStackTrace();
    }

}

public void loadMap(String s) {

    try {

        InputStream in = getClass().getResourceAsStream(s);
        BufferedReader br = new BufferedReader(
                    new InputStreamReader(in)
                );

        numCols = Integer.parseInt(br.readLine());
        numRows = Integer.parseInt(br.readLine());
        map = new int[numRows][numCols];
        width = numCols * tileSize;
        height = numRows * tileSize;

        xmin = GamePanel.WIDTH - width;
        xmax = 0;
        ymin = GamePanel.HEIGHT - height;
        ymax = 0;

        String delims = "\s+";
        for(int row = 0; row < numRows; row++) {
            String line = br.readLine();
            String[] tokens = line.split(delims);
            for(int col = 0; col < numCols; col++) {
                map[row][col] = Integer.parseInt(tokens[col]);
            }
        }

    }
    catch(Exception e) {
        e.printStackTrace();
    }

}

public int getTileSize() { return tileSize; }
public double getx() { return x; }
public double gety() { return y; }
public int getWidth() { return width; }
public int getHeight() { return height; }

public int getType(int row, int col) {
    int rc = map[row][col];
    int r = rc / numTilesAcross;
    int c = rc % numTilesAcross;
    return tiles[r][c].getType();
}

public void setTween(double d) { tween = d; }

public void setPosition(double x, double y) {

    this.x += (x - this.x) * tween;
    this.y += (y - this.y) * tween;

    fixBounds();

    colOffset = (int)-this.x / tileSize;
    rowOffset = (int)-this.y / tileSize;

}

private void fixBounds() {
    if(x < xmin) x = xmin;
    if(y < ymin) y = ymin;
    if(x > xmax) x = xmax;
    if(y > ymax) y = ymax;
}

public void update() {
    an.update();
}

public void draw(Graphics2D g) {

    for(
        int row = rowOffset;
        row < rowOffset + numRowsToDraw;
        row++) {

        if(row >= numRows) break;

        for(
            int col = colOffset;
            col < colOffset + numColsToDraw;
            col++) {

            if(col >= numCols) break;

            if(map[row][col] == 0) continue;

            int rc = map[row][col];
            int r = rc / numTilesAcross;
            int c = rc % numTilesAcross;

            g.drawImage(
                tiles[r][c].getImage(),
                (int)x + col * tileSize,
                (int)y + row * tileSize,
                null
            );

        }

    }

}

public class Tile {

private BufferedImage image;
private int type;

// tile types
public static final int NORMAL = 0;
public static final int BLOCKED = 1;

public Tile(BufferedImage image, int type) {
    this.image = image;
    this.type = type;
}

public BufferedImage getImage() { return image; }
public int getType() { return type; }

现在这是实施更改后的代码

变更集:

Tile.java

-构造函数参数已从 BufferedImage 更改为 BufferedImage[]

-BufferedImage图像转BufferedImage[]图像;

-getImage 到 getImage(int i) { return image[i]; }

TileMap.java

-初始化子图像并将其设置为BufferedImage[s.length];

-删除所有子图像[0]到子图像

-draw中的getImage现在是getImage(0); // 硬编码

之后

public class TileMap {

// position
private double x;
private double y;

// bounds
private int xmin;
private int ymin;
private int xmax;
private int ymax;

private double tween;

// map
private int[][] map;
private int tileSize;
private int numRows;
private int numCols;
private int width;
private int height;

// tileset
private BufferedImage[] tileset;
private int numTilesAcross;
private Tile[][] tiles;

private Animation an;

// drawing
private int rowOffset;
private int colOffset;
private int numRowsToDraw;
private int numColsToDraw;

public TileMap(int tileSize) {
    this.tileSize = tileSize;
    numRowsToDraw = GamePanel.HEIGHT / tileSize + 2;
    numColsToDraw = GamePanel.WIDTH / tileSize + 2;
    tween = 0.07;
    an = new Animation();
}

public void loadTiles(BufferedImage[] s, int delay) {

    an.setDelay(delay);
    an.setFrames(s);

    try {

        tileset = s;

        numTilesAcross = tileset[0].getWidth() / tileSize;
        tiles = new Tile[2][numTilesAcross];

        BufferedImage[] subimage = new BufferedImage[s.length];
        for(int col = 0; col < numTilesAcross; col++) {
            subimage[0] = tileset[0].getSubimage(
                        col * tileSize,
                        0,
                        tileSize,
                        tileSize
                    );
            tiles[0][col] = new Tile(subimage, Tile.NORMAL);
            subimage[0] = tileset[0].getSubimage(
                        col * tileSize,
                        tileSize,
                        tileSize,
                        tileSize
                    );
            tiles[1][col] = new Tile(subimage, Tile.BLOCKED);
        }

    }
    catch(Exception e) {
        e.printStackTrace();
    }

}

public void loadMap(String s) {

    try {

        InputStream in = getClass().getResourceAsStream(s);
        BufferedReader br = new BufferedReader(
                    new InputStreamReader(in)
                );

        numCols = Integer.parseInt(br.readLine());
        numRows = Integer.parseInt(br.readLine());
        map = new int[numRows][numCols];
        width = numCols * tileSize;
        height = numRows * tileSize;

        xmin = GamePanel.WIDTH - width;
        xmax = 0;
        ymin = GamePanel.HEIGHT - height;
        ymax = 0;

        String delims = "\s+";
        for(int row = 0; row < numRows; row++) {
            String line = br.readLine();
            String[] tokens = line.split(delims);
            for(int col = 0; col < numCols; col++) {
                map[row][col] = Integer.parseInt(tokens[col]);
            }
        }

    }
    catch(Exception e) {
        e.printStackTrace();
    }

}

public int getTileSize() { return tileSize; }
public double getx() { return x; }
public double gety() { return y; }
public int getWidth() { return width; }
public int getHeight() { return height; }

public int getType(int row, int col) {
    int rc = map[row][col];
    int r = rc / numTilesAcross;
    int c = rc % numTilesAcross;
    return tiles[r][c].getType();
}

public void setTween(double d) { tween = d; }

public void setPosition(double x, double y) {

    this.x += (x - this.x) * tween;
    this.y += (y - this.y) * tween;

    fixBounds();

    colOffset = (int)-this.x / tileSize;
    rowOffset = (int)-this.y / tileSize;

}

private void fixBounds() {
    if(x < xmin) x = xmin;
    if(y < ymin) y = ymin;
    if(x > xmax) x = xmax;
    if(y > ymax) y = ymax;
}

public void update() {
    an.update();
}

public void draw(Graphics2D g) {

    for(
        int row = rowOffset;
        row < rowOffset + numRowsToDraw;
        row++) {

        if(row >= numRows) break;

        for(
            int col = colOffset;
            col < colOffset + numColsToDraw;
            col++) {

            if(col >= numCols) break;

            if(map[row][col] == 0) continue;

            int rc = map[row][col];
            int r = rc / numTilesAcross;
            int c = rc % numTilesAcross;

            g.drawImage(
                tiles[r][c].getImage(0), // hard code the image at 0
                (int)x + col * tileSize,
                (int)y + row * tileSize,
                null
            );

        }

    }

}

public class Tile {

private BufferedImage[] image;
private int type;

// tile types
public static final int NORMAL = 0;
public static final int BLOCKED = 1;

public Tile(BufferedImage[] image, int type) {
    this.image = image;
    this.type = type;
}

public BufferedImage getImage(int i) { return image[i]; }
public int getType() { return type; }

对于任何想知道答案的人,它已经解决了。

本节

BufferedImage[] subimage = new BufferedImage[s.length];
    for(int col = 0; col < numTilesAcross; col++) {
        subimage[0] = tileset[0].getSubimage(
                    col * tileSize,
                    0,
                    tileSize,
                    tileSize
                );
        tiles[0][col] = new Tile(subimage, Tile.NORMAL);
        subimage[0] = tileset[0].getSubimage(
                    col * tileSize,
                    tileSize,
                    tileSize,
                    tileSize
                );
        tiles[1][col] = new Tile(subimage, Tile.BLOCKED);
    }

是罪魁祸首。感谢 haraldk 提供测试此问题的建议,解决方法是简单地将子图像放在循环中。不断更改内容并使用同一个数组只是将最后一个内容存储在整个数组中,因此把它搞砸了。

更新的代码示例

    for(int col = 0; col < numTilesAcross; col++) {
        BufferedImage[] subimage = new BufferedImage[s.length];
        subimage[0] = tileset[0].getSubimage(
                    col * tileSize,
                    0,
                    tileSize,
                    tileSize
                );
        tiles[0][col] = new Tile(subimage, Tile.NORMAL);
        subimage[0] = tileset[0].getSubimage(
                    col * tileSize,
                    tileSize,
                    tileSize,
                    tileSize
                );
        tiles[1][col] = new Tile(subimage, Tile.BLOCKED);
    }