1

数日以来、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 はそれほど多くはありません。私のコードに何か問題がありますか、それともあまりにも多くの長方形を描くのが遅すぎますか?

4

5 に答える 5

1

画面上にある長方形のみを描画したい。画面の境界が x 方向で 0 から 1024、y 方向で 0 から 768 の場合、それらの境界内にある四角形のみをループして、それらの四角形のみを描画します。これらの境界内に 21760 個の長方形を描画しようとしているとは想像できません。

そうであれば、毎回新しい長方形を作成するのではなく、1 つの静的な長方形を作成してから、描画する必要があるすべての異なる位置にその 1 つを描画してみてください。たとえば、私が作成しているゲームでは、「草」タイルである 1000 個のタイルがあるかもしれませんが、それらの 1000 個すべてが同じ静的テクスチャを共有しています。したがって、各タイルが独自の画像を作成するのではなく、1 つの画像を参照するだけで済みます。

各長方形は、独自の状態を持つことができます。独自の矩形クラスを作成し、5*5 の画像を保持する静的な最終画像を作成するだけです。各長方形は、描画する必要があるときにこの画像を使用します。四角形ごとに固有のプロパティを持つことができます。たとえば、プライベート Vector2f 位置、プライベート ブール値 isAlive など

于 2012-09-17T22:17:00.763 に答える
0

おそらく、それより速く個々の長方形を描くことはできないでしょう。

毎秒数百万のポリゴンをレンダリングするゲームは、頂点バッファオブジェクト(VBO)を使用してレンダリングします。そのためには、ラッパーではなく、OpenGL API(LWJGL)自体に対してコーディングする必要があります。

于 2012-09-17T22:13:47.807 に答える
0

Slickがそれを許可するかどうかはわかりませんが、これがチェス盤のグリッドのように見える場合は、4つの長方形を描画し、それらをつかんで、結果の画像を画像全体のテクスチャとして使用できます。私はJavaプログラマーでさえ、解決策を考え出そうとしているだけではありません。

于 2012-09-17T22:28:24.307 に答える
0

別の回答で、整数サイズのグリッド(5x5)があることに気づきました...この場合、これを行う最も速い方法は、各アイテムを単一のピクセルで描画することです(2-を使用してメモリ内で直接これを行うことができます次元配列) を 500% にスケーリングするか、テクスチャとして使用して、希望する最終的なサイズで 1 つの四角形を描画します ... 非常に高速です。以前の回答によって混乱が生じて申し訳ありません。最初から何をしているのかをもっと明確に言うべきでした。スケーリングとテクスチャが利用できない場合でも、このようなものを使用してメモリに描画できます (C++ で記述されているため、自分で Java に変換してください)。

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 がここで使用されている順序とは逆の順序で表されている可能性があるため、その場合はそれに応じてコードを変更してください (数回繰り返し実行するとすぐにわかります) 、また、データはおそらく少し異なる構造になっていますが、その考えは明確であるべきだと思います.

于 2012-09-18T09:34:00.630 に答える
0

ほんの数色しか繰り返し使用していないため、すべての色に対して新しい Color オブジェクトを作成するのは遅くなるはずです... new は、使用される異なる色ごとに 1 回だけ使用し、再利用可能な色をクラスのどこかに保存します。それらを使用して関数を呼び出すと、常にメモリを割り当てて解放するのが非常に遅くなります。

そして、これは毎回 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);
        }
    }
}
于 2012-09-17T22:16:25.257 に答える