JAVA 多線程制作大球吃小球 一、實現球的自動生成及運動 生產消費模型
阿新 • • 發佈:2018-07-15
生產者 tar thread ive 聯系 print random 線程 ram
/*文章中用到的代碼只是一部分,需要源碼的可通過郵箱聯系我 [email protected]*/
前幾天用多線程實現了創建小球並移動,想到大魚吃小魚,便突發奇想要寫一個大球吃小球。首先第一步自然是先把界面弄好啦
1 public class BallUI extends JPanel { 2 3 private ArrayList<Ball> li = new ArrayList<Ball>(); 4 5 public static void main(String[] args) { 6 BallUI bu = new BallUI();7 bu.UI(); 8 } 9 10 public void UI() { 11 JFrame jf = new JFrame(); 12 jf.setLocationRelativeTo(null); 13 jf.setResizable(false); 14 jf.setSize(700, 700); 15 this.setSize(jf.getWidth(),jf.getHeight()); 16 jf.setTitle("大球吃小球"); 17 18 this.setPreferredSize(new Dimension(jf.getWidth(), jf.getHeight())); 19 jf.add(this); 20 21 22 23 jf.setVisible(true); 24 } 25 26 27 }
界面寫好後想想要怎麽做呢?既然是大球吃小球還利用線程,那肯定需要一個隊列,然後呢?既然要隊列,那隊列裏存什麽?肯定存小球啊,那自然要創建一個小球類了,那小球有什麽屬性呢?坐標、移動速度、大小、顏色,除了這些在創建時還需不需要傳些什麽參數呢?既然傳了顏色,那肯定需要畫小球,我們在哪畫?是調用方法還是在線程中獲取小球屬性然後畫?我覺得調用方法會更好,所以我們要在這裏傳入一個畫布。同樣在後面我們還需要檢測小球是否碰撞,因此我們還需要傳入一個隊列。下面便是Ball類的構造了
public class Ball { private int size; private int x; private int y; private int speedX; private int speedY; private Color c; private JPanel jf; private ArrayList<Ball> li; public Ball(int size, int x, int y, int speedX, int speedY, Color c, JPanel jf, ArrayList<Ball> li) { this.size = size; this.x = x; this.y = y; this.speedX = speedX; this.speedY = speedY; this.c = c; this.jf = jf; this.li = li; } //畫球 public void draw(Graphics g) { } //移動球 public void move() { } //清除上次留下的痕跡 public void clear(Graphics g) { } //碰撞檢測 public void crash(Graphics g) { } }
創建好小球類後,我們便需要線程來創建小球、改變小球,那這裏也有一個問題,我們是用一個線程還是兩個還是多個?這樣看,如果只用一個線程,那麽我們每次改變小球得在創建了一個小球後進行,如果小球數量少還沒問題,但是當小球數量多了之後,每便利一次就會用上一段時間,那麽肯定會有延時,所以我們需要把這裏分成兩個線程,一個線程創建小球,一個線程改變小球。這裏其實就利用了生產者消費者模型: 生產者負責生產數據並存入緩沖區,消費者從緩沖區中取出數據並且處理並輸出。
1 public class ThreadBall extends Thread { 2 3 private ArrayList<Ball> li; 4 private JPanel jp; 5 private Graphics g; 6 7 public ThreadBall(ArrayList<Ball> li,JPanel jp) { 8 this.li = li; 9 this.jp=jp; 10 } 11 12 public void run() { 13 g=jp.getGraphics(); 14 while(true) { 15 for(int i=0;i<li.size();i++) { 16 Ball ball=li.get(i); 17 ball.clear(g); 18 ball.crash(g); 19 ball.move(); 20 ball.draw(g); 21 } 22 try { 23 Thread.sleep(100); 24 } catch (InterruptedException e) { 25 e.printStackTrace(); 26 } 27 } 28 } 29 30 }
public class BallLis extends Thread { private ArrayList<Ball> li = new ArrayList<Ball>(); private JPanel jp; public BallLis(ArrayList<Ball> li,JPanel jp) { this.li = li; this.jp = jp; } public void run() { while (true) { int size = new Random().nextInt(30) + 10; int x = new Random().nextInt(jp.getWidth()); int y = 0; int speedX = new Random().nextInt(10) + 10; int speedY = new Random().nextInt(10) + 5; Color c=new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256)); Ball bl=new Ball(size,x,y,speedX,speedY,c,jp,li); li.add(bl); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
創建好線程後肯定需要在BallUI類中創建對象啦
BallLis ball = new BallLis(li,this); ball.start(); ThreadBall tb=new ThreadBall(li,this); tb.start();
那麽,剩下的任務就是實現小球類中的方法了,就留給你們去實現了。
JAVA 多線程制作大球吃小球 一、實現球的自動生成及運動 生產消費模型