有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Slick的速度非常慢,但只绘制矩形

我从几天开始使用slick for java,遇到了一个严重的问题。 如果我使用800x600的解决方案运行一个完全空的应用程序(它只显示fps),我会得到一个介于700和800之间的fps计数。 如果我现在画一个包含13300个条目的数组,作为一个由绿色和白色矩形组成的网格,fps会下降到大约70

数组中的条目越多,速度就越慢。 例如,在1024x768的解决方案和包含21760个条目的阵列中,fps降至40

如何绘制单个条目:

public void draw(Graphics graphics){
    graphics.setColor(new Color(getColor().getRed(), getColor().getGreen(), getColor().getBlue(), getColor().getAlpha()));

    graphics.fillRect(getPosition().x, getPosition().y, getSize().x, getSize().y);

    Color_ARGB white = new Color_ARGB(Color_ARGB.ColorNames.WHITE);
    graphics.setColor(new Color(white.getRed(), white.getGreen(), white.getBlue(), white.getAlpha()));
}

这就是我绘制完整阵列的方式:

public void draw(Graphics graphics) {
    for (int ix = 0; ix < getWidth(); ix++) {
        for (int iy = 0; iy < getHeight(); iy++) {
            getGameGridAt(ix, iy).draw(graphics);
        }
    }
}

在我看来,21760没有那么多。 我的代码有什么问题吗?或者是slick太慢了,不能画这么多矩形


共 (5) 个答案

  1. # 1 楼答案

    你很可能无法画出比这更快的单个矩形

    每秒渲染数百万个多边形的游戏使用顶点缓冲区对象(VBO)进行渲染。为此,您可能需要针对OpenGLAPI(LWJGL)本身而不是包装器进行编码

  2. # 2 楼答案

    刚刚注意到在另一个答案中,您有一个整数大小的网格(5x5)。。。在这种情况下,最快的方法似乎是将每个项目绘制为一个像素(您可以直接在内存中使用二维数组进行此操作),并将其缩放到500%,或者将其用作纹理,并绘制一个矩形,以达到您所需的最终大小。。。应该很快。很抱歉,前面的回答造成了混乱,你应该从一开始就更清楚地说明你在做什么。 如果不可用缩放和纹理,你仍然可以使用这样的东西在内存中绘制(用C++编写,请自己翻译成java)< /p>

    for( int x = 0; x < grid.width(); x++ ) {
       for( int y = 0; y < grid.height(); y++ ) {
          image[x*5][y*5] = grid.color[x][y];
          image[x*5][y*5 + 1] = grid.color[x][y];
          image[x*5][y*5 + 2] = grid.color[x][y];
          image[x*5][y*5 + 3] = grid.color[x][y];
          image[x*5][y*5 + 4] = grid.color[x][y];
       }
       memcpy(image[x*5+1], image[x*5], grid.height() * sizeof(image[0][0]) );
       memcpy(image[x*5+2], image[x*5], grid.height() * sizeof(image[0][0]) );
       memcpy(image[x*5+3], image[x*5], grid.height() * sizeof(image[0][0]) );
       memcpy(image[x*5+4], image[x*5], grid.height() * sizeof(image[0][0]) );
    }
    

    我不确定,但也许对于图形,x和y的表示顺序可能与这里使用的相反,因此,如果是这样的话,请相应地更改代码(只要运行几次迭代,您就会发现这一点),而且您的数据结构可能有点不同,但我认为想法应该是明确的

  3. # 3 楼答案

    您只想绘制屏幕上的矩形。如果屏幕边界在x方向上从0到1024,在y方向上从0到768,那么您只需要在这些边界内的矩形中循环,然后只绘制这些矩形。我无法想象你试图在这些边界内绘制21760个矩形

    如果是,那么尝试创建一个静态矩形,然后尝试在需要绘制它的所有不同位置绘制该矩形,而不是每次都创建一个新矩形。例如,在我正在制作的一个游戏中,我可能有1000个“草”瓷砖,但所有1000个瓷砖共享相同的静态纹理。因此,我只需要参考一个图像,而不是每个瓷砖创建自己的

    每个矩形仍然可以具有唯一的状态。只需创建自己的矩形类,并创建一个静态最终图像,其中包含一个5*5的图像。每个矩形在需要绘制时都将使用此图像。每个矩形仍然可以具有唯一的属性。例如,私有向量2f位置、私有布尔值isAlive等

  4. # 4 楼答案

    不确定Slick是否允许,但如果这个东西看起来像棋盘格。。。您可以只绘制4个矩形,抓取它们,并将生成的图像用作整个图像的纹理。我甚至不是一个java程序员,只是想想出一个解决方案

  5. # 5 楼答案

    因为你只是重复使用一些颜色,所以为每一个颜色创建一个新的颜色对象肯定会很慢。。。对于使用的每种不同颜色只使用一次new,并将可重用的颜色存储在类中的某个位置,而不是使用这些颜色调用函数,不断分配和释放内存是非常缓慢的

    虽然这可能没有每次都使用new带来的好处那么多,但是您是否考虑过缓存所有这些函数调用的结果并重写代码

    public void draw(Graphics graphics) {
        int ixmax = getWidth();
        int iymax = getHeight();
        for (int ix = 0; ix < ixmax; ix++) {
            for (int iy = 0; iy < iymax; iy++) {
                getGameGridAt(ix, iy).draw(graphics);
            }
        }
    }
    

    或者如果您不想声明新变量

    public void draw(Graphics graphics) {
        for (int ix = getWidth() - 1; ix >= 0; ix--) {
            for (int iy = getHeight() - 1; iy >= 0; iy--) {
                getGameGridAt(ix, iy).draw(graphics);
            }
        }
    }