2

So, right now, I'm able to create multiple balls and update them all properly through a Vector of objects and a for loop to update each object independently. The problem is that for every ball after the first, the ball that is created seems to affect the momentum and position of the other balls, causing all the balls to abruptly change their flight paths.

Code for creating frame and managing ball creation based on mouselistener:

public class FrameCreation extends JFrame{
    static Vector<BallCreate> ballObjects = new Vector<BallCreate>();
    static Timer timer;
    Point m1;
    Point m2;
    static JFrame frame1;
    static mouseHandler mouse;

    public static void main(String args[]){
        FrameCreation frame = new FrameCreation();
        frame1 = new JFrame("Phyiscs Test");
        frame1.setVisible(true);
        frame1.setSize(520,530);
        frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
        mouse =  frame.new mouseHandler();
        frame1.addMouseListener(mouse);
    }

    public class mouseHandler extends JPanel implements MouseListener{
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            m1 = e.getPoint();
            System.out.println("Mouse pressed");
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            m2 = e.getPoint();
            Thread queryThread  = new Thread(){
                    double vX = m2.getX() - m1.getX();
                    double vY = m2.getY() - m1.getY();

                    public void run(){
                        createBall(m1.getX(),m1.getY(),vX,vY);
                    }
                };
            queryThread.start();
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }

    public void createBall(double posX, double posY, double vX, double vY){
        BallCreate newBall = new BallCreate(posX,posY,50,vX,vY);
        ballObjects.add(newBall);
        frame1.add(newBall);
        frame1.revalidate();
        newBall.repaint();
    }
}

Code for drawing and updating balls:

public class BallCreate extends JPanel {    
    Timer timer;
    int diam;
    Color color;
    double vX, vY, posX, posY;
    final double G = 30;

    public BallCreate(double posX, double posY, int diam, double vX, double vY){
        this.posX = posX;
        this.posY = posY;
        this.vX = vX;
        this.vY = vY;
        this.diam = diam;
        color = getRandomColor();
        timer = new Timer(100, new MovementUpdate());
        timer.start();
    }

    public void drawing(){
        repaint();
    }

    public void motionUpdate(){
        for(BallCreate ball : FrameCreation.ballObjects){
            double t = 0.1;
            double dX = ball.vX*t;
            double dY = (ball.vY + G*t)*t;
            double v2Y = G*t + ball.vY;
            System.out.println("Ball v2y: " + ball.vY);
            ball.posX = ball.posX + dX;
            ball.posY = ball.posY + dY;
            vY = v2Y;
            drawing();
            wallCollisionCheck();
        }
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for(BallCreate ball : FrameCreation.ballObjects){
            g.setColor(ball.color);
            //System.out.println("pos X: " + posX);
            //System.out.println("pos Y: " + posY);
            g.fillOval((int)ball.posX, (int)ball.posY, 
                       ball.diam ,ball.diam);
        }
        }

    public void wallCollisionCheck(){
        for(BallCreate ball : FrameCreation.ballObjects){
            double botBound = 500-(ball.posY + ball.diam);
            if((botBound <=0 && vY>=0)|| (ball.posY <=0 && ball.vY <=0 )){
                //System.out.println("Collision Noted");
                //System.out.println("Prev vY: " + ball.vY);
                ball.vY = ball.vY * -0.65;
                //System.out.println("Post vY: " + ball.vY);
                ball.posY = 460;
            }
            if((ball.posX <= 0 && ball.vX <= 0) || ((Math.abs(500 - ball.posX) <= 40)&& ball.vX >=0)){
                ball.vX = ball.vX * -0.65;

            }
            drawing();
        }
    }

    public Color getRandomColor(){
        int R = (int)(255*Math.random());
        int G = (int)(255*Math.random());
        int B = (int)(255*Math.random());
        Color c = new Color(R, G , B);
        return c;

    }
    public class MovementUpdate implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            for(BallCreate ball : FrameCreation.ballObjects){
                ball.motionUpdate();
            }
        }
    }   
}

I realize that the problem is slightly vague, but it's simply hard to describe without being able to show an image of what is happening. Any help is appreciated, and clarification of code can be done if necessary. Thanks.

ntalbs
  • 28,700
  • 8
  • 66
  • 83
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Use a logical and consistent form of indenting code lines and blocks. The indentation is intended to make the flow of the code easier to follow! 3) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. – Andrew Thompson Aug 16 '15 at 17:45
  • `public class BallCreate extends JPanel {` ... hmmm. `ballCreate(..)` should be a method that creates and returns a `Ball` object that knows it's own position (velocity, color, size etc.) and knows how to `paint(Graphics)` itself when asked to. There should only ever be a single custom painted component (like a `JPanel`) in which **all** of the (shrugs) `Collection` are painted. – Andrew Thompson Aug 16 '15 at 17:49
  • I believe you're saying that by extending JPanel I'm creating new panels each time I create a new instance of the BallCreate object; however, in order to add the object to the JFrame, I need to extend JPanel so that it can be registered as a component, so I'm not sure how to make a ball object that knows how to paint itself, but doesn't create new JPanels when it is created. – AlbedoEffect Aug 16 '15 at 18:43
  • Any chance you have some clarification or a code example of how it should be done? – AlbedoEffect Aug 16 '15 at 18:52
  • *"Any chance you have some clarification or a code example.."* I was wondering the same of you. See my first comment re a [mcve]. In this case you'd need to change `public class BallCreate extends JPanel {` to `class BallCreate extends JPanel {` and paste all that source into the end of the other code, then resolve the imports and check it runs from a single copy/paste. – Andrew Thompson Aug 16 '15 at 19:22
  • 1
    See also the `KineticModel` cited [here](http://stackoverflow.com/a/12041004/230513). – trashgod Aug 16 '15 at 19:53
  • Followed your advice, Andrew Thompson, and made BallCreate just a template for the object's position values with all the motion updates in a separate method that just calls ballCreate for painting. Seems to work perfectly with all the errors fixed. Thanks a lot! Sorry about not having my code more organized, it's my first post on the site, and I didn't know about the tab problems and the other formatting requirements. I'll make another comment if any other problems arise. – AlbedoEffect Aug 17 '15 at 02:39
  • *"Followed your advice, Andrew Thompson.."* Tip: Add @trashgod (or whoever, the `@` is important) to notify the person of a new comment. *"..all the errors fixed"* Glad you got it sorted.. :) – Andrew Thompson Aug 17 '15 at 14:54

0 Answers0