2016-09-20 4 views
1

Ich mache eine Java-App (für Übung), wo es ein Panel und 2 Tasten sein muss.Ändern Ball Farbe beim Zusammenstoß

  1. Jedes Mal, wenn Sie den Startknopf drücken, muss ein Ball angezeigt werden und er bewegt sich basierend auf dem Faden. Der Benutzer kann bis zu 10 unabhängige Bälle anzeigen.
  2. Durch Drücken der Stopptaste muss 1 Kugel jedes Mal entfernt werden, wenn die Stopptaste gedrückt wird (z. B. wenn 4 Kugeln vorhanden sind, muss der Benutzer 4 Mal Stopptaste drücken, um alle Kugeln unabhängig voneinander zu entfernen)
  3. Alle die x- und y-Koordinaten der Kugeln müssen in einer Matrix gespeichert werden
  4. Wenn 1 oder mehrere Kugel (n) sind miteinander kollidieren, werden nur die kollidierenden Kugeln müssen Farbe zu blau

Ok von rot ändern Ich bin damit fast fertig (von Punkt 1 bis 4), aber hier kommt mein Problem. Wenn ein Ball mit einem anderen Ball kollidiert, ändert der Code nicht die Farben der kollidierenden Bälle in Blau, sondern ändert alle Bälle von rot nach blau. Ich weiß, dass mein Fehler bei der new Balls().setColor(Color.Blue) liegt, aber ich habe keine Ahnung, wie man nur die kollidierenden Bälle auswechselt.

Unten folgt ein Screenshot der Java App und des Codes. Kann mir jemand mit diesen Kopfschmerzen helfen?

Printscreen: enter image description here

Quellcode:

