2016-09-20 52 views
1

私は、パネルと2つのボタンが必要なJavaアプリケーション(エクササイズ用)を作っています。衝突時にボールの色を変える

  1. スタートボタンを押すたびにボールが表示され、スレッドに基づいて移動する必要があります。ユーザーは最大10個の独立したボールを表示できます。
  2. 停止ボタンを押すと、停止ボタンを押すたびに1つのボールを取り外す必要があります(例:4つのボールがある場合、すべてのボールを個別に取り外すには4回停止ボタンを押す必要があります)
  3. すべて1以上のボール(s)が互いに衝突されるとX軸とボールのy座標が行列
  4. に格納する必要があり、唯一の衝突ボールが赤から青に色を変更しなければならない

オクラホマ私はほぼ完全に(ポイント1から4まで)やっていますが、ここに私の問題があります。ボールが衝突すると、ボールの色が青に変わるのではなく、ボールの色がすべて赤から青に変わります。私はエラーがnew Balls().setColor(Color.Blue)にあることを知っていますが、私はどのように衝突ボールだけを変更するのか分かりません。

以下は、Javaアプリとコードのスクリーンショットです。 誰もがこの頭痛で私を助けることができますか?

PrintScreenを:enter image description here

ソースコード:

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

実際にどのボールが衝突しているかを特定する必要があります。オブジェクトの座標を視覚的な表現から切り離して扱う奇妙な方法のようです。 – ChiefTwoPencils

+0

実例については、[複雑な形状による衝突検出](http://stackoverflow.com/a/14575043/418556)も参照してください。 –

答えて

5

あなたはあなたのアプリケーションの静的フィールドとしてclrを定義しています。 BallクラスがsetColor()を呼び出すと、clrの値が青色に変更され、getColor()を呼び出すBallは、clrが青色に変わります。

解決方法:clrをアプリケーション全体の静的フィールドにしないでください。 Ballクラスで非静的フィールドとして定義します。したがって、それぞれBallには独自の色があります。

+1

良い目です。私は彼らにも追加の問題があると思う。彼らは衝突時に新しいボールを作り、実際に衝突しているボールを持っていない。彼らの座標だけです。 – ChiefTwoPencils

+0

非常に助けていただきありがとうございます。 –

関連する問題