Java之小球碰撞反弹
本次我們主要實現了三個功能:
1,小球碰壁反彈、小球相互碰撞反彈。
2,使用緩沖繪圖解決閃屏問題。
3,增加暫停按鈕,實現界面動、停控制。
一,創建一個類ShowUI實現窗體界面
二,創建小球類Ball
1,在創建完Ball類之后,在界面類ShowUI中創建一個全局用來保存所有小球的動態數組balls。
之所以將ArrayList向上轉型為List,是因為這樣寫體現了面向接口編程的思想。List是一個接口,ArrayList是實現List接口的一個具體實現類,能夠降低程序的耦合度,當我們發現代碼使用的集合不正確應該使用的是LinkedList時,只需要修改以下一行代碼就可:
List<Ball> balls = new LinkedList<>();因為之后所有的操作都是針對List這個接口定義的方法,而與實現類的獨特方法無關,如果我們一開始直接使用ArrayList類型而不向上轉型,那么之后如果涉及到ArrayList類獨特的方法時需要修改的地方比較多,不便于程序的維護。
2,在Ball類中定義每個小球需要的屬性以及方法
關于運動小球的屬性有:小球外接圓左上角坐標lx、ly,小球速度vx、vy,小球直徑R、小球顏色color,小球球心rx、ry,畫筆參數g。
關于運動小球的方法有:
2.1構造方法傳參,隨機生成小球位置、速度、顏色。
2.2判斷小球是否碰到邊界。
//判斷小球是否碰到邊界 碰撞了返回true 沒碰撞返回falsepublic Boolean isknockbound() {//小球球心坐標rx=lx+R/2;ry=ly+R/2;//是否碰到邊界 因為緩沖畫布不能遮擋鼠標 故下方距離應該往上提arguemwntBoolean b1=((rx)<=(R/2))||((rx)>=(SCREENX-R/2))||((ry)<=(R/2))||((ry)>=(SCREENY-R/2-arguement));if(b1) {return true;}return false;}2.3判斷小球之間是否相互碰撞。
小球之間的相互碰撞和碰壁略有不同,碰壁對于每個邊界只有一種情況,但是對于球之間的碰撞有可能該球和左邊的球碰也有可能是和右邊的球碰,因此碰完速度改變的方向也不同,在該方法中直接改變小球速度。
2.4小球移動方法。
小球的基本移動方法是:位置=位置+速度。
但小球發生了碰撞之后移動方法要發生變化,要對小球的速度進行操作。當與邊界發生碰撞時速度直接取反,當小球之間發生碰撞時直接在isknockballs方法中直接對速度進行改變。
//如果小球碰到邊界 則反彈 速度取反if(isknockbound()) {vx=-vx;vy=-vy;}//如果小球之間相互碰撞 按情況改變速度 在isknockballs()方法中改變else if(isknockballs()) {}2.5畫小球方法。
將畫筆的顏色指定為生成該小球對象時的顏色,在指定位置畫出小球。
三,在線程中重寫run()方法,使用緩存畫圖
1,使用構造方法,將小球參數傳入,使的全局使用的參數一致。
2,重寫run()方法,將畫的操作全部放在緩存中,每隔10ms在緩存中將所有的小球取出移動、畫完之后,再在界面中展示出來,這樣可以解決閃屏問題。
//重寫run方法public void run() {//創建緩存BufferedImage buffer = new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);//獲取緩存上的畫布Graphics bgriphics = buffer.getGraphics();//使線程不終止while(true) {//清屏bgriphics.setColor(Color.BLACK);bgriphics.fillRect(0, 0 , 800,600);bgriphics.setColor(color);for(int i=0;i<balls.size();i++) {Ball ball=(Ball) balls.get(i);ball.move();ball.draw(bgriphics); }//顯示緩存 在界面上 將所有緩存上用bufferGraphics畫完的圖形只用一次用之前界面上的畫筆g展現處理啊g.drawImage(buffer, 0, 65,null);//0,65為圖形左上角坐標 65為了不遮擋鼠標//每過10ms利用緩存將數組中全部的小球移動+畫出+清屏try{Thread.sleep(10);}catch(Exception ef) {};}}四,創建監聽,實現暫停功能
1,在線程類Mythread中定義一個Boolean類型的變量isgo,根據isgo的狀態判斷是否執行清屏、畫等操作,而不是讓線程終止,因為線程一旦終止便無法再開啟。同時加入IsGo()方法,每調用一次改變一次isgo狀態,這樣就能夠實現暫停和開始的切換。
2,創建監聽類MyListener,對鼠標動作進行監聽
2.1,界面添加按鈕綁定監聽
2.2,在ShowUI類中創建線程對象thread,將線程對象傳入MyListener類中,鼠標每點擊一次,線程對象thread都調用一次MyThread中的IsGo()方法,改變isgo狀態,同時通過count計數取余改變按鈕上的字。
//創建線程 MyThread mythread=new MyThread(g,color,balls);//創建監聽器對象MyListener mylistener=new MyListener(jbutton,mythread); package com.yzd0126.BallsRebound;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JButton;public class MyListener implements ActionListener{private int count=0;//取余 用來切換按鈕上的字JButton jbutton;MyThread mythread;public MyListener(JButton jbutton,MyThread mythread) {this.jbutton=jbutton;this.mythread=mythread;}public void actionPerformed(ActionEvent e) {//每按下一次按鈕 就要調用線程的IsGo方法 切換isgo狀態 判斷是否執行畫操作mythread.IsGo();//count計數 取余切換按鈕上的字符count++;if(count%2==1) {jbutton.setText("stop");}else{jbutton.setText("start");}}}五,啟動線程,實現功能
在ShowUI類中一次性添加20個小球,然后啟動線程運行程序。
總結
以上是生活随笔為你收集整理的Java之小球碰撞反弹的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java魔兽争霸_GitHub - mz
- 下一篇: Android性能分析工具“TraceV