Skip to content

Instantly share code, notes, and snippets.

@ahmednasserpro
Created July 17, 2019 01:22
Show Gist options
  • Save ahmednasserpro/be175b05f8ca146bf578e971c6c8f4e7 to your computer and use it in GitHub Desktop.
Save ahmednasserpro/be175b05f8ca146bf578e971c6c8f4e7 to your computer and use it in GitHub Desktop.
Combine colliding bouncing balls
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class BouncingBall extends JFrame {
public BouncingBall() {
add(new BallControl());
}
public static void main(String[] args) {
JFrame frame = new BouncingBall();
frame.setSize(600, 500);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class BallControl extends JPanel {
private BallPanel ballPanel = new BallPanel();
private JButton jbtSuspend = new JButton("Suspend");
private JButton jbtResume = new JButton("Resume");
private JButton jbtAdd = new JButton("+1");
private JButton jbtSubtract = new JButton("-1");
private JScrollBar jsbDelay = new JScrollBar();
public BallControl() {
// Group buttons in a panel
JPanel panel = new JPanel();
panel.add(jbtSuspend);
panel.add(jbtResume);
panel.add(jbtAdd);
panel.add(jbtSubtract);
// Add ball and buttons to the panel
ballPanel.setBorder(
new javax.swing.border.LineBorder(Color.red));
jsbDelay.setOrientation(JScrollBar.HORIZONTAL);
ballPanel.setDelay(jsbDelay.getMaximum());
setLayout(new BorderLayout());
add(jsbDelay, BorderLayout.NORTH);
add(ballPanel, BorderLayout.CENTER);
add(panel, BorderLayout.SOUTH);
// Register listeners
jbtSuspend.addActionListener(new Listener());
jbtResume.addActionListener(new Listener());
jbtAdd.addActionListener(new Listener());
jbtSubtract.addActionListener(new Listener());
jsbDelay.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
ballPanel.setDelay(jsbDelay.getMaximum() - e.getValue());
}
});
}
class Listener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jbtSuspend) {
ballPanel.suspend();
} else if (e.getSource() == jbtResume) {
ballPanel.resume();
} else if (e.getSource() == jbtAdd) {
ballPanel.add();
} else if (e.getSource() == jbtSubtract) {
ballPanel.subtract();
}
}
}
}
class BallPanel extends JPanel {
private int delay = 10;
private ArrayList<Ball> list = new ArrayList<>();
private Timer timer = new Timer(delay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
repaint();
}
});
public BallPanel() {
timer.start();
}
public void add() {
list.add(new Ball());
}
public void subtract() {
list.remove(list.size() - 1);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < list.size(); i++) {
Ball ball1 = list.get(i);
g.setColor(ball1.color);
if (ball1.x < 0 || ball1.x > getWidth())
ball1.dx = -ball1.dx;
if (ball1.y < 0 || ball1.y > getHeight())
ball1.dy = -ball1.dy;
ball1.x += ball1.dx;
ball1.y += ball1.dy;
if (getcollideIndex(ball1, i) != -1) {
Ball ball2 = list.get(getcollideIndex(ball1, i));
list.remove(ball2);
ball1.radius += ball2.radius;
}
g.fillOval(ball1.x - ball1.radius, ball1.y - ball1.radius,
ball1.radius * 2, ball1.radius * 2);
}
}
public int getcollideIndex(Ball ball1, int index) {
for (int i = 0; i < list.size(); i++) {
if (i == index)
continue;
Ball ball2 = list.get(i);
int dis = distance(ball1.x + ball1.radius, ball1.y + ball1.radius,
ball2.x + ball2.radius, ball2.y + ball2.radius);
if (dis <= Math.abs(ball1.radius - ball2.radius) || dis <= (ball1.radius + ball2.radius))
return i;
}
return -1;
}
public static int distance(int x1, int y1, int x2, int y2) {
return (int) Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
public void suspend() {
timer.stop();
}
public void resume() {
timer.start();
}
public void setDelay(int delay) {
this.delay = delay;
timer.setDelay(delay);
}
}
class Ball {
int x = 0;
int y = 0;
int dx = 2;
int dy = 2;
int radius = 5;
Color color = new Color((int) (Math.random() * 256), (int)
(Math.random() * 256), (int) (Math.random() * 256));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment