Package inheritance

Source Code of inheritance.Asteroids

package inheritance;

import java.util.ArrayList;
import java.util.List;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.util.Duration;

public class Asteroids extends Pane implements EventHandler<KeyEvent>  {

  private List<SpaceObject> spaceObjects;
 
  protected void add(SpaceObject so, double x, double y) {
    so.translate(x, y);
    getChildren().add(so);
    spaceObjects.add(so);
  }

  protected void remove(SpaceObject so) {
    getChildren().remove(so);
    spaceObjects.remove(so);
  }
 
  public void init() {
    spaceObjects = new ArrayList<SpaceObject>();
  }

  public void run() {
    Timeline tickTimer = new Timeline(new KeyFrame(Duration.millis(50), new EventHandler<ActionEvent>() {
      private int tickCount = 0;
      @Override
      public void handle(ActionEvent event) {
        tick(tickCount++);
      }
    }));
    tickTimer.setCycleCount(Timeline.INDEFINITE);
    tickTimer.play();
    requestFocus();
    setOnKeyPressed(this);
    setOnKeyTyped(this);
  }

  protected void handleKey(KeyCode keyCode) {
  }

  /*
   * Used for pausing or stepping
   */
  private int steps = -1;
 
  protected void handleKey(String character) {
    if ("+".equals(character)) {
      zoom(2);
    } else if ("-".equals(character)) {
      zoom(0.5);
    } else if (" ".equals(character)) {
      // toggle steps
      steps = (steps < 0 ? 0 : -1);
    } else if (">".equals(character)) {
      // one step
      steps = 1;
    }
  }
 
  private void zoom(double factor) {
    setScaleX(getScaleX() * factor);
    setScaleY(getScaleY() * factor);
  }
 
  @Override
  public void handle(KeyEvent keyEvent) {
    if (keyEvent.getCode() == KeyCode.UNDEFINED) {
      handleKey(keyEvent.getCharacter());
    } else {
      handleKey(keyEvent.getCode());
    }
  }

  private void tick(int tickCount) {
   
    if (steps == 0) {
      return;
    } else if (steps > 0) {
      steps--;
    }
   
    // accelerate due to gravity
    for (int i = 0; i < spaceObjects.size(); i++) {
      for (int j = i + 1; j < spaceObjects.size(); j++) {
        handleGravity(spaceObjects.get(i), spaceObjects.get(j));
      }
    }

    // move all objects
    for (SpaceObject spaceObject : spaceObjects) {
      spaceObject.tick();
    }
   
    // check for collision
    List<SpaceObject> collisions = new ArrayList<SpaceObject>();
    for (int i = 0; i < spaceObjects.size(); i++) {
      for (int j = i + 1; j < spaceObjects.size(); j++) {
        SpaceObject spaceObject1 = spaceObjects.get(i), spaceObject2 = spaceObjects.get(j);
        if (spaceObject1.intersects(spaceObject2)) {
          collisions.add(spaceObject1);
          collisions.add(spaceObject2);
        }
      }
    }
    for (SpaceObject spaceObject : spaceObjects) {
      if (! collisions.contains(spaceObject)) {
        handleCollision(spaceObject, null);
      }
    }
    for (int i = 0; i < collisions.size(); i += 2) {
      SpaceObject spaceObject1 = collisions.get(i), spaceObject2 = collisions.get(i + 1);
      handleCollision(spaceObject1, spaceObject2);
    }
  }
 
  public void handleGravity(SpaceObject spaceObject1, SpaceObject spaceObject2) {
    if (spaceObject1.getMass() * spaceObject2.getMass() != 0) {
      Point2D d = sub(spaceObject2.getCenter(true), spaceObject1.getCenter(true));
      double d2 = d.getX() * d.getX() + d.getY() * d.getY(), dist = Math.sqrt(d2);
      double force = spaceObject1.getMass() * spaceObject2.getMass() / d2;
      spaceObject1.applyForce(force * d.getX() / dist, force * d.getY() / dist);
      spaceObject2.applyForce(force * (- d.getX()) / dist, force * (- d.getY()) / dist);
    }
  }
 
  //

  private Point2D add(Point2D p1, Point2D p2) {
    return new Point2D(p2.getX() + p1.getX(), p2.getY() + p2.getY());
  }

  private Point2D sub(Point2D p1, Point2D p2) {
    return new Point2D(p1.getX() - p2.getX(), p1.getY() - p2.getY());
  }

  private Point2D mult(Point2D p, double d) {
    return new Point2D(p.getX() * d, p.getY() * d);
  }

  private Point2D div(Point2D p, double d) {
    return new Point2D(p.getX() / d, p.getY() / d);
  }

  private double dist(Point2D p) {
    return Math.sqrt(p.getX() * p.getX() + p.getY() * p.getY());
  }
 
  private double dot(Point2D p1, Point2D p2) {
    return p1.getX() * p2.getX() + p1.getY() * p2.getY();
  }
 
  private void setSpeed(SpaceObject so, Point2D speed) {
    so.setSpeed(speed.getX(), speed.getY());
  }

  // http://stackoverflow.com/questions/345838/ball-to-ball-collision-detection-and-handling
  public void handleCollision(SpaceObject so1, SpaceObject so2) {
    if (so2 == null) {
      so1.setStroke(null);
    } else {
      so1.setStroke(Color.RED);
      so2.setStroke(Color.RED);
      if (so1 instanceof Star || so2 instanceof Star) {
        handleInelasticCollision(so1, so2);
      } else {
        handleElasticCollision(so1, so2);
      }
    }
  }

  private void handleElasticCollision(SpaceObject so1, SpaceObject so2) {
    // diff = so1.center - so2.center
    Point2D diff = sub(so1.getCenter(true), so2.getCenter(true));
    // d = diff / diff.length
    Point2D d = div(diff, dist(diff));
    // u1 = so1.speed * d, u2 = so2.speed * d
    double u1 = dot(so1.getSpeed(), d), u2 = dot(so2.getSpeed(), d);
    double md12 = so1.getMass() - so2.getMass(), ms12 = so1.getMass() + so2.getMass();
    double v1 = (u1 * md12 + 2 * so2.getMass() * u2) / ms12;
    double v2 = (u2 * (- md12) + 2 * so1.getMass() * u1) / ms12;
    // so1.speed += (v1 - u1) * d
    setSpeed(so1, add(so1.getSpeed(), mult(d, (v1 - u1))));
    // so2.speed += (v2 - u2) * d
    setSpeed(so2, add(so2.getSpeed(), mult(d, (v2 - u2))));
  }

  private void handleInelasticCollision(SpaceObject so1, SpaceObject so2) {
    // so1.speedX = (so1.speed * so1.mass + so2.speed * so2.mass) / (so1.mass + s02.mass)
    setSpeed(so1, div(add(mult(so1.getSpeed(), so1.getMass()), mult(so2.getSpeed(), so2.getMass())), so1.getMass() + so2.getMass()));
    remove(so2);
  }
 
  //

  public static void main(String[] args) {
    AsteroidsProgram.main(new String[]{inheritance.Asteroids.class.getName()});
  }
}
TOP

Related Classes of inheritance.Asteroids

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.