1. 程式人生 > >JAVA 多線程制作大球吃小球 一、實現球的自動生成及運動 生產消費模型

JAVA 多線程制作大球吃小球 一、實現球的自動生成及運動 生產消費模型

生產者 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 多線程制作大球吃小球 一、實現球的自動生成及運動 生產消費模型