【问题标题】:Slow map in javajava中的慢地图
【发布时间】:2014-09-01 08:18:14
【问题描述】:

我正在用java制作一个游戏,是一个rpg,但是,只有地图游戏很慢。 地图是在 TiledMap Editor 中制作的,因此是一个被读取并加载到 ArrayList 中的 XML。我的电脑是双核 3.0、4GB RAM、1GB 视频。 渲染完成如下:

//method of tileset class
public void loadTileset(){
    positions = new int[1 + tilesX * tilesY][2];
    int yy = 0;
    int xx = 0;
    int index = 0;
    // save the initial x and y point of each tile in an array named positions 
    // positions[tileNumber] [0] - X position 
    // positions[tileNumber] [1] - Y position
    for(int i = 1 ; i < positions.length; i++){ 
        if(index == tilesX ){
            yy += tileHeight;
            xx = 0;
            index = 0;
        }
        positions[i][0] = xx;
        positions[i][1] = yy;
        xx += tileWidth;    
        index++;
    }
}


//method of map class
public void draw(Graphics2D screen){
    //x and y position of each tile on the screen
    int x = 0; int y = 0;

    for(int j = 0; j < 20 ; j++){
        for(int i = initialTile ; i < initialTile + quantTiles  ; i++){
            int tile = map[j][i];
            if(tile != 0){
                screen.drawImage(tileSet.getTileImage().getSubimage(tileSet.getTileX(tile), tileSet.getTileY(tile),tileSet.getTileWidth(), tileSet.getTileHeight()),x,y,null);
            }
            x += tileSet.getTileWidth();
        }
        x = 0;
        y += tileSet.getTileHeight();
    }

}

我做错了吗? 注意:我是论坛的新手,更糟糕的是,我不太懂英语,如有错误请见谅。

【问题讨论】:

  • 这里很难看到任何明显的错误。您可能想尝试使用分析器(例如应该包含在 JDK 中的 visualvm)并使用它来查找花费最多时间的内容。
  • 您多久重绘一次地图?您使用的是什么图像子类型?最后,AWT 和 Swing 都很慢,请考虑使用更快的 2D 图形库。
  • @KarolS AWT 和 Swing 慢。 (无意冒犯,只是提一下……)
  • @Marco 与实际的面向游戏的库相比,它们是。好吧,也许不是 AWT,我从未使用过它,但在使用 Swing 后,我在 Slick2D 中重新渲染主窗口后发现了巨大的性能差异。

标签: java graphics 2d-games


【解决方案1】:

首先,您不应在每次调用期间为图块创建子图像。严格来说,对于要绘制的图像,您根本不应该调用getSubimage:它会使图像“不受管理”,这会使渲染性能降低一个数量级。您应该只为不想渲染的图像调用getSubimage - 例如,当您最初为图块创建单个图像时。

你显然已经有一个TileSet 类。您可以向此类添加一些功能,以便您可以直接访问图块的图像。

您当前的代码如下所示:

screen.drawImage(
    tileSet.getTileImage().getSubimage(
        tileSet.getTileX(tile), 
        tileSet.getTileY(tile),
        tileSet.getTileWidth(), 
        tileSet.getTileHeight()),
    x,y,null);

你可以把它改成这样:

screen.drawImage(tileSet.getTileImage(tile), x,y,null);

此处建议的getTileImage(int tile) 方法随后可以获取已在内部存储的图块。

我会从脑海中勾勒出几行代码,您可能可以将其转移到您的 TileSet 类中:

class TileSet
{
    private Map<Integer, BufferedImage> tileImages;

    TileSet()
    {
        ....
        prepareTileImages();
    }

    private void prepareTileImages()
    {
        tileImages = new HashMap<Integer, BufferedImage>();

        for (int tile : allPossibleTileValuesThatMayBeInTheMap)
        {
            // These are the tiles that you originally rendered
            // in your "draw"-Method
            BufferedImage image = 
                getTileImage().getSubimage(
                    getTileX(tile), 
                    getTileY(tile),
                    getTileWidth(), 
                    getTileHeight());

            // Create a new, managed copy of the image,
            // and store it in the map
            BufferedImage managedImage = convertToARGB(image);
            tileImages.put(tile, managedImage);
        }
    }

    private static BufferedImage convertToARGB(BufferedImage image)
    {
        BufferedImage newImage = new BufferedImage(
            image.getWidth(), image.getHeight(),
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = newImage.createGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return newImage;
    }    

    // This is the new method: For a given "tile" value
    // that you found at map[x][y], this returns the
    // appropriate tile:
    public BufferedImage getTileImage(int tile) 
    {
        return tileImages.get(tile);
    }
}

【讨论】:

  • 我明白你的意思,我会试试的。感谢您的帮助
  • 大大改进,连屏幕上没有出现的渲染区域也慢慢停止了。只是一个问题,不明白为什么方法convertToARGB(),发如下:tileImages.put(index,image.getSubimage(xx, yy, tileWidth, tileHeight);。前面提到的方法的目的是什么?
  • @Cairo 我在stackoverflow.com/a/22231370/3182664 中写了几句话,更多信息是例如在jhlabs.com/ip/managed_images.html
  • 好的,谢谢@Marco13 的帮助
猜你喜欢
  • 1970-01-01
  • 2011-03-16
  • 2015-02-15
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
相关资源
最近更新 更多