import java.awt.Color;    
import java.awt.Dimension;  
import java.awt.FlowLayout; 
import java.awt.Graphics;  
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JButton;  
import javax.swing.JFrame;  
import javax.swing.JLabel; 
import javax.swing.JPanel;` 


public class BouncingBalls extends JPanel implements ActionListener { 

protected List<Ball> balls = new ArrayList<Ball>(10); 
private final Container container; 
private final DrawCanvas canvas; 
private int canvasWidth; 
private int canvasHeight; 
public JButton start, stop; 
int [][] coords= new int[11][2]; 
int ammountOfBalls = 0; 
static Color clr= Color.RED; 


public static int random(int maxRange) { 
    return (int) Math.round((Math.random() * maxRange)); 
} 

public BouncingBalls(int width, int height) { 
    setLayout(new FlowLayout()); 
    start= new JButton("start"); 
    start.addActionListener(this); 
    stop= new JButton("stop"); 
    stop.addActionListener(this); 
    add(start); 
    add(stop); 
    add(new JLabel("")); 
    container = new Container(); 
    canvasWidth = width; 
    canvasHeight = height; 
    canvas = new DrawCanvas(); 
    this.setLayout(new FlowLayout()); 
    this.add(canvas); 
    start(); 

} 

public void start() { 

    Thread t = new Thread() { 
     @Override 
     public void run() { 

      while (true) { 

       update(); 
       getPositions(); 
       collisionDetection(); 
       repaint(); 
       try { 
        Thread.sleep(30); 
       } catch (InterruptedException e) { 
       } 
      } 
     } 

     private void collisionDetection() { 
      // The algorithm that detects collision 
      for(int i=0;i<ammountOfBalls;i++){ 
      for(int j=i+1; j<ammountOfBalls; j++){ 
        if(collisionMethod(i,j)){ // my collision method 
         //HOW DO I CHANGE ONLY THE COLLIDING BALLS COLOR HERE???? 
        new Ball().setColor(Color.BLUE); // this line here changes the color of all the balls on the panel 
         System.out.println("Its a hit"); 
        } 
       } 

      } 

     } 

     private void getPositions() { 
      int row=0; 
      for (Ball ball : balls) { 
      int x =ball.getXPosition(); 
      int y =ball.getYPosition(); 
      coords[row][0]=x; 
      coords[row][1]=y; 
      row++; 
      } 

     } 

     private boolean collisionMethod(int i, int j) { 
      float xd = coords[i][0]-coords[j][0]; 
      float yd=coords[i][1]-coords[j][1]; 
      float radius= new Ball().ballRadius; 
      float sqrRadius= radius * radius; 
      float distSqr= (xd * xd) + (yd * yd); 

      if(distSqr <= sqrRadius) 
       return true; 

      return false; 
     } 
     }; 
    t.start(); 
} 

public void update() { 
    for (Ball ball : balls) { 
     ball.move(container); 
    } 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    if(e.getSource() == start){ 
     if(ammountOfBalls < 10){ 
      // to limit the ammount of balls to 10 
      balls.add(new Ball()); 
      ammountOfBalls++; 
     } 
    } 

    else if(e.getSource() == stop){ 
     if(ammountOfBalls > 0){ 
     ammountOfBalls --; 
     balls.remove(ammountOfBalls); 

    } 

    } 
} 

class DrawCanvas extends JPanel { 

    @Override 
    public void paintComponent(Graphics g) { 

     super.paintComponent(g); 
     container.draw(g); 
     for (Ball ball : balls) { 
      ball.draw(g); 
     } 
    } 
    @Override 
    public Dimension getPreferredSize() { 
     return (new Dimension(700, 400)); 
    } 
} 

public static void main(String[] args) { 
      JFrame f = new JFrame("Bouncing Balls"); 
      f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); 
      f.setPreferredSize(new Dimension(800,500)); 
      f.setContentPane(new BouncingBalls(800,800)); 
      f.pack(); 
      f.setVisible(true); 
    } 


public static class Ball { 

    public int random(int maxRange) { 
     return (int) Math.round(Math.random() * maxRange); 
    } 

int x = random(700); // method to get random coords for the x-value 
int y = random(400); // method to get random coords for the y-value ...... these are used to get random positions for the balls instead of only static 
int xMovement = 10; 
int yMovement = 10; 
int ballRadius = 20; 
int i = 0; 


public Color getColor(){ 
    return clr; 
} 
public Color setColor(Color color){ 
clr=color; 
return clr; 
} 
    public void draw(Graphics g) { 
     g.setColor(getColor()); 
     g.fillOval(x,y,ballRadius,ballRadius); 

    } 
    public int getXPosition(){ 
     return x; 
    } 
    public int getYPosition(){ 
     return y; 
    } 

    public void move(Container container) { 
     x += xMovement; 
     y += yMovement; 

     if (x - ballRadius < 0) { 
      xMovement = -xMovement; 
      x = ballRadius; 
     } 
     else if (x + ballRadius > 700) { 
      xMovement = -xMovement; 
      x = 700 - ballRadius; 
     } 

     if (y - ballRadius < 0) { 
      yMovement = -yMovement; 
      y = ballRadius; 
     } 
     else if (y + ballRadius > 400) { 
      yMovement = -yMovement; 
      y = 400 - ballRadius; 
     } 
    } 
} 



public static class Container { 
    private static final int hightPanel = 800; 
    private static final int widthPanel= 800; 

    public void draw(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, widthPanel, hightPanel); 
    } 
} 
} 

`

+1

Sie müssen identifizieren, welche Bälle tatsächlich kollidieren. Scheint wie eine seltsame Methode, mit den Koordinaten von Objekten umzugehen, die von ihrer visuellen Darstellung getrennt sind. – ChiefTwoPencils

+0

Siehe auch [Kollisionserkennung mit komplexen Formen] (http://stackoverflow.com/a/14575043/418556) für ein funktionierendes Beispiel. –

Antwort

5

Sie clr als statisches Feld Ihrer Anwendung definiert haben. Wenn Ihre Ball Klasse setColor() aufruft, ändern Sie den Wert von clr zu blau ... und dann alle Ball, die getColor() aufrufen, sehen, dass clr blau ist.

Lösung: Machen Sie clr nicht zu einem anwendungsweiten statischen Feld. Definieren Sie es in der Ball Klasse als ein nicht statisches Feld, so dass jede Ball ihre eigene Farbe hat.

+1

Gutes Auge. Ich denke, sie haben auch zusätzliche Probleme. Sie erzeugen einen neuen Ball bei einer Kollision und haben nicht die Bälle, die kollidieren; nur ihre Koordinaten. – ChiefTwoPencils

+0

vielen dank für die hilfe .. es funktioniert jetzt perfekt –