-1

I have a task in which I have to make a app in a JFrame.

It will contain 5 balls, which move randomly around the form, they can't exit the form and have to hit the borders. There's also an rectangle in the middle of the form, and that's the main problem, because I can't figure out how to make the ball's bounce off the rectangle.

I already started doing something but the balls just bounce off at some random places in the form.

Task:

  • Create JFrame (Done)
  • Create 5 Balls, which move around and spawn in random positions (Done)
  • Create a Rectangle in the middle of the form (Done)
  • Make the balls bounce off the rectangle. (Done)

Figured it out in the end.

Here is my code:

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Main extends JPanel {

Random rn = new Random();
int blueX = rn.nextInt(650) + 1;
int blueY = rn.nextInt(650) + 1;

int redX = rn.nextInt(650) + 1;
int redY = rn.nextInt(650) + 1;

int yellowX = rn.nextInt(650) + 1;
int yellowY = rn.nextInt(650) + 1;

int greenX = rn.nextInt(650) + 1;
int greenY = rn.nextInt(650) + 1;

int magentaX = rn.nextInt(650) + 1;
int magentaY = rn.nextInt(650) + 1;

int blueAngleX = rn.nextInt(10) + 1;
int blueAngleY = rn.nextInt(20) + 1;

int redAngleX = rn.nextInt(10) + 1;
int redAngleY = rn.nextInt(50) + 1;

int yellowAngleX = rn.nextInt(40) + 1;
int yellowAngleY = rn.nextInt(50) + 1;

int greenAngleX = rn.nextInt(30) + 1;
int greenAngleY = rn.nextInt(20) + 1;

int magentaAngleX = rn.nextInt(20) + 1;
int magentaAngleY = rn.nextInt(50) + 1;

int rectX = 325, rectY = 325, rectW = 100, rectH = 100;

int speed = 5;

private void move() {

    rectContact();

    if (blueX + blueAngleX < 0) {
        blueAngleX = speed;
    } else if (blueX + blueAngleX > getWidth() - 30) {
        blueAngleX = -speed;
    } else if (blueY + blueAngleY < 0) {
        blueAngleY = speed;
    } else if (blueY + blueAngleY > getHeight() - 30) {
        blueAngleY = -speed;
    }

    blueX = blueX + blueAngleX;
    blueY = blueY + blueAngleY;

    ///////////////////////////////////////////////////////////////////////////////////////////

    if (redX + redAngleX < 0) {
        redAngleX = speed;
    } else if (redX + redAngleX > getWidth() - 30) {
        redAngleX = -speed;
    } else if (redY + redAngleY < 0) {
        redAngleY = speed;
    } else if (redY + redAngleY > getHeight() - 30) {
        redAngleY = -speed;
    }

    redX = redX + redAngleX;
    redY = redY + redAngleY;

    ///////////////////////////////////////////////////////////////////////////////////////////

    if (yellowX + yellowAngleX < 0) {
        yellowAngleX = speed;
    } else if (yellowX + yellowAngleX > getWidth() - 30) {
        yellowAngleX = -speed;
    } else if (yellowY + yellowAngleY < 0) {
        yellowAngleY = speed;
    } else if (yellowY + yellowAngleY > getHeight() - 30) {
        yellowAngleY = -speed;
    }

    yellowX = yellowX + yellowAngleX;
    yellowY = yellowY + yellowAngleY;

    ///////////////////////////////////////////////////////////////////////////////////////////

    if (greenX + greenAngleX < 0) {
        greenAngleX = speed;
    } else if (greenX + greenAngleX > getWidth() - 30) {
        greenAngleX = -speed;
    } else if (greenY + greenAngleY < 0) {
        greenAngleY = speed;
    } else if (greenY + greenAngleY > getHeight() - 30) {
        greenAngleY = -speed;
    }

    greenX = greenX + greenAngleX;
    greenY = greenY + greenAngleY;

    ///////////////////////////////////////////////////////////////////////////////////////////

    if (magentaX + magentaAngleX < 0) {
        magentaAngleX = speed;
    } else if (magentaX + magentaAngleX > getWidth() - 30) {
        magentaAngleX = -speed;
    } else if (magentaY + magentaAngleY < 0) {
        magentaAngleY = speed;
    } else if (magentaY + magentaAngleY > getHeight() - 30) {
        magentaAngleY = -speed;
    }

    magentaX = magentaX + magentaAngleX;
    magentaY = magentaY + magentaAngleY;

}

public void rectContact() {

    if (blueY + 30 >= rectY && (blueX >= rectX - 25 && blueX <= rectX)
            || (blueY >= rectY + 100 && (blueX >= rectX && blueX <= rectX + 100))) {
        blueAngleX = -speed;
    }
    if (blueX + 10 >= rectX && (blueY >= rectY && blueY <= rectY - 25)
            || (blueX >= rectX && (blueY >= rectY && blueY <= rectY))) {
        blueAngleY = -speed;
    }

}

@Override
public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.BLUE);
    g.fillOval(blueX, blueY, 30, 30);

    g.setColor(Color.RED);
    g.fillOval(redX, redY, 30, 30);

    g.setColor(Color.YELLOW);
    g.fillOval(yellowX, yellowY, 30, 30);

    g.setColor(Color.GREEN);
    g.fillOval(greenX, greenY, 30, 30);

    g.setColor(Color.MAGENTA);
    g.fillOval(magentaX, magentaY, 30, 30);

    g.setColor(Color.RED);
    g.fillRect(rectX, rectY, rectW, rectH);
}

