2

ここで私がやろうとしているのは、ゲーム内のすべてのグラフィックをできるだけ速くレンダリングすることです。ゲームはタイルベースであり、レンダリングするには多くの画像が必要です。私が抱えている問題は、すべての画像を描画するのに時間がかかることです。タイルを特別な方法で描画することになっているのかどうかはわかりませんが、現在、ビューポート内にあるすべてのタイルを1つずつレンダリングしています。

これが私の描画方法です:

public void draw(Graphics2D g){

    boolean drawn=false; // if player is drawn
    int px=vpPosX, py=vpPosY; // Viewport Position

    for(int y=Math.round(py/64); y<Math.round(py/64)+core.blcHeight; y++){
        for(int x=Math.round(px/64); x<Math.round(px/64)+core.blcWidth; x++){
            if(y<height && x<width && y>-1 && x>-1 && worldData[currentLayer][x][y] != 0){ // if tile is inside map
            BufferedImage img = tileset.tiles[worldData[currentLayer][x][y]]; //tile image
            if(-py+player.PosY+64-15 < (y*64)-py-(img.getHeight())+64 && drawn==false){player.draw(g);drawn=true;} // if player should be drawn
                if(worldBackground[currentLayer][x][y]!=0){ // if tile has background
                    BufferedImage imgBack = tileset.tiles[worldBackground[currentLayer][x][y]]; // background tile
                    g.drawImage(imgBack, (x*64)-px-(((imgBack.getWidth())-64)/2), (y*64)-py-(imgBack.getHeight())+64, null); //draw background
                }
                g.drawImage(img, (x*64)-px-(((img.getWidth())-64)/2), (y*64)-py-(img.getHeight())+64, null); // draw tile
            }
        }
    }

    if(!drawn){player.draw(g);} // if drawn equals false draw player

    }

すべての画像はタイルセットクラスにロードされます。
ゲームのfps/upsは60でロックされ
ています。このメソッドは、gameloopを持つコアクラスから呼び出されます。

私が知りたいのは、私が何を間違っているのかということです。
描画方法を変更する必要がありますか?
特別な方法で画像をロードする必要がありますか?
ペイントの方法を変更する必要がありますか?

私の目標は、ラグのない2Dタイルゲームを作ることです。

私が気付いたのは、タイル画像を保持するバッファリングされた画像がRGBA形式であるということでした。しかし、RGBにしたときは、レンダリングにかかる​​時間が大幅に短縮されました。追加情報の描画に時間がかかっていることはわかっています。しかし、私が知らなかったのは、それが実際にどれだけだったかということでした。

パフォーマンスを向上させるものを1つ見つけることができました。
すべての画像をロードして、この方法で作成された画像にコピーした場合:

BufferedImage bi = ImageIO.read(ims[i]);
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage b = gc.createCompatibleImage(bi.getWidth()*4, bi.getHeight()*4, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = b.createGraphics();
g.drawImage(bi, 0, 0, bi.getWidth()*4, bi.getHeight()*4, null);
tiles[id]=b;
g.dispose();

その後、すべてのタイルを描画するのにかかる時間が大幅に短縮されました。しかし、それでももっと良いかもしれません。そして、私が軽いエンジンを作るつもりであるとき(例えば地下)。次に、タイルの上に透明な長方形を使用する必要があります。または、透明な長方形を使用せずにタイルを暗くするためのより良い方法を誰かが提案できる場合。しかし、透明な長方形を描画しようとすると、遅れが生じます。透明な画像や長方形の使用を避けるべきかどうかはわかりません。

誰かが私を正しい方向に向けることができることを願っています。

4

1 に答える 1

1

役に立つかもしれないいくつかのトリック:

  • 静的な背景タイルがたくさんある場合は、すべてのフレームを再描画しないでください。それらを一度 BufferedImage に描画し、これを使用して一度に背景全体を描画します。タイルの 1 つが変更された場合、または画面をスクロールした場合などにのみ、この背景画像を更新する必要があります。
  • 表示されているタイルのみを描画していることを確認してください。これを行っているように見えますが、core.blcHeight と core.blcWidth が大きすぎると、描画するタイルが多すぎる可能性があります。
  • 60FPs へのロックについて心配する必要はありません。タイル ベースのゲームの場合、これはおそらく必要ありません。ゲーム ロジックをフレーム レートから切り離し、処理可能な速度でゲームをレンダリングすることをお勧めします。
  • 単色の背景タイルの場合、アルファ シェーディングで描画する必要はありません。これにより、場合によっては描画が大幅に高速化されます。TYPE_INT_RGBつまり、代わりに使用できますTYPE_INT_ARGB

高性能の描画/アニメーションが本当に必要な場合は、OpenGL ベースのレンダリング エンジン ( Slick2DLWJGLなど) への切り替えを検討することをお勧めします。

于 2012-09-22T11:37:09.500 に答える