使用定時器實現彈彈球

今天模擬書上的一個例題做了一個彈彈球,是在畫布上的指定位置畫多個圓,經過一段的延時後,在附近位置重新畫。使球看起來是動,通過JSpinner組件調節延時,來控制彈彈球的移動速度.

BallsCanvas.java

public class BallsCanvas extends Canvas implements ActionListener, FocusListener { private Ball balls[]; // 多個球 private Timer timer; private static class Ball { int x, y; // 座標 Color color; // 顏色 boolean up, left; // 運動方向 Ball(int x, int y, Color color) { this.x = x; this.y = y; this.color = color; up = left = false; } } public BallsCanvas(Color colors[], int delay) { // 初始化顏色、延時 this.balls = new Ball[colors.length]; for (int i = 0, x = 40; i < colors.length; i++, x += 40) { balls[i] = new Ball(x, x, colors[i]); } this.addFocusListener(this); timer = new Timer(delay, this); // 創建定時器對象,delay指定延時 timer.start(); } // 設置延時 public void setDelay(int delay) { timer.setDelay(delay); } // 在canvas上面作畫 public void paint(Graphics g) { for (int i = 0; i < balls.length; i++) { g.setColor(balls[i].color); // 設置顏色 balls[i].x = balls[i].left ? balls[i].x - 10 : balls[i].x + 10; if (balls[i].x < 0 || balls[i].x >= this.getWidth()) { // 到水平方向更改方向 balls[i].left = !balls[i].left; } balls[i].y = balls[i].up ? balls[i].y - 10 : balls[i].y + 10; if (balls[i].y < 0 || balls[i].y >= this.getHeight()) { // 到垂直方向更改方向 balls[i].up = !balls[i].up; } g.fillOval(balls[i].x, balls[i].y, 20, 20); // 畫指定直徑的圓 } } // 定時器定時執行事件 @Override public void actionPerformed(ActionEvent e) { repaint(); // 重畫 } // 獲得焦點 @Override public void focusGained(FocusEvent e) { timer.stop(); // 定時器停止 } // 失去焦點 @Override public void focusLost(FocusEvent e) { timer.restart(); // 定時器重啓動 } }


BallsJFrame.java

class BallsJFrame extends JFrame implements ChangeListener { private BallsCanvas ball; private JSpinner spinner; public BallsJFrame() { super("彈彈球"); this.setBounds(300, 200, 480, 360); this.setDefaultCloseOperation(EXIT_ON_CLOSE); Color colors[] = { Color.red, Color.green, Color.blue, Color.magenta, Color.cyan }; ball = new BallsCanvas(colors, 100); this.getContentPane().add(ball); JPanel panel = new JPanel(); this.getContentPane().add(panel, "South"); panel.add(new JLabel("Delay")); spinner = new JSpinner(); spinner.setValue(100); panel.add(spinner); spinner.addChangeListener(this); this.setVisible(true); } @Override public void stateChanged(ChangeEvent e) { // 修改JSpinner值時,單擊JSpinner的Up或者down按鈕時,或者在JSpinner中按Enter鍵 ball.setDelay(Integer.parseInt("" + spinner.getValue())); } public static void main(String[] args) { new BallsJFrame(); } }


效果如下: