2017-04-04 149 views
1

美好的一天,我是StackOverflow和Java編程的新手。我目前有一個需要多線程的學校項目,我只需要你的建議就如何修復我的代碼。我花了太多時間尋找如何使用線程創建移動多個圖像的答案。我知道我快要找到解決方案了,但由於提交內容正在迅速接近,所以我沒有時間了。我相信如果我以某種方式尋求Java方面的更好的幫助,我會更有效率。在Java中的多線程應用中移動圖像/形狀

非常感謝提前。

下面是我目前的代碼,看起來圖像在移動時閃爍。

// Bounce.java 

import javax.swing.JFrame; 
public class Bounce { 

    public static void main(String args[]) { 
     myBall s = new myBall(10, 20, 2, 2); 
     myBall s1 = new myBall(100, 10, 2, 2); 
     myBall s2 = new myBall(40, 10, 2, 2); 
     JFrame f = new JFrame(); 
     f.add(s); 
     f.add(s1); 
     f.add(s2); 
     f.setVisible(true); 
     f.setSize(600, 400); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setTitle("Moving Ball"); 
    } 
} 

下一個代碼位於單獨的文件中。

// myBall.java 

import java.awt.*; 
import java.awt.geom.Ellipse2D;  
import javax.swing.*; 

public class myBall extends JPanel implements Runnable { 
    private Thread animator; 
    int x = 0, y = 0, velX = 2, velY = 2; 
    Timer t; 

    public myBall(int x, int y, int velX, int velY) { 
     JFrame jf = new JFrame(); 
     jf.setSize(600,400); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jf.add(this); 
     jf.setVisible(true); 

     this.x = (int)(Math.random() * 560); 
     this.y = (int)(Math.random() * 360); 
     this.velX = velX; 
     this.velY = velY; 
    } 

    @Override 
    public void addNotify() { 
     super.addNotify(); 
     animator = new Thread(this); 
     animator.start(); 

    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40); 
     g2.fill(ellipse);  
    } 

    public void cycle() { 
     if(x < 0 || x > 560) { 
      velX = -velX; 
     } 
     if(y < 0 || y > 360) { 
      velY = -velY; 
     } 
     x += velX; 
     y += velY; 
     System.out.println(x); 
    } 

    @Override 
    public void run() { 
     while(true) { 
      for (int i = 0; i < 600; i++) { 
       cycle(); 
       repaint(); 

       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) { 
        System.out.println("interrupted"); 
       } 
      } 
     } 


    } 

}  
+0

首先要知道的是,每次你創建一個新球的時候,你還創建一個新的JFrame。這就是爲什麼你有3幀運行。你的gui課程打破了單一責任原則 - 它控制着圖形用戶界面,並創建新的球。我會創建一個桂類,然後創建一個球類。 –

回答

0

你在這裏。我通常不這樣做,但是你問得很好,你的代碼很乾淨,所以我認爲你在這方面做了很多工作。

public class Start { 

    public static void main(String args[]) { 
     JFrame f = new JFrame(); 
     Gui gui = new Gui(); 
     gui.addBalls(); 
     f.add(gui); 

     f.setSize(600, 400); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setTitle("Moving Ball"); 
     f.setVisible(true); 
    } 
} 

類GUI:

public class Gui extends JPanel implements Runnable { 
    private Thread animator; 
    int x = 0, y = 0, velX = 2, velY = 2; 
    Timer t; 

    ArrayList<myBall> myBalls = new ArrayList<>(); 

    @Override 
    public void addNotify() { 
     super.addNotify(); 
     animator = new Thread(this); 
     animator.start(); 

    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 

     for (myBall ball: myBalls) { 
      int x = ball.getX(); 
      int y = ball.getY(); 
      Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40); 
      g2.fill(ellipse); 
     } 
    } 

    public void cycle() { 
     for (myBall ball: myBalls) { 
      int x = ball.getX(); 
      int y = ball.getY(); 

      if(x < 0 || x > 560) { 
       ball.reverseX(); 
      } 
      if(y < 0 || y > 360) { 
       ball.reverseY(); 
      } 

      ball.move(); 
      System.out.println(x); 
     } 
    } 

    @Override 
    public void run() { 
     while(true) { 
      for (int i = 0; i < 600; i++) { 
       cycle(); 
       repaint(); 

       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) { 
        System.out.println("interrupted"); 
       } 
      } 
     } 
    } 

    public void addBalls() { 
     for (int i = 0; i < 4; i++) { 
      int x = (int)(Math.random() * 560); 
      int y = (int)(Math.random() * 360); 
      int velX = -5; 
      int velY = 5; 
      myBalls.add(new myBall(x, y, velX, velY)); 
     } 
    } 
} 

類球:

public class myBall { 

    int x; 
    int y; 
    int velX; 
    int velY; 


    public myBall(int x, int y, int velX, int velY) { 
     this.x = (int)(Math.random() * 560); 
     this.y = (int)(Math.random() * 360); 
     this.velX = velX; 
     this.velY = velY; 
    } 

    public void move() { 
     x+=velX; 
     y+=velY; 

    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    public void reverseX() { 
     velX = -velX; 
    } 

    public void reverseY() { 
     velY = -velY; 
    } 
} 
+0

太棒了!非常感謝你做的這些!完美的作品。我實際上有Traffic Light Simulation項目,我只想了解線程和移動對象是如何工作的,這樣我就可以學習自己做的實際項目。真的很想學習Java,你真的拯救了我的一天。感謝堆! =) – newProgramm3r