public static void main(String[] args) throws InterruptedException {

    JFrame frame = new JFrame("Moving Ball!");
    Main main = new Main();
    frame.add(main);
    frame.setBounds(300, 0, 750, 750);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    while (true) {
        main.move();
        main.repaint();
        Thread.sleep(10);
    }
}

}
leKt0
  • 3
  • 5
  • 1
    1. Don't override `paint', override `paintComponent` 2. If you wish to animate I would recommend using a [javax.swing.Timer](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) – copeg Sep 29 '16 at 20:05
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). *"Create 5 `Balls`"* Only put one ball in the MCVE/SSCCE. If you can get it working with one, it should work with 5 in exactly the same way. 2) See also [Collision detection with complex shapes](http://stackoverflow.com/a/14575043/418556) for a (somewhat) related example. – Andrew Thompson Sep 29 '16 at 23:03
  • @copeg So i switched to Timer, now i ran into another problem... Added new code below. Maybe you can help me out or give a hint. – leKt0 Oct 03 '16 at 16:51

2 Answers2

0

I was doing something like this recently and I came across this. It's not exactly the same but I think looking at the top answer would help you out quite a bit.

Community
  • 1
  • 1
X_Wera
  • 160
  • 10
0

Okay so i switched to using the javax.swing.Timer. Now i ran into a few other problems, regarding to random spawn areas for the balls. I noticed that if i use cordinates X,Y for the balls, which divide by 5. Everything is fine, but if not the balls start going trough the rectangle again. So i can't figure out why. My ideas are maybe make a random number generator for x1, y1, x2,y2 etc. Which picks a random number in a range from let's say 50 to 250, but the numbers have to be able to be divided by 5. which means the random numbers would be something like 5,10,15,20,25. I could use a for loop and an array to store the values and then let the program pick a random value for the x1 from the array list.

But all that sounds totally wrong and i guess i have just wandered off topic...

So here's my new code:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class Uzd2 extends JFrame implements ActionListener, KeyListener {
Graphics2D g2d;
Timer timer = new Timer(5, this);

int width1 = 30, width2 = 30, width3 = 30, width4 = 30, width5 = 30;
int height1 = 30, height2 = 30, height3 = 30, height4 = 30, height5 = 30;

Random rn = new Random();

int x1 = 20 + rn.nextInt(50) + 1;

int x2 = 20 + rn.nextInt(50) + 1;

int x3 = 20 + rn.nextInt(50) + 1;

int x4 = 20 + rn.nextInt(50) + 1;

int x5 = 20 + rn.nextInt(50) + 1;

int y1 = 20 + rn.nextInt(50) + 1;

int y2 = 20 + rn.nextInt(50) + 1;

int y3 = 20 + rn.nextInt(50) + 1;

int y4 = 20 + rn.nextInt(50) + 1;

int y5 = 20 + rn.nextInt(50) + 1;



int x1Diff = 5, y1Diff = -5;
int x2Diff = 5, y2Diff = -5;
int x3Diff = 5, y3Diff = -5;
int x4Diff = 5, y4Diff = -5;
int x5Diff = 5, y5Diff = -5;
int y1Rect = 325, x1Rect = 325;
int y2Rect = 100, x2Rect = 150;

public Uzd2() {
    timer.start();

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setBounds(10, 10, 750, 750);
    setResizable(false);
    setTitle("Animācija");
    addKeyListener(this);

    System.out.println("X1 = " + x1 + " X2 = " + x2 + " X3 = " + x3 + " X4 = " + x4 + " X5 = " + x5);
    System.out.println("Y1 = " + y1 + " Y2 = " + y2 + " Y3 = " + y3 + " Y4 = " + y4 + " Y5 = " + y5);

}

public void paint(java.awt.Graphics g) {

    super.paint(g);
    g2d = (Graphics2D) g;
    g2d.setStroke(new BasicStroke(5));
    g2d.setColor(Color.BLUE);

    animacija1(x1, y1, width1);
    animacija2(x2, y2, width2);
    animacija3(x3, y3, width3);
    animacija4(x4, y4, width4);
    animacija5(x5, y5, width5);

    g2d.setColor(Color.RED);
    g2d.fillRect(325, 325, 100, 100);
}

public void animacija1(int x1, int y1, int w1) {
    g2d.setColor(Color.BLUE);
    g2d.fillOval(x1, y1, width1, height1);
}

public void animacija2(int x2, int y2, int w2) {
    g2d.setColor(Color.GREEN);
    g2d.fillOval(x2, y2, width2, height2);
}

public void animacija3(int x3, int y3, int w3) {
    g2d.setColor(Color.MAGENTA);
    g2d.fillOval(x3, y3, width3, height3);
}

public void animacija4(int x4, int y4, int w4) {
    g2d.setColor(Color.CYAN);
    g2d.fillOval(x4, y4, width4, height4);
}

public void animacija5(int x5, int y5, int w5) {
    g2d.setColor(Color.YELLOW);
    g2d.fillOval(x5, y5, width5, height5);
}

public void actionPerformed(ActionEvent e) {
    aprekini1();
    aprekini2();
    aprekini3();
    aprekini4();
    aprekini5();

    repaint();

}

public void aprekini1() {
     //Top, bottom.
    if ((y1 <= 20 || y1 + 30 >= 760) || (y1 + 25 == y1Rect && (x1 >= x1Rect && x1 <= x1Rect + 100))
            || (y1 == y1Rect + 100 && (x1 >= x1Rect && x1 <= x1Rect + 100))) {
        y1Diff = -y1Diff;

    }
     //Left, right.
    if ((x1 <= 0 || x1 + 30 >= 750) || (x1 + 25 == x1Rect && (y1 >= x1Rect && y1 <= y1Rect + 100))
            || (x1 == x1Rect + 100 && (y1 >= x1Rect && y1 <= y1Rect + 100))) {
        x1Diff = -x1Diff;

    }

    x1 += x1Diff;
    y1 += y1Diff;

}

public void aprekini2() {


    // Top, bottom.
    if ((y2 <= 20 || y2 + 30 >= 760) || (y2 + 25 == y1Rect && (x2 >= x1Rect && x2 <= x1Rect + 100))
            || (y2 == y1Rect + 100 && (x2 >= x1Rect && x2 <= x1Rect + 100))) {
        y2Diff = -y2Diff;

    }
    // Left, right.
    if ((x2 <= 0 || x2 + 30 >= 750) || (x2 + 25 == x1Rect && (y2 >= x1Rect && y2 <= y1Rect + 100))
            || (x2 == x1Rect + 100 && (y2 >= x1Rect && y2 <= y1Rect + 100))) {
        x2Diff = -x2Diff;

    }

    x2 += x2Diff;
    y2 += y2Diff;

}

public void aprekini3() {

    // Top, bottom.
    if ((y3 <= 20 || y3 + 30 >= 760) || (y3 + 25 == y1Rect && (x3 >= x1Rect && x3 <= x1Rect + 100))
            || (y3 == y1Rect + 100 && (x3 >= x1Rect && x3 <= x1Rect + 100))) {
        y3Diff = -y3Diff;

    }
    // Left, right.
    if ((x3 <= 0 || x3 + 30 >= 750) || (x3 + 25 == x1Rect && (y3 >= x1Rect && y3 <= y1Rect + 100))
            || (x3 == x1Rect + 100 && (y3 >= x1Rect && y3 <= y1Rect + 100))) {
        x3Diff = -x3Diff;

    }

    x3 += x3Diff;
    y3 += y3Diff;

}

public void aprekini4() {


    // Top, bottom.
    if ((y4 <= 20 || y4 + 30 >= 760) || (y4 + 25 == y1Rect && (x4 >= x1Rect && x4 <= x1Rect + 100))
            || (y4 == y1Rect + 100 && (x4 >= x1Rect && x4 <= x1Rect + 100))) {
        y4Diff = -y4Diff;

    }
    // Left, right.
    if ((x4 <= 0 || x4 + 30 >= 750) || (x4 + 25 == x1Rect && (y4 >= x1Rect && y4 <= y1Rect + 100))
            || (x4 == x1Rect + 100 && (y4 >= x1Rect && y4 <= y1Rect + 100))) {
        x4Diff = -x4Diff;

    }

    x4 += x4Diff;
    y4 += y4Diff;

}

public void aprekini5() {

    // Top, bottom.
    if ((y5 <= 20 || y5 + 30 >= 760) || (y5 + 25 == y1Rect && (x5 >= x1Rect && x5 <= x1Rect + 100))
            || (y5 == y1Rect + 100 && (x5 >= x1Rect && x5 <= x1Rect + 100))) {
        y5Diff = -y5Diff;

    }
    // Left, right.
    if ((x5 <= 0 || x5 + 30 >= 750) || (x5 + 25 == x1Rect && (y5 >= x1Rect    && y5 <= y1Rect + 100))
            || (x5 == x1Rect + 100 && (y5 >= x1Rect && y5 <= y1Rect + 100)))     {
        x5Diff = -x5Diff;

    }

    x5 += x5Diff;
    y5 += y5Diff;

}



@Override
public void keyTyped(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_W) {
        y1Rect -= 5;
    }
}

@Override
public void keyPressed(KeyEvent e) {

}

@Override
public void keyReleased(KeyEvent e) {

}

public static void main(String[] args) {

    Uzd2 frame = new Uzd2();
    frame.setVisible(true);

}

}
leKt0
  • 3
  • 5