0

各プレイヤーが複数のユニットを持ち、各ユニットが次の方法でファイルから読み取った共通の画像を使用してユーザーに表示されるボードゲームを実装しています。アプリケーションの起動時にこの画像を読み取り、後で使用します。

    private static BufferedImage readBufferedImage (String imagePath) {
        try {
            InputStream is = IconManager.class.getClassLoader().getResourceAsStream(imagePath);
            BufferedImage bimage = ImageIO.read(is);
            is.close();
            return bimage;
        } catch (Exception e) {
            return null;
        }
    }

ユニットは、共通の画像の上にあるさまざまなカラフルなトークンで異なります。

いくつかの commonImages を JPanel に追加する前に、commonImage の上に浮かんでいた JLabels を使用してトークンを実装しました。

    //at startup
    ImageIcon commonImage = new ImageIcon(readBufferedImage("image.png"));
    ...
    JPanel panel = new JPanel();
    panel.add(commonImage);
    panel.add(commonImage);

    //located JLabels with token on the top of each commonImage        

しかし、今は JPanel の代わりに JScrollPane を使用したいので、ユーザーに表示する前に各 commonImage に drawString() と drawImage() を使用する方が良いと思います。

おおよそのユニット数を 20 と見積もっています。したがって、ユニットごとにターンごとに、さまざまなトークン構成でオンザフライで個別の BufferedImage を生成する必要があります。

問題は、トークンの構成に応じて、既に生成された BufferedImages をキャッシュして、同じ構成でイメージが以前に生成された場合にキャッシュから抽出する必要があるかどうかです。

4

1 に答える 1

1

あなたが尋ねる質問は、いくつかの要因によって異なります。

  1. イメージをゼロから生成するのにかかる時間
  2. イメージが以前に生成されたかどうかを確認するのにかかる時間
  3. 各画像の大きさ
  4. 画像が再利用される確率

そのため、アプリケーションに関する十分な知識がなければ、あらゆる状況に対して正確な回答を提供できる人はいません。

一般に、トークンを移動するだけの場合は、図面のパネルのupdateおよびメソッドをすばやく実装する必要があります。paintComponentベースイメージ、トークンイメージ、および現在の結果イメージ (基本的には提案したもの) を保存すると、パフォーマンスの問題は発生しないと思います。重要なのは、カスタムupdateメソッドで画像の更新を行い、現在の結果の画像をメソッドで常に描画するpaintComponentことです。

アップデート

たとえば、次のようなコードを使用して現在の表示をキャッシュできます。

private BufferedImage cachedImage;
...

@Override
public void paintComponent(Graphics g){
    //If the image needs to be refreshed draw it to the cache first
    if(cachedImage == null){
        cachedImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        super.paintComponent(cachedImage.getGraphics());
    }

    //Draw the image from cache
    g.drawImage(cachedImage, 0, 0, this);
}

キャッシュをクリアしたい場合は、更新を行うメソッドで、次のように設定しますcachedImage = null;

しかし、あなたの状況では、

  • 200x200 のスケールで発生するパフォーマンスの問題は、実行している描画の数に関係しています。あなたはフレーム/秒のレートを気にしていないと思うので、パフォーマンスの問題があるとは思えません (タイミングを収集して、描画にかかる時間を正確に確認できます - 100 ミリ秒未満だと思います)
  • 最も簡単な方法は、トークンとその文字列のイメージをキャッシュすることです (ほとんど変更されないと思います) が、それでもトークンのレイアウトを動的に作成します。(あなたの状況での他のパフォーマンスの向上はそれほど簡単ではありません)。
  • 画面の以前のレンダリングをキャッシュすると、基本的にスイング表示モデルが壊れます (それを使用する意味はあまりありません - 自分でレイアウトを行うだけです)。これは実際には、ほとんどすべてのコンテナーのキャッシュに適用されます。
于 2012-11-20T21:56:17.940 に答える