1

私は現在、NetBeans で Java アニメーションとグラフィックスを学んでいます。

JPanel で簡単なボールの動きから始めることにしました。

ちらつきの問題を解決するのに問題があります。私は多くのフォーラムを見てきましたが、ほとんどはダブル バッファリングを使用する AWT に関するものでしたが、SWING コンポーネントにはダブル バッファリングが必要ないことがわかりました。と を使っrepaint()てみました。clearRect().

2つのうち、 を使用していることがわかりました。clearRect()より良い結果が得られましたが、常にシームレスなちらつきのないアニメーションではありませんでした。

これが私のコードです:

public class NewJFrame extends javax.swing.JFrame {

int x;
int y;
int xspeed = 1;
int yspeed = 1;
int width;
int height;
Graphics g;

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {
        initComponents();
    }                             

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
g = jp.getGraphics();
width = jp.getWidth();
height = jp.getHeight();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
    public void run() {
        move();
        time();

    }
}, 1000, 10);

    }                                        
void time() {
    final Graphics g = jp.getGraphics();
    final Timer timerCHK = new Timer();
    timerCHK.schedule(new TimerTask() {
        public void run() {
            g.clearRect(0, 0, jp.getWidth() - 3, jp.getHeight() - 3);

        }
    }, 1000, 12);
}

void move() {
    x = x + xspeed;
    y = y + yspeed;
    Graphics mk = jp.getGraphics();
    if (x < 0) {
        x = 0;
        xspeed = -xspeed;
    } else if (x > width - 20) {
        x = width - 20;
        xspeed = -xspeed;
    }

    if (y < 0) {
        y = 0;
        yspeed = -yspeed;
    } else if (y == height - 20) {
        y = height - 20;
        yspeed = -yspeed;
    }

    mk.drawOval(x, y, 20, 20);

}
    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
}
4

3 に答える 3

3
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class NewJFrame extends JFrame {

    private JPanel jp;
    private Timer timer;

    public NewJFrame() {
        initComponents();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setLocationByPlatform(true);
        timer.start();
    }

    public void initComponents() {
        ActionListener al = new ActionListener() {

            public void actionPerformed(ActionEvent evt) {
                jp.repaint();
            }
        };
        timer = new Timer(50,al);

        jp = new JPanel() {

            int x;
            int y;
            int xspeed = 1;
            int yspeed = 1;

            Dimension preferredSize = new Dimension(300, 100);

            @Override
            public Dimension getPreferredSize() {
                return preferredSize;
            }

            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                this.move();
                Graphics2D g2 = (Graphics2D)g;
                g2.setRenderingHint(
                        RenderingHints.KEY_ANTIALIASING, 
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g.drawOval(x, y, 20, 20);
            }

            void move() {
                x = x + xspeed;
                y = y + yspeed;
                if (x < 0) {
                    x = 0;
                    xspeed = -xspeed;
                } else if (x > getWidth() - 20) {
                    x = getWidth() - 20;
                    xspeed = -xspeed;
                }

                if (y < 0) {
                    y = 0;
                    yspeed = -yspeed;
                } else if (y == getHeight() - 20) {
                    y = getHeight() - 20;
                    yspeed = -yspeed;
                }
            }
        };
        jp.setBackground(Color.ORANGE);

        this.add(jp);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
}
于 2012-12-27T10:29:19.900 に答える
0

これは(それ自体)回答ではなく、拡張されたコメントです - コメントには十分なスペースがありませんでした

もっと学びたいのですが、基本的なアニメーションに関するチュートリアル(参照した例など)を提案してもらえますか?

残念ながら違います。数年前に 3D アニメーションの短いコースを受講し、そこから学んだ基本原則の多くを自分のプログラミングに適用しました。多くの理論は私たちの仕事には不必要ですが、理解することは依然として重要です。

直面する問題は、アニメーションの理論を十分に理解する必要があるだけでなく、Swing の内部動作と API についても十分に理解する必要があるということです。

この点で役立つ優れた API が多数ありますが、それらを海賊版として使用するには、アニメーション理論を理解する必要があります。

  • TimingFramwork - バージョン 1 より前からこの API を使用してきました。この API を中心に合理的なコード ライブラリを作成しましたが、非常に柔軟で便利であることがわかりました。最新バージョンは、実行するのに少し手間がかかります...
  • Trident - TimingFramework に似ていますが、TimingFramework よりもコンポーネントの操作に重点を置いています。
  • Universal Tween Engine - 私はこれを使ったことはありませんが、見てみたいと思っています...

Kirill Grouchnikov は彼のPushing Pixels Web サイト (彼のTrident アニメーションエンジンをサポートするため) でいくつかの優れた投稿を行っています。

Kirill はまた、次のアーティカルを強調しています (これは認めざるを得ません。私はまだ読んでいません ;))

Swing側で更新

Swing 側については、次のことを十分に理解している必要があります。

Swing でのペイント- AWT と Swingでのペイントおよびカスタム ペイントの実行を参照してください。

これは本当に、本当に重要です。これは、開発者が初めて Swing でアニメーションを実行しようとしたときによくある誤解の 1 つです。

また、Java の同時実行性、特にSwingへの適用方法についても理解する必要があります。

于 2012-12-27T21:31:44.267 に答える
-1

私は非常によく似たちらつきの問題を抱えていました。

contentPane.updateUI();

私の問題をすべて解決し、 updateUI() があなたの問題を解決したかどうか教えてください

于 2012-12-27T07:50:57.217 に答える