1. 程式人生 > >Java--彈彈球(定時器與圖形動畫設計)

Java--彈彈球(定時器與圖形動畫設計)

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import
javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.Timer; import javax.swing.colorchooser.ColorSelectionModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class ballsJFrame extends JFrame implements ChangeListener{ private JSpinner spinner;//微調按鈕
private ballsCanvas canvas;//用畫布畫球 public ballsJFrame() { super("彈彈球"); setBounds(300, 200, 400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); Color colors[]={Color.red ,Color.yellow ,Color.BLUE,Color.green,Color.gray};//小球顏色及個數 canvas=new ballsCanvas(colors, 100
);//new一個畫布 getContentPane().add(canvas); JPanel panel=new JPanel(); getContentPane().add(panel,BorderLayout.SOUTH);//getContentPane().add(panel,"SOUTH"); panel.add(new JLabel("dalay")); spinner =new JSpinner();//new一個微調按鈕 spinner.setValue(100);//設定初始值new ballsCanvas(colors, 100); panel.add(spinner); spinner.addChangeListener(this);//監聽裡面的數值發生變化 setVisible(true); } public static void main(String[] args) { new ballsJFrame(); } public void stateChanged(ChangeEvent e) { int delay=Integer.parseInt(""+spinner.getValue());//獲取微調按鈕文本里的值 canvas.setDelay(delay);//對timer設定數值 } } class ballsCanvas extends Canvas implements ActionListener, FocusListener{ private ball balls[];//球 private Timer timer;//定時器 class ball{//內部類,,底下畫球時就可以直接呼叫座標,不用getX()函式 private int x,y; private Color color; boolean up,left;//初始值是false public ball(int x, int y, Color color) { this.x = x; this.y = y; this.color = color; } } 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);//用法和btn.addActionLis一樣 timer.start();//定時器本身是一個執行緒物件,必須要啟動才會生效 } public void setDelay(int delay){//在ballsJFrame 類中的方法進行設定數值 timer.setDelay(delay); } public void paint(Graphics g) {//畫筆 for(int i=0;i<balls.length;i++){ g.setColor(balls[i].color);//用當前顏色畫球 //方法1: balls[i].x=balls[i].left? balls[i].x-5 : balls[i].x+5 ; //遇到邊界就改變方向 if(balls[i].x<=0 || balls[i].x+20>=this.getWidth()){//balls[i].x+20和balls[i].y+20因為球的座標是 **球外接正方形左上方的那一點**,所以判斷球碰到下面和右邊的邊界時要加上求的直徑g.fillOval(balls[i].x, balls[i].y, 20, 20); balls[i].left=!balls[i].left; } balls[i].y=balls[i].up? balls[i].y-5 : balls[i].y+5 ; if(balls[i].y<=0 || balls[i].y+20>=this.getHeight()){ balls[i].up=!balls[i].up; } //方法2: // balls[i].x+=5;//球被畫死了 // balls[i].y+=5; g.fillOval(balls[i].x, balls[i].y, 20, 20);//畫實心球,直徑20,20 } } public void actionPerformed(ActionEvent e) {?//監聽執行緒,每delay時間間隔畫一次球 repaint(); } public void focusGained(FocusEvent e) {//監聽焦點,點選畫布時停止 timer.stop(); } public void focusLost(FocusEvent e) {//監聽焦點,點選其他重新啟動,如微調按鈕編輯框 timer.restart(); } }

結果顯示:
這裡寫圖片描述