Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package twoballs2;
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- /**
- *
- * @author noraekstrom
- */
- public class Twoballs2 {
- final static int UPDATE_FREQUENCY = 100; // GlobalĀ constant: fps, ie times per second to simulate
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) {
- JFrame frame = new JFrame("Many collisions!");
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- Table table = new Table();
- frame.add(table);
- frame.pack();
- frame.setVisible(true);
- }
- }
- class Coord {
- double x, y;
- Coord(double xCoord, double yCoord) {
- x = xCoord;
- y = yCoord;
- }
- Coord(MouseEvent event) { // Create a Coord from a mouse event
- x = event.getX();
- y = event.getY();
- }
- static final Coord ZERO = new Coord(0, 0);
- double magnitude() {
- return Math.sqrt(x * x + y * y);
- }
- Coord norm() { // norm: a normalised vector at the same direction
- return new Coord(x / magnitude(), y / magnitude());
- }
- void increase(Coord c) {
- x += c.x;
- y += c.y;
- }
- void decrease(Coord c) {
- x -= c.x;
- y -= c.y;
- }
- static double scal(Coord a, Coord b) { // scalar product
- return a.x * b.x + a.y * b.y;
- }
- static Coord sub(Coord a, Coord b) {
- return new Coord(a.x - b.x, a.y - b.y);
- }
- static Coord mul(double k, Coord c) { // multiplication by a constant
- return new Coord(k * c.x, k * c.y);
- }
- static double distance(Coord a, Coord b) {
- return Coord.sub(a, b).magnitude();
- }
- static void paintLine(Graphics2D graph2D, Coord a, Coord b) { // paint line between points
- graph2D.setColor(Color.black);
- graph2D.drawLine((int) a.x, (int) a.y, (int) b.x, (int) b.y);
- }
- }
- class Table extends JPanel implements ActionListener {
- final int TABLE_WIDTH = 1000;
- final int TABLE_HEIGHT = 500;
- final int WALL_THICKNESS = 20;
- private final Color COLOR = Color.green;
- private final Color WALL_COLOR = Color.black;
- final Timer simulationTimer;
- JButton button = new JButton("PAUSE");
- final int BALL_AMOUNT = 100;
- Ball[] ballList = new Ball[BALL_AMOUNT];
- Table() {
- setPreferredSize(new Dimension(TABLE_WIDTH + 2 * WALL_THICKNESS,
- TABLE_HEIGHT + 2 * WALL_THICKNESS));
- createInitialBalls();
- simulationTimer = new Timer((int) (1000.0 / Twoballs2.UPDATE_FREQUENCY), this);
- simulationTimer.start();
- buttonActivity();
- this.add(button);
- }
- private void createInitialBalls() {
- for (int i = 0; i < BALL_AMOUNT; i++) {
- double RANDOM_V_X = 1 - (2 * Math.random());
- double RANDOM_V_Y = 1 - (2 * Math.random());
- Coord RANDOM_VELOCITY = new Coord(RANDOM_V_X, RANDOM_V_Y);
- double randomPosX = (Math.random() * (TABLE_WIDTH - WALL_THICKNESS)/2) + WALL_THICKNESS + Ball.RADIUS;
- double randomPosY = (Math.random() * ((TABLE_HEIGHT - WALL_THICKNESS))) + WALL_THICKNESS + Ball.RADIUS;
- Coord newPosition = new Coord(randomPosX, randomPosY);
- ballList[i] = new Ball(newPosition, RANDOM_VELOCITY, this);
- }
- }
- @Override
- public void actionPerformed(ActionEvent e) { // Timer event
- for (Ball ball : ballList) {
- ball.move();
- repaint();
- }
- }
- void buttonActivity() {
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (button.getText()=="PAUSE") {
- simulationTimer.stop();
- button.setText("START");
- }
- else {
- simulationTimer.start();
- button.setText("PAUSE");
- }
- }
- });
- }
- @Override
- public void paintComponent(Graphics graphics) {
- super.paintComponent(graphics);
- Graphics2D g2D = (Graphics2D) graphics;
- g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // This makes the graphics smoother
- RenderingHints.VALUE_ANTIALIAS_ON);
- g2D.setColor(WALL_COLOR);
- g2D.fillRect(0, 0, TABLE_WIDTH + 2 * WALL_THICKNESS, TABLE_HEIGHT + 2 * WALL_THICKNESS);
- g2D.setColor(COLOR);
- g2D.fillRect(WALL_THICKNESS, WALL_THICKNESS, TABLE_WIDTH, TABLE_HEIGHT);
- for (Ball ballList1 : ballList) {
- ballList1.paint(g2D);
- }
- }
- } // end class Table
- class Ball {
- Color COLOR = Color.white;
- Color COLOR_R = Color.red;
- private double impuls;
- private double dx;
- private double dy;
- double ballPosition;
- private final Color COLOR_WHITE = Color.white;
- private final Color COLOR_RED = Color.red;
- private final Color COLOR_BLACK = Color.black;
- private final int BORDER_THICKNESS = 2;
- static final double RADIUS = 10;
- private final double DIAMETER = 2 * RADIUS;
- private final double FRICTION = 0; // its friction constant (normed for 100 updates/second)
- private Coord position;
- private Coord velocity;
- Table theTable;
- private final double PROB_SICK = 0.3;
- private final double PROB_INFECT = 0.8;
- private final double PROB_DIE = 0.9;
- boolean isSick = false;
- boolean isDead = false;
- int timeSick;
- int timeIncubation = 300;
- Ball(Coord initialPosition, Coord RANDOM_VELOCITY, Table table) {
- position = initialPosition;
- velocity = RANDOM_VELOCITY;
- theTable = table;
- if ((Math.random()) < PROB_SICK) {
- sick();
- }
- }
- void move() {
- position.increase(velocity);
- if (wallHitRight() || wallHitLeft()) {
- velocity.x = velocity.x * -1;
- }
- if (wallHitTop() || wallHitBottom()) {
- velocity.y = velocity.y * -1;
- }
- for (Ball ball : theTable.ballList) {
- ballCollision(ball);
- }
- if (isSick) {
- ballDeadOrAlive();
- }
- }
- void sick (){
- isSick = true;
- }
- void dead(){
- isDead = true;
- isSick = false;
- COLOR = Color.black;
- position.x = 0;
- position.y = 0;
- velocity = Coord.ZERO;
- }
- void healthy(){
- isSick = false;
- COLOR = Color.white;
- }
- void becomesInfected(Ball ball) {
- if (isSick && (Math.random() < PROB_INFECT) && !isDead) {
- ball.isSick = true;
- }
- }
- void ballDeadOrAlive() {
- timeSick++;
- if (timeSick >= timeIncubation) {
- if (Math.random() < PROB_DIE) {
- dead();
- }
- else {
- healthy();
- }
- }
- }
- void collisionEffect(Ball otherBall) {
- dx = position.x - otherBall.position.x;
- dy = position.y - otherBall.position.y;
- Coord d = new Coord(dx, dy);
- Coord normD = d.norm();
- impuls = Coord.scal(velocity, normD) - Coord.scal(otherBall.velocity, normD);
- double New_velocityX1 = velocity.x - impuls * normD.x;
- double New_velocityY1 = velocity.y - impuls * normD.y;
- double New_velocityX2 = otherBall.velocity.x + impuls * normD.x;
- double New_velocityY2 = otherBall.velocity.y + impuls * normD.y;
- velocity = new Coord(New_velocityX1, New_velocityY1);
- otherBall.velocity = new Coord(New_velocityX2, New_velocityY2);
- }
- void ballCollision(Ball ball) {
- if (ball != this) {
- double distance = Math.sqrt(Math.pow((position.x - ball.position.x), 2) + Math.pow((position.y - ball.position.y), 2));
- double distance2 = Math.sqrt(((ball.position.x + ball.velocity.x) - (position.x + velocity.x)) * ((ball.position.x + ball.velocity.x)
- - (position.x + velocity.x)) + ((ball.position.y + ball.velocity.y) - (position.y + velocity.y))
- * ((ball.position.y + ball.velocity.y) - (position.y + velocity.y)));
- if (distance <= RADIUS * 2 && distance2 < distance) {
- collisionEffect(ball);
- becomesInfected(ball);
- }
- }
- }
- boolean wallHitRight() {
- boolean hit = false;
- if (position.x + RADIUS >= theTable.TABLE_WIDTH + theTable.WALL_THICKNESS && velocity.x > 0) {
- hit = true;
- }
- return hit;
- }
- boolean wallHitLeft() {
- boolean hit = false;
- if (position.x - RADIUS <= theTable.WALL_THICKNESS && velocity.x < 0) {
- hit = true;
- }
- return hit;
- }
- boolean wallHitTop() {
- boolean hit = false;
- if (position.y - RADIUS <= theTable.WALL_THICKNESS && velocity.y < 0) {
- hit = true;
- }
- return hit;
- }
- boolean wallHitBottom() {
- boolean hit = false;
- if (position.y + RADIUS >= theTable.TABLE_HEIGHT + theTable.WALL_THICKNESS && velocity.y > 0) {
- hit = true;
- }
- return hit;
- }
- void paint(Graphics2D g2D) {
- g2D.setColor(Color.black);
- g2D.fillOval(
- (int) (position.x - RADIUS + 0.5),
- (int) (position.y - RADIUS + 0.5),
- (int) DIAMETER,
- (int) DIAMETER);
- if (isSick) {
- g2D.setColor(COLOR_RED);
- }
- else {
- g2D.setColor(COLOR_WHITE);
- }
- if (isDead && isSick == false) {
- g2D.setColor(COLOR_BLACK);
- }
- g2D.fillOval(
- (int) (position.x - RADIUS + 0.5 + BORDER_THICKNESS),
- (int) (position.y - RADIUS + 0.5 + BORDER_THICKNESS),
- (int) (DIAMETER - 2 * BORDER_THICKNESS),
- (int) (DIAMETER - 2 * BORDER_THICKNESS));
- }
- } // end class Ball
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement