Advertisement
Guest User

Labb_sjuka_bollar

a guest
Nov 20th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.45 KB | None | 0 0
  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6. package twoballs2;
  7.  
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.*;
  11.  
  12. /**
  13.  *
  14.  * @author noraekstrom
  15.  */
  16. public class Twoballs2 {
  17.  
  18.     final static int UPDATE_FREQUENCY = 100;    // GlobalĀ constant: fps, ie times per second to simulate
  19.  
  20.     /**
  21.      * @param args the command line arguments
  22.      */
  23.     public static void main(String[] args) {
  24.  
  25.         JFrame frame = new JFrame("Many collisions!");
  26.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  27.  
  28.         Table table = new Table();
  29.  
  30.         frame.add(table);
  31.         frame.pack();
  32.         frame.setVisible(true);
  33.     }
  34. }
  35.  
  36. class Coord {
  37.  
  38.     double x, y;
  39.  
  40.     Coord(double xCoord, double yCoord) {
  41.         x = xCoord;
  42.         y = yCoord;
  43.     }
  44.  
  45.     Coord(MouseEvent event) {                   // Create a Coord from a mouse event
  46.         x = event.getX();
  47.         y = event.getY();
  48.     }
  49.  
  50.     static final Coord ZERO = new Coord(0, 0);
  51.  
  52.     double magnitude() {
  53.         return Math.sqrt(x * x + y * y);
  54.     }
  55.  
  56.     Coord norm() {                              // norm: a normalised vector at the same direction
  57.         return new Coord(x / magnitude(), y / magnitude());
  58.     }
  59.  
  60.     void increase(Coord c) {
  61.         x += c.x;
  62.         y += c.y;
  63.     }
  64.  
  65.     void decrease(Coord c) {
  66.         x -= c.x;
  67.         y -= c.y;
  68.     }
  69.  
  70.     static double scal(Coord a, Coord b) {      // scalar product
  71.         return a.x * b.x + a.y * b.y;
  72.     }
  73.  
  74.     static Coord sub(Coord a, Coord b) {
  75.         return new Coord(a.x - b.x, a.y - b.y);
  76.     }
  77.  
  78.     static Coord mul(double k, Coord c) {       // multiplication by a constant
  79.         return new Coord(k * c.x, k * c.y);
  80.     }
  81.  
  82.     static double distance(Coord a, Coord b) {
  83.         return Coord.sub(a, b).magnitude();
  84.     }
  85.  
  86.     static void paintLine(Graphics2D graph2D, Coord a, Coord b) {  // paint line between points
  87.         graph2D.setColor(Color.black);
  88.         graph2D.drawLine((int) a.x, (int) a.y, (int) b.x, (int) b.y);
  89.     }
  90. }
  91.  
  92. class Table extends JPanel implements ActionListener {
  93.  
  94.     final int TABLE_WIDTH = 1000;
  95.     final int TABLE_HEIGHT = 500;
  96.     final int WALL_THICKNESS = 20;
  97.     private final Color COLOR = Color.green;
  98.     private final Color WALL_COLOR = Color.black;
  99.     final Timer simulationTimer;
  100.     JButton button = new JButton("PAUSE");
  101.    final int BALL_AMOUNT = 100;
  102.  
  103.     Ball[] ballList = new Ball[BALL_AMOUNT];
  104.  
  105.     Table() {
  106.         setPreferredSize(new Dimension(TABLE_WIDTH + 2 * WALL_THICKNESS,
  107.                 TABLE_HEIGHT + 2 * WALL_THICKNESS));
  108.  
  109.         createInitialBalls();
  110.  
  111.         simulationTimer = new Timer((int) (1000.0 / Twoballs2.UPDATE_FREQUENCY), this);
  112.         simulationTimer.start();
  113.         buttonActivity();
  114.         this.add(button);
  115.  
  116.     }
  117.  
  118.     private void createInitialBalls() {
  119.  
  120.         for (int i = 0; i < BALL_AMOUNT; i++) {
  121.  
  122.             double RANDOM_V_X = 1 - (2 * Math.random());
  123.             double RANDOM_V_Y = 1 - (2 * Math.random());
  124.             Coord RANDOM_VELOCITY = new Coord(RANDOM_V_X, RANDOM_V_Y);
  125.  
  126.             double randomPosX = (Math.random() * (TABLE_WIDTH - WALL_THICKNESS)/2) + WALL_THICKNESS + Ball.RADIUS;
  127.             double randomPosY = (Math.random() * ((TABLE_HEIGHT - WALL_THICKNESS))) + WALL_THICKNESS + Ball.RADIUS;
  128.  
  129.             Coord newPosition = new Coord(randomPosX, randomPosY);
  130.  
  131.             ballList[i] = new Ball(newPosition, RANDOM_VELOCITY, this);
  132.  
  133.         }
  134.  
  135.     }
  136.  
  137.     @Override
  138.     public void actionPerformed(ActionEvent e) { // Timer event
  139.  
  140.         for (Ball ball : ballList) {
  141.             ball.move();
  142.             repaint();
  143.  
  144.         }
  145.  
  146.     }
  147.     void buttonActivity() {
  148.         button.addActionListener(new ActionListener() {
  149.             public void actionPerformed(ActionEvent e) {
  150.                 if (button.getText()=="PAUSE") {
  151.                     simulationTimer.stop();
  152.                     button.setText("START");
  153.                    
  154.                 }
  155.                 else {
  156.                     simulationTimer.start();
  157.                     button.setText("PAUSE");
  158.                 }
  159.             }
  160.         });
  161.     }
  162.  
  163.     @Override
  164.     public void paintComponent(Graphics graphics) {
  165.         super.paintComponent(graphics);
  166.         Graphics2D g2D = (Graphics2D) graphics;
  167.         g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // This makes the graphics smoother
  168.                 RenderingHints.VALUE_ANTIALIAS_ON);
  169.  
  170.         g2D.setColor(WALL_COLOR);
  171.         g2D.fillRect(0, 0, TABLE_WIDTH + 2 * WALL_THICKNESS, TABLE_HEIGHT + 2 * WALL_THICKNESS);
  172.  
  173.         g2D.setColor(COLOR);
  174.         g2D.fillRect(WALL_THICKNESS, WALL_THICKNESS, TABLE_WIDTH, TABLE_HEIGHT);
  175.  
  176.         for (Ball ballList1 : ballList) {
  177.             ballList1.paint(g2D);
  178.  
  179.         }
  180.  
  181.     }
  182. }  // end class Table
  183.  
  184. class Ball {
  185.     Color COLOR = Color.white;
  186.     Color COLOR_R = Color.red;
  187.     private double impuls;
  188.     private double dx;
  189.     private double dy;
  190.     double ballPosition;
  191.     private final Color COLOR_WHITE = Color.white;
  192.     private final Color COLOR_RED = Color.red;
  193.     private final Color COLOR_BLACK = Color.black;
  194.     private final int BORDER_THICKNESS = 2;
  195.     static final double RADIUS = 10;
  196.     private final double DIAMETER = 2 * RADIUS;
  197.     private final double FRICTION = 0;                          // its friction constant (normed for 100 updates/second)
  198.  
  199.     private Coord position;
  200.     private Coord velocity;
  201.     Table theTable;
  202.     private final double PROB_SICK = 0.3;
  203.     private final double PROB_INFECT = 0.8;
  204.     private final double PROB_DIE = 0.9;
  205.  
  206.     boolean isSick = false;
  207.     boolean isDead = false;
  208.     int timeSick;
  209.     int timeIncubation = 300;
  210.  
  211.     Ball(Coord initialPosition, Coord RANDOM_VELOCITY, Table table) {
  212.  
  213.         position = initialPosition;
  214.         velocity = RANDOM_VELOCITY;
  215.         theTable = table;
  216.  
  217.         if ((Math.random()) < PROB_SICK) {
  218.             sick();
  219.            
  220.         }
  221.  
  222.     }
  223.  
  224.     void move() {
  225.  
  226.         position.increase(velocity);
  227.  
  228.         if (wallHitRight() || wallHitLeft()) {
  229.             velocity.x = velocity.x * -1;
  230.         }
  231.         if (wallHitTop() || wallHitBottom()) {
  232.             velocity.y = velocity.y * -1;
  233.         }
  234.  
  235.         for (Ball ball : theTable.ballList) {
  236.             ballCollision(ball);
  237.  
  238.         }
  239.  
  240.         if (isSick) {
  241.             ballDeadOrAlive();
  242.         }
  243.  
  244.     }
  245.    
  246.     void sick (){
  247.         isSick = true;
  248.     }
  249.    
  250.     void dead(){
  251.             isDead = true;
  252.             isSick = false;
  253.             COLOR = Color.black;
  254.             position.x = 0;
  255.             position.y = 0;
  256.             velocity = Coord.ZERO;
  257.     }
  258.    
  259.             void healthy(){
  260.             isSick = false;
  261.             COLOR = Color.white;
  262.             }
  263.  
  264.     void becomesInfected(Ball ball) {
  265.  
  266.         if (isSick && (Math.random() < PROB_INFECT) && !isDead) {
  267.             ball.isSick = true;
  268.  
  269.         }
  270.  
  271.     }
  272.  
  273.     void ballDeadOrAlive() {
  274.  
  275.         timeSick++;
  276.  
  277.         if (timeSick >= timeIncubation) {
  278.             if (Math.random() < PROB_DIE) {
  279.                 dead();
  280.             }
  281.          else {
  282.                 healthy();
  283.             }
  284.  
  285.         }
  286.  
  287.     }
  288.  
  289.     void collisionEffect(Ball otherBall) {
  290.         dx = position.x - otherBall.position.x;
  291.         dy = position.y - otherBall.position.y;
  292.         Coord d = new Coord(dx, dy);
  293.         Coord normD = d.norm();
  294.  
  295.         impuls = Coord.scal(velocity, normD) - Coord.scal(otherBall.velocity, normD);
  296.  
  297.         double New_velocityX1 = velocity.x - impuls * normD.x;
  298.         double New_velocityY1 = velocity.y - impuls * normD.y;
  299.         double New_velocityX2 = otherBall.velocity.x + impuls * normD.x;
  300.         double New_velocityY2 = otherBall.velocity.y + impuls * normD.y;
  301.  
  302.         velocity = new Coord(New_velocityX1, New_velocityY1);
  303.         otherBall.velocity = new Coord(New_velocityX2, New_velocityY2);
  304.  
  305.     }
  306.  
  307.     void ballCollision(Ball ball) {
  308.  
  309.         if (ball != this) {
  310.  
  311.             double distance = Math.sqrt(Math.pow((position.x - ball.position.x), 2) + Math.pow((position.y - ball.position.y), 2));
  312.  
  313.             double distance2 = Math.sqrt(((ball.position.x + ball.velocity.x) - (position.x + velocity.x)) * ((ball.position.x + ball.velocity.x)
  314.                     - (position.x + velocity.x)) + ((ball.position.y + ball.velocity.y) - (position.y + velocity.y))
  315.                     * ((ball.position.y + ball.velocity.y) - (position.y + velocity.y)));
  316.  
  317.             if (distance <= RADIUS * 2 && distance2 < distance) {
  318.                 collisionEffect(ball);
  319.                 becomesInfected(ball);
  320.  
  321.             }
  322.         }
  323.     }
  324.  
  325.     boolean wallHitRight() {
  326.         boolean hit = false;
  327.         if (position.x + RADIUS >= theTable.TABLE_WIDTH + theTable.WALL_THICKNESS && velocity.x > 0) {
  328.             hit = true;
  329.         }
  330.         return hit;
  331.     }
  332.  
  333.     boolean wallHitLeft() {
  334.         boolean hit = false;
  335.         if (position.x - RADIUS <= theTable.WALL_THICKNESS && velocity.x < 0) {
  336.             hit = true;
  337.         }
  338.         return hit;
  339.     }
  340.  
  341.     boolean wallHitTop() {
  342.         boolean hit = false;
  343.         if (position.y - RADIUS <= theTable.WALL_THICKNESS && velocity.y < 0) {
  344.             hit = true;
  345.         }
  346.         return hit;
  347.     }
  348.  
  349.     boolean wallHitBottom() {
  350.         boolean hit = false;
  351.         if (position.y + RADIUS >= theTable.TABLE_HEIGHT + theTable.WALL_THICKNESS && velocity.y > 0) {
  352.             hit = true;
  353.         }
  354.         return hit;
  355.     }
  356.  
  357.     void paint(Graphics2D g2D) {
  358.  
  359.         g2D.setColor(Color.black);
  360.         g2D.fillOval(
  361.                 (int) (position.x - RADIUS + 0.5),
  362.                 (int) (position.y - RADIUS + 0.5),
  363.                 (int) DIAMETER,
  364.                 (int) DIAMETER);
  365.  
  366.         if (isSick) {
  367.             g2D.setColor(COLOR_RED);
  368.         }
  369.         else {
  370.             g2D.setColor(COLOR_WHITE);
  371.  
  372.         }
  373.  
  374.         if (isDead && isSick == false) {
  375.             g2D.setColor(COLOR_BLACK);
  376.         }
  377.  
  378.         g2D.fillOval(
  379.                 (int) (position.x - RADIUS + 0.5 + BORDER_THICKNESS),
  380.                 (int) (position.y - RADIUS + 0.5 + BORDER_THICKNESS),
  381.                 (int) (DIAMETER - 2 * BORDER_THICKNESS),
  382.                 (int) (DIAMETER - 2 * BORDER_THICKNESS));
  383.  
  384.     }
  385.  
  386. } // end  class Ball
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement