1

JavaのGraphics2Dを使用して画面に描画する画像を取得しようとしています。これが私が使用しているコードです。画面上で画像が着実に移動するのを見たいです。現時点では画像を見ることができますが、ウィンドウのサイズを変更しない限り移動しません。その場合、移動します。以下のクラスをスケッチしました。

 public class Tester extends JFrame {

    private static final long serialVersionUID = -3179467003801103750L;
    private Component myComponent;
    public static final int ONE_SECOND = 1000;
    public static final int FRAMES_PER_SECOND = 20;

    private Timer myTimer;

    public Tester (Component component, String title) {
        super(title);
        myComponent = component;
    }

    public void start () {

        myTimer = new Timer(ONE_SECOND / FRAMES_PER_SECOND, new ActionListener() {
            @Override
            public void actionPerformed (ActionEvent e) {
                repaint();
            }
        });
        myTimer.start();
    }

    @Override
    public void paint (Graphics pen) {
        if (myComponent != null) {
            myComponent.paint(pen);
        }
    }

}

Tester に渡される Component オブジェクトは、次のクラスです。

public class LevelBoard extends Canvas implements ISavable {

    private static final long serialVersionUID = -3528519211577278934L;

    @Override
    public void paint (Graphics pen) {
        for (Sprite s : mySprites) {
            s.paint((Graphics2D) pen);
        }
    }

    protected void add (Sprite sprite) {
        mySprites.add(sprite);
    }

このクラスには、追加したスプライトが 1 つだけあることを確認しました。スプライトのクラスは、おおよそ次のとおりです。

public class Sprite {

    private Image myImage;
    private int myX, myY;

    public Sprite () {
        URL path = getClass().getResource("/images/Bowser.png");
        ImageIcon img = new ImageIcon(path);
        myImage = img.getImage();

    }

    public void update () {
        myX += 5;
        myY += 5;
    }

    public void paint (Graphics2D pen) {
        update();
        pen.drawImage(myImage, myX, myY,null);
    }

しかし、画面にはクッパの静止画像しか見えません。ウィンドウのサイズを変更しない限り、彼は動きません。Sprite クラスの paint(Graphics2D pen) メソッドが特定の間隔で呼び出されていることはわかっています (Tester クラスの Timer のため)。ただし、x と y の位置は毎回 5 ずつインクリメントされますが。スプライトは動かない。なぜだめですか?どうすれば修正できますか?現在、プログラムの他の機能をテストしようとしているので、これを起動して実行する必要があります。方法はあまり気にしません。

4

1 に答える 1

5

あなたのコードには問題がたくさんあります:

  1. JFrame.paint()特に を呼び出さない場合は、 をオーバーライドしないでくださいsuper。ContentPane を設定し、その をオーバーライドしますpaintComponent()。便利に見えるかもしれませんが、通常は設計が悪く、不要です。
  2. をオーバーライドJComponent.paint()するのではなく、オーバーライドするJComponent.paintComponent()(そして を呼び出すsuper)
  3. a を使用しJLabelてイメージを表示します。それははるかに簡単です。
  4. AWT(Canvas) と Swing (JFrame) を混在させないでください。スイングに固執します。

これは、フレーム内を移動するクッパを示す簡単な例です。(コマサイズを小さくしてコマ枠で画像を叩くと面白いです;-))

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UnsupportedLookAndFeelException;

public class TestAnimation2 {
    private static final int NB_OF_IMAGES_PER_SECOND = 50;
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private Random random = new Random();

    private double dx;
    private double dy;

    private double x = WIDTH / 2;
    private double y = HEIGHT / 2;

    protected void initUI() throws MalformedURLException {
        final JFrame frame = new JFrame(TestAnimation2.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        final JLabel label = new JLabel(new ImageIcon(new URL("http://www.lemondedemario.fr/images/dossier/bowser/bowser.png")));
        label.setSize(label.getPreferredSize());
        frame.setMinimumSize(label.getPreferredSize());
        frame.add(label);
        frame.setSize(WIDTH, HEIGHT);
        dx = getNextSpeed();
        dy = getNextSpeed();
        Timer t = new Timer(1000 / NB_OF_IMAGES_PER_SECOND, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                x += dx;
                y += dy;
                if (x + label.getWidth() > frame.getContentPane().getWidth()) {
                    x = frame.getContentPane().getWidth() - label.getWidth();
                    dx = -getNextSpeed();
                } else if (x < 0) {
                    x = 0;
                    dx = getNextSpeed();
                }
                if (y + label.getHeight() > frame.getContentPane().getHeight()) {
                    y = frame.getContentPane().getHeight() - label.getHeight();
                    dy = -getNextSpeed();
                } else if (y < 0) {
                    y = 0;
                    dy = getNextSpeed();
                }
                label.setLocation((int) x, (int) y);

            }
        });
        frame.setVisible(true);
        t.start();
    }

    private double getNextSpeed() {
        return 2 * Math.PI * (0.5 + random.nextDouble());
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new TestAnimation2().initUI();
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}
于 2012-11-16T23:44:25.383 に答える