java實(shí)現(xiàn)小球碰撞功能
本文實(shí)例為大家分享了java實(shí)現(xiàn)小球碰撞的具體代碼,供大家參考,具體內(nèi)容如下
這次我們做一個(gè)小球的碰撞的游戲,規(guī)則是:按下添加按鈕,窗口的中心部分會(huì)產(chǎn)生一個(gè)小球(剛開(kāi)始默認(rèn)為黑色),四個(gè)方向隨機(jī)產(chǎn)生,發(fā)射小球,再次按下即產(chǎn)生兩個(gè)小球。當(dāng)小球碰到窗體邊緣的時(shí)候會(huì)產(chǎn)生反彈,當(dāng)兩個(gè)小球接觸時(shí)會(huì)產(chǎn)生碰撞,雙方交換速度,向相反方向移動(dòng)。我們可以選擇相應(yīng)的顏色來(lái)改變下一個(gè)發(fā)射的小球顏色。當(dāng)按下清除可以清除屏幕上的小球,當(dāng)按下添加則會(huì)繼續(xù)產(chǎn)生小球。最后我們還添加了自動(dòng)產(chǎn)生小球的功能,按下開(kāi)關(guān),在屏幕中間會(huì)定時(shí)產(chǎn)生小球。接下來(lái),我們來(lái)展示代碼部分。
public class Jframe { private Ball[] arrayball = new Ball[100]; public static void main(String[] args) { Jframe frame = new Jframe(); frame.showUI(); } public void showUI() { javax.swing.JFrame jf = new javax.swing.JFrame(); jf.setSize(1000, 1000); jf.getContentPane().setBackground(Color.WHITE); jf.setTitle("小球"); jf.setDefaultCloseOperation(3); // 設(shè)置居中顯示 jf.setLocationRelativeTo(null); JPanel jp1 =new JPanel(); JButton jb1 = new JButton("添加"); jp1.add(jb1); // jb1.setBounds(100,50, 40, 20); JButton jb2 = new JButton("暫停"); jp1.add(jb2); // jb1.setBounds(200,50, 40, 20); JButton jb3 = new JButton("清除"); jp1.add(jb3); // jb1.setBounds(300,50, 40, 20); JButton jb4 = new JButton("自動(dòng)添加"); jp1.add(jb4); jf.add(jp1,BorderLayout.NORTH); Mouse mouse = new Mouse(); Color[] color = {Color.RED,Color.BLUE,Color.BLACK,Color.GREEN,Color.YELLOW}; for(int i=0;i<color.length;i++){ JButton jbu = new JButton(); jbu.setBackground(color[i]); jbu.setPreferredSize(new Dimension(30, 30)); jp1.add(jbu); jbu.addActionListener(mouse); } jb1.addActionListener(mouse); jb2.addActionListener(mouse); jb3.addActionListener(mouse); jb4.addActionListener(mouse); jf.addMouseListener(mouse); jf.addMouseMotionListener(mouse); BallJpanel cp = new BallJpanel(); cp.setBackground(Color.WHITE); jf.add(cp,BorderLayout.CENTER); jf.setVisible(true); Graphics g = cp.getGraphics(); mouse.setcp(cp); mouse.setg(g); mouse.setarrayball(arrayball); mouse.setmouse(mouse); cp.setarrayball(arrayball); } }
這是窗體的基本配置,采用邊框布局,上方放置按鈕,中間是畫(huà)布。我們?yōu)榘粹o添加了動(dòng)作監(jiān)聽(tīng)器,并使用了一系列的方法來(lái)把對(duì)象傳遞到其他類(lèi)中。
public class Ball { public int size = 90; // 小球的直徑 public int x = 500; // 小球所在的x坐標(biāo) public int y = 500; // 小球所在的y坐標(biāo) public int vx = 5; public int vy = 5; public BallJpanel cp; public Color color = Color.BLACK; public int max_x, max_y, Min_x, Min_y; private Ball[] arrayball; public void setcp(BallJpanel cp) { this.cp = cp; } public void setarrayball(Ball[] arrayball) { this.arrayball = arrayball; } public void setX(int x) { this.x = x; } public int getX() { return x; } public void setY(int y) { this.y = y; } public int setY() { return y; } public Ball(int x, int y, int vx, int vy, Color color) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.color = color; } public void ballMove(Graphics g) { x += vx; y += vy; max_y = cp.getHeight(); max_x = cp.getWidth(); if (x <= size / 2) { x = size / 2; vx = -vx; } if (y <= size / 2) { y = size / 2; vy = -vy; } if (x + size / 2 >= max_x) { x = max_x - size / 2; vx = -vx; } if (y + size / 2 >= max_y) { y = max_y - size / 2; vy = -vy; } for (int i = 0; i < arrayball.length; i++) { if (arrayball[i] == null) break; Ball ball = arrayball[i]; if (this.equals(ball)) continue; if ((ball.x - this.x) * (ball.x - this.x) + (ball.y - this.y) * (ball.y - this.y) <= size * size) { int tempvx = this.vx; int tempvy = this.vy; this.vx = ball.vx; this.vy = ball.vy; ball.vx = tempvx; ball.vy = tempvy; while ((ball.x - this.x) * (ball.x - this.x) + (ball.y - this.y) * (ball.y - this.y) <= size * size) { this.x += this.vx; this.y += this.vy; System.out.println("等待"); } } } } }
考慮到這是一個(gè)小球的運(yùn)動(dòng)系統(tǒng),我們?yōu)樾∏驅(qū)懥艘粋€(gè)類(lèi),添加小球的時(shí)候,會(huì)創(chuàng)建小球?qū)ο螅⑹蛊浍@得位置,顏色,速度等參數(shù),并將其存入數(shù)組。小球的方法就是運(yùn)動(dòng),每當(dāng)執(zhí)行ballMove方法,便會(huì)為小球修改位置坐標(biāo)(基于其速度),再判斷是否撞擊邊框,以及判斷是否和別的小球有坐標(biāo)重疊,如果有重疊,則跑一個(gè)循環(huán),修改位置坐標(biāo),使其分離。Ball這部分代碼和監(jiān)聽(tīng)器中的方法有所聯(lián)系,我們接下來(lái)介紹監(jiān)聽(tīng)器的方法。
public class Mouse implements MouseMotionListener, MouseListener, ActionListener { private Graphics g; private BallJpanel cp; private Ball[] arrayball; private int index = 0; private int x; private int y; private int vx; private int vy; private int random=1; private Color color=Color.black; private ThreadBall tb; private Mouse mouse; public int selfFlag=0; public void setmouse(Mouse mouse) { this.mouse= mouse; } public void setarrayball(Ball[] arrayball) { this.arrayball = arrayball; } public void setg(Graphics g) { this.g = g; } public void setcp(BallJpanel cp) { this.cp = cp; } public void actionPerformed(ActionEvent e) { if ("添加".equals(e.getActionCommand())) { System.out.println("添加"); if (tb == null) { // 創(chuàng)建線程對(duì)象 tb = new ThreadBall(); tb.setcp(cp); tb.setarrayball(arrayball); tb.setg(g); tb.start(); tb.setmouse(mouse); } tb.stopFlag=0; addBall(); } if ("暫停".equals(e.getActionCommand())) { if(tb!=null) { if(tb.stopFlag==0) { tb.stopFlag=1; System.out.println("暫停"); } else { tb.stopFlag=0; System.out.println("開(kāi)始"); } } } if ("清除".equals(e.getActionCommand())) { tb.stopFlag=1; cp.paint1(g); index=0; System.out.println("清除"); } if ("自動(dòng)添加".equals(e.getActionCommand())){ if(selfFlag==0) {selfFlag=1;System.out.println("自動(dòng)添加打開(kāi)");} else {selfFlag=0;System.out.println("自動(dòng)添加關(guān)閉");} } if("".equals(e.getActionCommand())){ JButton jbu=(JButton)e.getSource(); color=jbu.getBackground(); g.setColor(color); } } public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void addBall() { x = 500; y = 500; random=1+(int)(Math.random()*4); switch(random) { case 1: vx=5; vy=5; break; case 2: vx=-5; vy=-5; break; case 3: vx=5; vy=-5; break; case 4: vx=-5; vy=5; break; } Ball ball = new Ball(x, y,vx , vy, color); arrayball[index++] = ball; } }
監(jiān)聽(tīng)器中,我們?cè)O(shè)置了一系列參數(shù)來(lái)控制一些方法的開(kāi)啟和關(guān)閉,以及寫(xiě)了添加小球的方法,為其賦初值,隨機(jī)一個(gè)初始發(fā)射方向。這段代碼我們用到了線程。線程的使用分為兩步,創(chuàng)建線程對(duì)象并start線程。
public class ThreadBall extends Thread { private Graphics g; private BallJpanel cp; private Ball[] arrayball; public int stopFlag=0; private int add=0; private Mouse mouse; public void setmouse(Mouse mouse) { this.mouse=mouse; } public void setcp(BallJpanel cp) { this.cp = cp; } public void setg(Graphics g) { this.g=g; } public void setarrayball(Ball[] arrayball) { this.arrayball = arrayball; } /** * 啟動(dòng)線程執(zhí)行的方法 */ public void run() { while (true) { if(stopFlag==0) { for (int i = 0; i < arrayball.length; i++) { if(arrayball[i]==null) break; Ball ball = arrayball[i]; ball.setarrayball(arrayball); ball.setcp(cp); ball.ballMove(g); } cp.paint(g); add++; if(add==5000) add=0; if(add%50==0&&mouse.selfFlag==1) mouse.addBall(); } try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } }
以上是線程的屬性和方法,此類(lèi)繼承Thread并重寫(xiě)了run方法。run方法的思路是循環(huán)調(diào)用ballMove方法修改小球坐標(biāo),并調(diào)用paint方法更新顯示,我們加入了一個(gè)延時(shí)函數(shù),來(lái)控制調(diào)用的頻率。
public class BallJpanel extends JPanel { private Ball[] arrayball; public void setarrayball(Ball[] arrayball) { this.arrayball=arrayball; } public void paint(Graphics g) { super.paint(g); for(int i=0;i<arrayball.length;i++) { if(arrayball[i]==null) { break; } Ball ball=arrayball[i]; g.setColor(ball.color); g.fillOval(ball.x-ball.size/2, ball.y-ball.size/2, ball.size, ball.size); } } public void paint1(Graphics g) { super.paint(g); for(int i=0;i<arrayball.length;i++) { if(arrayball[i]==null) { break; } arrayball[i]=null; } } }
BallJpanel類(lèi)寫(xiě)的是畫(huà)布,及小球的運(yùn)動(dòng)區(qū)域,畫(huà)筆也是從其對(duì)象cp上獲得。類(lèi)里用paint寫(xiě)畫(huà)面的重繪方法(包括畫(huà)板小球的重繪),paint1用來(lái)清空畫(huà)布及數(shù)組。
以上便是java小球運(yùn)動(dòng)的全部代碼,我們來(lái)看一下效果。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot整合vue實(shí)現(xiàn)上傳下載文件
這篇文章主要為大家詳細(xì)介紹了springboot整合vue實(shí)現(xiàn)上傳下載文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Windows系統(tǒng)下Java連接SQL Server的方法簡(jiǎn)介
這篇文章主要介紹了Windows系統(tǒng)下Java連接SQL Server的方法,分別是JDBC和JTDS的相關(guān)使用,需要的朋友可以參考下2015-09-09解決IDEA開(kāi)發(fā)工具右側(cè)沒(méi)有Maven工具欄的問(wèn)題
這篇文章主要給大家解決了IDEA開(kāi)發(fā)工具右側(cè)沒(méi)有Maven工具欄的問(wèn)題,文中有詳細(xì)的解決步驟,如果有遇到一樣問(wèn)題的小伙伴,可以參考閱讀本文2023-09-09java并發(fā)編程JUC CountDownLatch線程同步
這篇文章主要介紹CountDownLatch是什么、CountDownLatch 如何工作、CountDownLatch 的代碼例子來(lái)展開(kāi)對(duì)java并發(fā)編程JUC CountDownLatch線程同步,需要的朋友可以參考下面文章內(nèi)容2021-09-09詳解mybatis collection標(biāo)簽一對(duì)多的使用
這篇文章主要介紹了mybatis collection標(biāo)簽一對(duì)多的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06