1

小さなゲームを作っています。アクションではなくパズルなので、パフォーマンスはそれほど重要ではありません。これで、メインのゲーム エリアである背景イメージができました。場合によっては、背景画像の一部の上に別の画像を描きたいことがあります。私の問題は、背景画像と重ね合わせた画像の両方が、フレーム数が不明な(基本的に、ユーザーが選択した)アニメーションgifになる可能性があることです。

今、私がやりたいことは、基本的には次のとおりです。背景画像を描画してアニメーション化し(GIFの場合)、その上に0〜n​​個の小さなアニメーションGIFを描画し、ピクセル座標で指定された背景画像に相対的な位置にします。さらに、画像がそれに応じてズーム/移動するようにサイズ変更可能である必要があります。

最終結果は次のようになります: http://i.stack.imgur.com/PxdDt.png (アニメーション化されていると想像してください)

レイアウトマネージャーをnullに設定し、絶対に配置されたアイコン付きのJLabelsを使用してそれらをアニメーション化し、1つを背景として使用し、もう1つを前景として追加することで機能する解決策を見つけました。

background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
background.setLocation(0, 0);
foreground.setLocation(30, 30);
background.setLayout(null);
background.add(foreground);
frame.setLayout(null);
frame.add(background);

(以下の完全なコード)

私が聞いたように、レイアウトマネージャーをnullに設定することは問題があります(特に、後で画像にテキストを追加したいので、背景ラベル自体ではなく、背景ラベル内に別のラベルを使用しますが) )、JLabels画像アイコンのサイズを変更できないため、この方法ではサイズ変更ができないようです(gifをレイヤーごとに1つのbufferedImageに分割し、それらをすべてサイズ変更してから再度まとめるソリューションがいくつか見つかりました。これにより、特定のフレーム間の遅延など)。また、位置はピクセル パーフェクトである必要があるため、サイズ変更が可能であっても、丸め誤差が原因で問題が発生する可能性があります。

さて、これを行うより良い方法はありますか?どうにかしてアニメーション GIF を読み込んで、それらを手動でマージすることはできますか (レイヤーの数が異なる可能性がある場合でも)、1 つの画像だけをペイントする必要がありましたか? コンポーネントの位置を手動で設定できるが、ウィンドウ/パネルのサイズを変更すると自動的にスケーリングされるレイアウト マネージャーはありますか? 私がやりたいことをすぐに実行できるサードパーティのグラフィックプロジェクトはありますか?

理想的には、マージされた画像を作成し、サイズを変更して表示するなど、アニメーションではない場合に行うことのようなものになります。

完全なコード:

import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public final class Tester  extends JFrame {
    public static void main(String[] args) throws MalformedURLException {
        new Tester();
    }

    private Tester() throws MalformedURLException {
        setTitle("Tester");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon backgroundIcon = new ImageIcon(new URL("http://s5.favim.com/orig/51/animated-gif-gif-hands-sign-language-Favim.com-542945.gif"));
        Icon foregroundIcon = new ImageIcon(new URL("http://i.imgur.com/89HANHg.gif"));

        JLabel background = new JLabel(backgroundIcon);
        JLabel foreground = new JLabel(foregroundIcon);

        // ugly
        background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
        foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
        background.setLocation(0, 0);
        foreground.setLocation(30, 30);
        background.setLayout(null);
        background.add(foreground);
        setLayout(null);
        add(background);

        // set size of frame to size of content
        setResizable(false);
        getContentPane().setPreferredSize(new Dimension(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight()));
        pack();

        setLocationRelativeTo(null);
        setVisible(true);
    }
}
4

1 に答える 1

3

これは私にとってはうまくいきます。小さい軌道の画像は、大きい月の満ち欠けの画像の中央に配置されています。

import java.awt.*;
import javax.swing.*;
import java.net.*;

public final class Tester  extends JFrame {
    public static void main(String[] args) throws MalformedURLException {
        new Tester();
    }

    private Tester() throws MalformedURLException {
        setTitle("Tester");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon backgroundIcon = new ImageIcon(
                new URL("http://1point1c.org/gif/moon/moonphases.gif"));
        Icon foregroundIcon = new ImageIcon(
                new URL("http://1point1c.org/gif/thum/plnttm.gif"));

        JLabel background = new JLabel(backgroundIcon);
        JLabel foreground = new JLabel(foregroundIcon);

        background.setLayout(new GridBagLayout());
        background.add(foreground);
        add(background);

        pack();

        setLocationByPlatform(true);
        setVisible(true);
    }
}
于 2013-08-25T21:56:18.907 に答える