2017-04-04 147 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