2016-06-12 6 views
-1

kollidieren Ich habe ein einfaches Ball-Bounce-Programm, in dem die Bälle von den Seiten meines Rahmens fein prallen. Ich versuchte, den Kugeln einen Weg zu geben, sich gegenseitig abzuprallen, indem ich prüfte, ob sich zwei Bälle berühren, indem ich um jeden Ball ein Rechteck kreiere und überprüfe, ob ein anderer Ball das Rechteck schneidet und ob sie ihre Geschwindigkeiten ändern. Es funktioniert gut, wenn ich den Code ** hinzufüge und es gibt nur einen Ball, aber sobald ich mehr als einen hinzufüge, beginnen sie sich zusammen zu bewegen, bis sie aus dem Rahmen stecken. Ich habe keine Ahnung, was falsch ist.Verursacht Kugeln in einem einfachen Ball Bounce-Programm

import javax.swing.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.event.*; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D; 
import java.util.ArrayList; 

public class BallBounceFrame 
{ 

public static void main(String[] args) 
{ 
    new BallBounceFrame(); 
} 

JFrame frame; 
JPanel controlPanel; 
JButton stop, start; 
JSpinner ballNum; 
Timer t; 
BallCanvas c; 
static int WIDTH = 500; 
static int HEIGHT = 500; 

public BallBounceFrame() 
{ 
    frame = new JFrame("Bouncing Balls"); 
    frame.setSize(WIDTH, HEIGHT); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLocationRelativeTo(null); 
    frame.setResizable(false); 
    c = new BallCanvas(0, 20); 
    frame.add(c, BorderLayout.CENTER); 
    addPanels(); 
    frame.setVisible(true); 
    t = new Timer(10, new animator()); 
    t.start(); 
} 

public void addPanels() 
{ 
    controlPanel = new JPanel(); 
     start = new JButton("Start"); 
     start.addActionListener(new buttonControlListener()); 
     controlPanel.add(start); 

     stop = new JButton("Stop"); 
     stop.addActionListener(new buttonControlListener()); 
     controlPanel.add(stop); 

     ballNum = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); 
     ballNum.addChangeListener(new spinnerControlListener()); 
     controlPanel.add(ballNum); 

    frame.add(controlPanel, BorderLayout.NORTH); 
} 

class BallCanvas extends JPanel 
{ 

    private static final long serialVersionUID = 1L; 
    ArrayList<Ball> balls = new ArrayList<Ball>(); 

    public BallCanvas(int ballNum, int ballSize) 
    { 
     setBalls(ballNum, ballSize); 
    } 

    public void paint(Graphics g) 
    { 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(Color.RED); 
     for(Ball b : balls) 
     { 
      b.move(this.getSize()); 
      g2.fill(b); 
     } 
    } 

    public void animate() 
    { 
     while(true) 
     { 
      try 
      { 
       frame.repaint(); 
       Thread.sleep(10); 
      } 
      catch(Exception e) 
      { 
       System.out.println(e); 
      } 
     } 
    } 
    public void setBalls(int ballNum, int ballSize) 
    { 
     balls.clear(); 
     for(int i = 0; i < ballNum; i++) 
     { 
      balls.add(new Ball(ballSize, balls)); 
     } 
    } 
} 

class Ball extends Ellipse2D.Float 
{ 
    private int xVel, yVel; 
    private int size; 
    private ArrayList<Ball> balls; 

    public Ball(int size, ArrayList<Ball> balls) 
    { 
     super((int) (Math.random() * (BallBounceFrame.WIDTH /(1.1)) + 1), (int) (Math.random() * (BallBounceFrame.WIDTH /(1.3)) + 7), size, size); 
     this.size = size; 
     this.xVel = (int) (Math.random() * 7 + 2); 
     this.yVel = (int) (Math.random() * 7 + 2); 
     this.balls = balls; 
    } 

    public void move(Dimension panelSize) 
    { 
     **Rectangle2D r = new Rectangle2D.Float(super.x, super.y, size, size); 
     for(Ball b : balls) 
     { 
      if(b != this && b.intersects(r)); 
      { 
       int tempx = xVel; 
       int tempy = yVel; 
       xVel = b.xVel; 
       yVel = b.yVel; 
       b.xVel = tempx; 
       b.yVel = tempy; 
       break; 
      } 
     }** 

     if(super.x < 0 || super.x > panelSize.getWidth() - size) xVel *= -1; 
     if(super.y < 5 || super.y > panelSize.getHeight() - size) yVel *= -1; 
     super.x += xVel; 
     super.y += yVel; 
    } 
} 
class animator implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     frame.repaint(); 
    } 
} 

class buttonControlListener implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     if (e.getSource() == stop) t.stop(); 

     if(e.getSource() == start) t.start(); 
    } 
} 

class spinnerControlListener implements ChangeListener 
{ 
    public void stateChanged(ChangeEvent e) { 
     if(e.getSource() == ballNum) 
     { 
      int balls = (int) ballNum.getValue(); 
      c.setBalls(balls, 20); 
      frame.revalidate(); 
      frame.repaint(); 
     } 
    } 

} 
} 

Antwort

-1

Ihr Code hat eine einzige ArrayList<Ball> innerhalb BallCanvas - der ‚Master‘ Liste - und dann jedes Ball hat seine eigene ArrayList<Ball> die Liste der Bälle, die die bis zu diesem Zeitpunkt erstellt wurden bis. Ball verwendet dann nur die eigene ArrayList<Ball> innerhalb der move() Methode.

Darf ich vorschlagen, dass Sie nur einen haben, Master ArrayList<Ball> innerhalb BallCanvas? Anstatt es an den Ball Konstruktor zu übergeben, übergeben Sie es an den move() Aufruf.