2

我了解其背后的逻辑,但不知道如何将其转换为代码。有人可以告诉我我写的这个例子吗?

小程序所做的只是中心矩形自行上下左右移动。我想用双缓冲区摆脱烦人的闪烁,但我不知道要进行什么更改/添加才能实现。

import java.applet.*;

import java.awt.*;

public class Broadway extends Applet implements Runnable {

Thread animation;

int locx,locy; // location of rectangle
int width, height; // dimensions of rectangle

// direction of motion
static final byte UP = 0; 
static final byte DOWN = 1;
static final byte LEFT = 2;
static final byte RIGHT = 3;

byte state; // state the rect is in

// length of pausing interval in ms
static final int REFRESH_RATE = 100;


public void init() {

    setBackground(Color.black);

    locx = 80; // parameters of center rect
    locy = 100;
    width = 110;
    height = 90;
    state = UP;
}

public void start() {

    animation = new Thread(this);

    if (animation != null) {
    animation.start();
    }
}

public void paint(Graphics g) {

    g.setColor(Color.yellow);
    g.fillRect(0,0,90,90);
    g.fillRect(250,0,40,190);
    g.fillRect(80,110,100,20);

    g.setColor(Color.blue);
    g.fillRect(80,200,220,90);
    g.fillRect(100,10,90,80);

    g.setColor(Color.lightGray);
    g.fillRect(locx,locy,width,height);

    g.setColor(Color.red);
    g.fillRect(200,0,45,45);
    g.fillRect(0,100,70,200);

    g.setColor(Color.magenta);
    g.fillRect(200,55,60,135);
}

//update the center rectangle
void updateRectangle() {

    switch (state) {
    case DOWN:
        locy += 2;
        if (locy >= 110) {
        state = UP;
        }
        break;
    case UP:
        locy -= 2;
        if (locy <= 90) {
        state = RIGHT;
        }
        break;
    case RIGHT:
        locx += 2;
        if (locx >= 90) {
        state = LEFT;
        }
        break;
    case LEFT:
        locx -= 2;
        if (locx <= 70) {
        state = DOWN;
        }
        break;
    }
}

public void run() {

    while (true) {
        repaint();  
        updateRectangle();              
        try {
        Thread.sleep (REFRESH_RATE);    
        } catch (Exception exc) { };
    }
}

public void stop() {

    if (animation != null) {
    animation.stop();
    animation = null;
    }
}
}
4

2 回答 2

2
  1. import java.awt.*;
    将其更改为
    import javax.swing.*;
  2. public class Broadway extends Applet ..
    将其更改为
    public class Broadway extends JApplet ..
  3. 将所有自定义绘画移动到JPanel. 覆盖paintComponent(Graphics)而不是 paint(Graphics). AJPanel默认情况下是双缓冲的。
  4. 使用 Swing 做动画Timer

作为一般提示

在考虑使用小程序之前,使用Java Web Start编写框架并从链接启动它。

更新

此代码实现了上面的大部分建议,并在选项窗格中显示了生成的平滑缓冲动画。它可以改为显示在 aJFrameJApplet中。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Broadway extends JPanel {

    int locx, locy; // location of rectangle
    int width, height; // dimensions of rectangle
    Timer timer;
// direction of motion
    static final byte UP = 0;
    static final byte DOWN = 1;
    static final byte LEFT = 2;
    static final byte RIGHT = 3;
    byte state; // state the rect is in
// length of pausing interval in ms
    static final int REFRESH_RATE = 100;

    public Broadway() {

        setBackground(Color.black);

        locx = 80; // parameters of center rect
        locy = 100;
        width = 110;
        height = 90;
        state = UP;

        ActionListener listener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
                updateRectangle();
            }
        };

        timer = new Timer(this.REFRESH_RATE, listener);
    }

    public void start() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.yellow);
        g.fillRect(0, 0, 90, 90);
        g.fillRect(250, 0, 40, 190);
        g.fillRect(80, 110, 100, 20);

        g.setColor(Color.blue);
        g.fillRect(80, 200, 220, 90);
        g.fillRect(100, 10, 90, 80);

        g.setColor(Color.lightGray);
        g.fillRect(locx, locy, width, height);

        g.setColor(Color.red);
        g.fillRect(200, 0, 45, 45);
        g.fillRect(0, 100, 70, 200);

        g.setColor(Color.magenta);
        g.fillRect(200, 55, 60, 135);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

//update the center rectangle
    void updateRectangle() {

        switch (state) {
            case DOWN:
                locy += 2;
                if (locy >= 110) {
                    state = UP;
                }
                break;
            case UP:
                locy -= 2;
                if (locy <= 90) {
                    state = RIGHT;
                }
                break;
            case RIGHT:
                locx += 2;
                if (locx >= 90) {
                    state = LEFT;
                }
                break;
            case LEFT:
                locx -= 2;
                if (locx <= 70) {
                    state = DOWN;
                }
                break;
        }
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                Broadway bw  = new Broadway();

                bw.start();
                JOptionPane.showMessageDialog(null, bw);
                bw.stop();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}
于 2013-01-05T01:14:04.133 回答
1

基本上,您替换了paint方法,使其绘制到与Applet大小相同的图像,然后将该图像绘制在Graphics g.

那里有很多实现。

相关问题:

于 2013-01-05T01:11:32.607 回答