2

この弾むボールのアニメーションの簡単なコード例では、次のようになります。

import javax.swing.JApplet;
import javax.swing.JFrame;
import java.awt.*;

public class GraphicsMovement extends JApplet
{
public static void pause()
{
    try {
        Thread.sleep(10);
        } catch(InterruptedException e) {
          }
}

public static void main(String args[])
{
    JApplet example = new GraphicsMovement();
    JFrame frame = new JFrame("Movement");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(example);
    frame.setSize(new Dimension(500,300));       //Sets the dimensions of panel to appear when run
    frame.setVisible(true);
}

  public void paint (Graphics page)
  {
 int width = getWidth();    // width = the width of the panel which appears when run
 int height = getHeight();  // height = the height of the panel which appears when run.

//Changes background color to a blueish color
page.setColor(new Color (140,214,225));
page.fillRect(0,0,width,height);
for(int i = 0; i <= 5; i++)
{
    for (int j = 0; j <= 100; j++)
    {
        page.setColor(Color.YELLOW);
        page.fillOval(100,55 + j,100,100);  //draws a yellow oval
        pause();
        page.setColor(new Color (140,214,225));
        page.fillOval(100,55 + j,100,100);  //draws a blueish oval over the yellow oval
    }
    for (int k = 100; k >= 0; k--)
    {
        page.setColor(Color.YELLOW);
        page.fillOval(100,55 + k,100,100);  //draws a yellow oval
        pause();
        if (k != 0)
        {
            page.setColor(new Color (140,214,225));  //draws a blueish oval over the yellow oval
            page.fillOval(100,55 + k,100,100);
        }
    }
}
 }
 }

アニメーションは正常に描画され、Windows マシン (JCreator を使用) で実行されますが、IntelliJ または Eclipse でコンパイルされた Mac OS X では実行されません。2 つの異なる OS X マシンで試してみましたが、どちらもボールと背景を (長い間待った後) 描画しますが、アニメーションは続行しません。

私が見逃しているプラ​​ットフォーム固有のコードはありますか? ありがとう!

4

2 に答える 2

3

paint()メソッドは UI スレッドで呼び出され、できるだけ早く返される必要があります。

では、アニメーション コードをどこに配置するのでしょうか?答えは簡単です。コードを別のスレッドに配置する必要があります。

Windows と OS X の違いについては、スレッドのスケジュール方法などに関連しているとしか言えません。

于 2012-10-22T14:21:30.760 に答える
2

paint再描画要求をブロックするか、またはトリガーする可能性のあるメソッドで何も実行しないでください。

常に を呼び出す必要がありますsuper.paintXxx。これらのメソッドは、バックグラウンドで多くの作業を行います。通常は、実行できるよりもはるかに優れています。

JAppletやのような最上位のコンテナから拡張する必要はありません (非常にまれなケースです) JFrame。カスタム コンテナ ( などJPanel) を作成し、そこにコンポーネントを追加する (またはカスタム ペイントを実行する) 方が適切です。ダブル バッファリングのサポートとは別に、展開の選択の柔軟性も得られます。

自分をからかわないでください。ペイント プロセスを制御するのはあなたではありません。これらの決定を下すのは再描画マネージャー次第ですが、更新を「奨励」することはできます。これは、人々がアニメーションで遊んでいるときに最も苦痛を引き起こします。

Event Dispatching Thread (EDT) の影響の外で、またはあなたの場合はpaintコンテキストの外で、アニメーションの「状態」を変更する必要があります。

javax.swing.Timerあなたの問題は、単純な人がそれを解決するほど単純です。より複雑なアニメーションには、「アニメーション」スレッドが必要になる場合があります。

public class GraphicsMovement extends JApplet {

    @Override
    public void init() {
        setLayout(new BorderLayout());
        add(new AnimatedPane());
    }

    @Override
    public void start() {
    }

    public class AnimatedPane extends JPanel {

        private Timer timer;
        private boolean colorSwitch = false;

        private int yOffset = 0;
        private int direction = 1;

        public AnimatedPane() {
            timer = new Timer(10, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
//                    colorSwitch = !colorSwitch;
                    yOffset += direction;
                    if (yOffset > 100) {
                        direction = -1;
                        yOffset = 100;
                    } else if (yOffset < 0){
                        direction = 1;
                        yOffset = 0;
                    }
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();

            setBackground(new Color(140, 214, 225));
        }

        @Override
        protected void paintComponent(Graphics page) {
            super.paintComponent(page);
            int width = getWidth();    // width = the width of the panel which appears when run
            int height = getHeight();  // height = the height of the panel which appears when run.

            if (colorSwitch) {
                page.setColor(new Color(140, 214, 225));
            } else {
                page.setColor(Color.YELLOW);
            }
            page.fillOval(100, 55 + yOffset, 100, 100);  //draws a yellow oval
        }
    }
}

私は 10 ミリ秒の「遅延」に関心があります。

読み進めるとわかるかもしれません...

興味のあること

于 2012-10-22T23:41:57.820 に答える