OK I have yet another homework problem. Again, help me by teaching, not writing my code for me. I have looked through the pages of threads on collision detection and found nothing to answer my question. My issue is that I have a collision detection method that should (in theory) work. I have a program that populates the screen with balls of random colors and sizes and they bounce around. There is also a button to add more balls to induce chaos. I am trying to make it so that when the balls collide, they will make a new ball so a collision calls the moreBalls method which adds another ball to the arraylist. I have put some checks in that will print strings to the terminal depending on the method as well. I think, and correct me if I'm wrong, that my for loop is comparing the p and r of the same bounding rectangle therefore it would either never collide or constantly collide. It gives no reason for me to believe that there is constant collision, though, due to my checks.
The code:
Ball Class:
package balls_lab5;
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
*
* @author 24x24
*/
public class Ball {
int ballxCoord;
int ballyCoord;
int ballHeight;
int ballWidth;
int ballRise;
int ballRun;
Color ballColor;
BallPanel ballPanel;
public Ball() {
// Initialize Ball with random values
ballxCoord = (int) (Math.random() * (50));
ballyCoord = (int) (Math.random() * (50));
ballHeight = (int) (10 + (int)(Math.random() * ((20 - 10) + 1)));
ballWidth = (int) (10 + (int)(Math.random() * ((20 - 10) + 1)));
ballRise = (int) (Math.random() * (10));
ballRun = (int) (Math.random() * (10));
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
ballColor = randomColor;
}
/**
Paints the balls at their current positions within the panel.
*/
public void paintComponent (Graphics g) {
// Paint Ball
g.setColor(ballColor);
//g.setColor(Color.white);
g.fillOval(ballxCoord, ballyCoord, ballWidth, ballHeight);
}
public void move (int pWidth, int pHeight){
// Move Ball
// If ball is approaching a wall, reverse direction
if (ballxCoord < (0 - ballRun) || ballxCoord > (pWidth - ballWidth)) {
ballRun = -ballRun;
}
if (ballyCoord < (0 - ballRise) || ballyCoord > (pHeight - ballHeight)) {
ballRise = -ballRise;
}
// "Move" ball according to values in rise and run
ballxCoord += ballRun;
ballyCoord += ballRise;
}
public void collision(){
ballPanel.moreBalls();
// A check to make sure balls collided
System.out.println("Collision!");
}
public Color getBallColor() {
return ballColor;
}
public void setBallColor(Color ballColor) {
this.ballColor = ballColor;
}
public int getBallHeight() {
return ballHeight;
}
public void setBallHeight(int ballHeight) {
this.ballHeight = ballHeight;
}
public int getBallRise() {
return ballRise;
}
public void setBallRise(int ballRise) {
this.ballRise = ballRise;
}
public int getBallRun() {
return ballRun;
}
public void setBallRun(int ballRun) {
this.ballRun = ballRun;
}
public int getBallWidth() {
return ballWidth;
}
public void setBallWidth(int ballWidth) {
this.ballWidth = ballWidth;
}
public int getBallxCoord() {
return ballxCoord;
}
public void setBallxCoord(int ballxCoord) {
this.ballxCoord = ballxCoord;
}
public int getBallyCoord() {
return ballyCoord;
}
public void setBallyCoord(int ballyCoord) {
this.ballyCoord = ballyCoord;
}
} // end of Ball class
BallPanel class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package balls_lab5;
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
* @author 24x24
*/
/**
* A panel containing two bouncing balls. This panel may be placed in a JFrame.
* @author ahanes
*/
public class BallPanel extends JPanel {
ArrayList balls = new ArrayList();
Ball ball;
/** Creates a new instance of BallPanel */
public BallPanel() {
super();
balls = new ArrayList();
}
public void moreBalls(){
Ball ball = new Ball ();
balls.add(ball);
System.out.println(balls); // A check to make sure balls were added
}
public void detectCollision (){
for (Object e : balls)
{
Rectangle r = new Rectangle(((Ball)e).ballxCoord,((Ball)e).ballyCoord,((Ball)e).ballWidth,((Ball)e).ballHeight);
Rectangle p = new Rectangle(((Ball)e).ballxCoord,((Ball)e).ballyCoord,((Ball)e).ballWidth,((Ball)e).ballHeight);
if (r.intersects(p))
{
ball.collision(); // multiplies balls
System.out.println("Intersection!"); // a check to make sure balls intersect
}
}
}
public ArrayList addBalls(){
String stringBalls = JOptionPane.showInputDialog("How many balls would you like?");
int numBalls = Integer.parseInt( stringBalls );
for (int i = 0; i < numBalls; i++){
Ball ball = new Ball ();
balls.add(ball);
System.out.println(balls); // A check to make sure balls were added
}
return balls;
}
/**
Paints the panel and the balls.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black); // set color black
g.fillRect(0, 0, this.getWidth(), this.getHeight()); // paint background
for (int i = 0; i < balls.size(); i++){
((Ball)balls.get(i)).paintComponent(g);
}
} // end method paintComponent
/**
Computes the next position for the balls and updates their positions.
*/
public void move() {
// Move Ball
// If ball is approaching a wall, reverse direction
for (Object b : balls){
((Ball)b).move(getWidth(), getHeight());
}
} // end method move
}
The Test:
package balls_lab5;
import java.awt.*; // Old library classes, you still need them
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*; // New library classes, Swing extends AWT
/**
* Frame to hold a bouncing ball panel, implemented in the BallPanel class.
* Controls the animation of the ball via pauses and calls to BallPanel's move and
* paintComponent methods.
* @author 24x24
*/
public class BallTest extends JFrame implements ActionListener {
// size of the window
private static final int WINDOW_WIDTH = 1000;
private static final int WINDOW_HEIGHT = 500;
ArrayList balls;
// panel containing the bouncing ball
private BallPanel ballPanel;
/**
* Pause command used to control the speed of the bouncing ball animation.
* Currently pauses for 20 ms. Use smaller values for faster animation and
* vice versa.
*/
public static void pause() {
try {
Thread.sleep(12); // pause for 20 ms
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
/** Creates a new instance of BallTest */
public BallTest() {
super("Bouncing Ball"); // set frame name
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLayout(new BorderLayout());
ballPanel = new BallPanel();
add(ballPanel);
center(this);
setVisible(true);
JButton moreBalls = new JButton ();
moreBalls.setText("More Balls");
moreBalls.addActionListener(this);
add(moreBalls, BorderLayout.SOUTH);
ballPanel.addBalls();
// infinite animation loop, program halts when window is closed.
while (true) {
pause();
ballPanel.move();
ballPanel.repaint();
}
}
/** Helper routine to center a frame on the screen (will cause problems if
frame is bigger than the screen!)
*/
public static void center(JFrame frame) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Point center = ge.getCenterPoint();
int w = frame.getWidth();
int h = frame.getHeight();
int x = center.x - w / 2, y = center.y - h / 2;
frame.setBounds(x, y, w, h);
frame.validate();
}
public static void main(String[] args) {
BallTest t = new BallTest();
}
@Override
public void actionPerformed(ActionEvent e) {
ballPanel.moreBalls();
}
} // end method Main
Any help will be greatly appreciated. Not as important until its fixed but still also appreciated, if you see something I am doing backwards that could be improved let me know. We are always learning.