Commit eb88a44e authored by Marc Feger's avatar Marc Feger

First Commit

parents
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>PhysikBalls</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
package MainApp;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import Math.BallGenerator;
import Math.MathCalc;
import Math.Physik;
import Math.Vektor2D;
import Objekts.Ball;
public class Main extends JFrame implements Runnable, MouseListener {
static final int Screen_W = 640;
static final int Screen_H = 480;
// the loop for the animation
Thread gameLoop;
// double buffered objects (smooth animation)
BufferedImage backbuffer;
Graphics2D g2d;
// Test Objects
Physik physik;
ArrayList<Object> objects;
//Ball b1;
@SuppressWarnings("unchecked")
public Main() {
/**
* Here we create the window and the regarding options
*/
super("PhysikBalls");
setSize(Screen_W, Screen_H);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/**
* Know we create the double buffered objects for a smooth
* animation.
* Then we can paint and refresh the screen smoothly.
*/
backbuffer = new BufferedImage(Screen_W, Screen_H, BufferedImage.TYPE_INT_RGB);
g2d = backbuffer.createGraphics();
/**
* Initialize the test Objects
*/
objects = (new BallGenerator(Screen_W, Screen_H)).BallList(10);
// b1 = new Ball( new Vektor2D(250, 100), new Vektor2D(1, 0), 1, 5, 5);
physik = new Physik(Screen_W, Screen_H, g2d, objects);
/**
* We start the thread in which we want to run the animation
*/
addMouseListener(this);
gameLoop = new Thread(this);
gameLoop.start();
}
@Override
public void run() {
Thread current = Thread.currentThread();
while(current == gameLoop){
try{
Thread.sleep(1000 / 30);
}catch(InterruptedException e){
e.printStackTrace();
}
updateGame();
}
}
public void updateGame(){
/**
* Start with refreshing the Screen.
* After all you have to repaint the whole
* Screen.
*/
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0,Screen_W - 1, Screen_H - 1);
for(int i = 0; i < objects.size(); i++){
//physik.gravity((Ball)objects.get(i));
physik.checkBallCollision((Ball)objects.get(i));
physik.bounceWall((Ball)objects.get(i));
((Ball)objects.get(i)).drawBody(g2d, Color.YELLOW);
((Ball)objects.get(i)).move();
}
/*
physik.gravity(b1);
physik.bounceWall(b1);
b1.drawBody(g2d, Color.RED);
b1.move();
*/
repaint();
}
public void paint(Graphics g){
g.drawImage(backbuffer, 0, 0, this);
}
public static void main(String[] args) {
new Main();
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
Random rand = new Random();
int radius = 5; //rand.nextInt( 10 ) + 1;
int xPos = e.getX();
int yPos = e.getY();
int mass = radius;
objects.add((Ball)new Ball(new Vektor2D(xPos, yPos), new Vektor2D(0, 1), 0, mass, radius));
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
package Math;
import java.util.ArrayList;
import java.util.Random;
import Objekts.Ball;
public class BallGenerator {
int Screen_W = 0, Screen_H = 0;
public BallGenerator(int Screen_W, int Screen_H) {
this.Screen_W = Screen_W;
this.Screen_H = Screen_H;
}
public ArrayList BallList(int n) {
ArrayList<Ball> BallSet = new ArrayList<>();
Random rand = new Random();
Ball currentBall;
while(BallSet.size() < n){
int radius = 5; //rand.nextInt( 10 ) + 1;
int xPos = rand.nextInt(Screen_W + 2 * radius) + radius;
int yPos = rand.nextInt(Screen_W + 2 * radius) + radius;
int xVel = rand.nextInt( 5 ) + 1;
int yVel = rand.nextInt( 5 ) + 1;
int speed = rand.nextInt( 5 );
int mass = radius;
// check if there is an similar Ball at the same position in the list
boolean contains = false;
for(int i = 0; i < BallSet.size(); i++){
Ball tmpBall = BallSet.get(i);
if(tmpBall.position().x() == xPos && tmpBall.position().y() == yPos)
contains = true;
}
if(contains == true) continue;
currentBall = new Ball(new Vektor2D(xPos, yPos), new Vektor2D(xVel, yVel), speed, mass, radius);
boolean collides = false;
for(int i = 0; i < BallSet.size(); i++){
if(currentBall.collides(BallSet.get(i)))
collides = true;
}
if(collides == true) continue;
else BallSet.add(currentBall);
}
return BallSet;
}
}
package Math;
public class MathCalc {
public MathCalc() {
}
public double roundDouble(double d, int n){
return Math.round(d * Math.pow(10, n)) / Math.pow(10, n);
}
}
package Math;
import java.awt.Graphics2D;
import java.util.ArrayList;
import Objekts.Ball;
public class Physik {
// temporary Graphics
Graphics2D g2d;
// for preventing double precision errors
MathCalc mathCalc;
// for the wall bounce
int Screen_W = 0, Screen_H = 0;
// all objects are subclasses of Object (use instance of)
ArrayList<Object> objects;
// constants
Vektor2D g = new Vektor2D(0, 1);
public Physik(int Screen_W, int Screen_H, Graphics2D g2d, ArrayList<Object> objects ) {
this.Screen_W = Screen_W;
this.Screen_H = Screen_H;
this.g2d = g2d;
// add all objects of the world
this.objects = objects;
// error protection for double precission
mathCalc = new MathCalc();
}
public void bounceWall(Object obj){
if( obj instanceof Ball){
((Ball) obj).bounceWall(Screen_W, Screen_H);
}
}
/**
* Hier muss noch eine For-Loop gespart werden
*/
public void checkBallCollision(Ball b1){
for(int i = 0; i < objects.size(); i++){
if(objects.get(i) instanceof Ball){
Ball currentBall = (Ball)objects.get(i);
if(b1.collides(currentBall) && !b1.equals(currentBall)){
elasticCollisionBalls(b1, currentBall);
}
}
}
}
public void checkWallCollision(){
for(int i = 0; i < objects.size(); i++){
if(objects.get(i) instanceof Ball)
bounceWall((Ball)objects.get(i));
}
}
public void elasticCollisionBalls(Ball b1, Ball b2){
Vektor2D v_n = b2.position().subWith(b1.position());
Vektor2D v_un = v_n.unitVektor();
Vektor2D v_ut = v_un.orthogonalVektor();
double v1n = v_un.dotProduct(b1.velocity());
double v1t = v_ut.dotProduct(b1.velocity());
double v2n = v_un.dotProduct(b2.velocity());
double v2t = v_ut.dotProduct(b2.velocity());
double v1tPrime = v1t;
double v2tPrime = v2t;
double v1nPrime = ( v1n * ( b1.mass() - b2.mass() ) + 2.0 * b2.mass() * v2n ) /
(b1.mass() + b2.mass());
double v2nPrime = ( v2n * ( b2.mass() - b1.mass() ) + 2.0 * b1.mass() * v1n ) /
(b1.mass() + b2.mass());
Vektor2D v_v1nPrime = v_un.mulWith(v1nPrime);
Vektor2D v_v1tPrime = v_ut.mulWith(v1tPrime);
Vektor2D v_v2nPrime = v_un.mulWith(v2nPrime);
Vektor2D v_v2tPrime = v_ut.mulWith(v2tPrime);
b1.velocity().setX( v_v1nPrime.x() + v_v1tPrime.x());
b1.velocity().setY( v_v1nPrime.y() + v_v1tPrime.y());
b2.velocity().setX( v_v2nPrime.x() + v_v2tPrime.x());
b2.velocity().setY( v_v2nPrime.y() + v_v2tPrime.y());
// do some correction for keeping the double precision
b1.velocity().setX( mathCalc.roundDouble(b1.velocity().x, 14));
b1.velocity().setY( mathCalc.roundDouble(b1.velocity().y, 14));
b2.velocity().setX( mathCalc.roundDouble(b2.velocity().x, 14));
b2.velocity().setY( mathCalc.roundDouble(b2.velocity().y, 14));
b1.move();
b2.move();
}
public void gravity(Ball b1){
b1.velocity().setX(b1.velocity().x() + g.x());
b1.velocity().setY(b1.velocity().y() + g.y());
if(b1.position().y() + b1.radius() > Screen_H){
b1.position().setY(b1.position().y() + 2*b1.radius() - 1);
}
}
}
package Math;
public class Vektor2D {
// The x and y Coordinates
double x = 0, y = 0;
public Vektor2D(double x, double y) {
this.x = x;
this.y = y;
}
public Vektor2D(){}
// get / set Methods
public double x() { return x; }
public double y() { return y; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
public double magnitude() { return Math.sqrt(Math.pow(x,2) + Math.pow(y, 2)); }
public double dotProduct( Vektor2D v) { return (x * v.x()) + (y * v.y()); }
// return Methods
public Vektor2D addWith(Vektor2D v) { return new Vektor2D(x + v.x(), y + v.y()); }
public Vektor2D subWith(Vektor2D v) { return new Vektor2D(x - v.x(), y - v.y()); }
public Vektor2D mulWith(double fak) { return new Vektor2D(x * fak , y * fak ); }
public Vektor2D unitVektor() { return new Vektor2D(x, y).mulWith(1/magnitude()); }
public Vektor2D orthogonalVektor() { return new Vektor2D(-y, x); }
// printer Methods
public void printVektor(){
System.out.format("Vektor: %s [ %f, %f]\n", this, x(), y());
}
}
package Objekts;
import java.awt.Color;
import java.awt.Graphics2D;
import Math.MathCalc;
import Math.Vektor2D;
public class Ball extends Object{
double speed = 1;
double mass = 1;
double radius = 1;
double size = 2 * radius;
Vektor2D velocity = new Vektor2D();
Vektor2D position = new Vektor2D();
Vektor2D acceleration = new Vektor2D();
public Ball(Vektor2D position, Vektor2D velocity, double speed, double mass, double radius) {
this.position = position;
this.velocity = velocity;
this.speed = speed;
this.mass = mass;
this.radius = radius;
size = 2 * radius;
// set the position to the center
this.position.setX(position.x() );
this.position.setY(position.y() );
// given is a direktion, normalize it and give it the speed
this.velocity = this.velocity.unitVektor().mulWith(speed);
}
// get / set Methoden
public double speed() { return this.speed; }
public double mass() { return this.mass ; }
public double radius(){ return this.radius;}
public double size() { return this.size; }
public Vektor2D position(){ return this.position; }
public Vektor2D velocity(){ return this.velocity; }
public void setVelocity(Vektor2D velocity) { this.velocity = velocity; }
public void setSpeed(double speed) { this.speed = speed;}
public void setMass(double mass) { this.mass = mass; }
public void setRadius(double radius){ this.radius = radius; }
public void setSize(double size){ this.size = size; setRadius(size/2); }
// Draw and Move Methods
public boolean collides(Ball b){
double dist = Math.sqrt( Math.pow( (b.position.x() - position.x()), 2 ) +
Math.pow( (b.position.y() - position.y()), 2)) ;
dist = dist - (b.radius + radius);
if(dist <= 0) return true;
else return false;
}
public void drawBody(Graphics2D g2d, Color color){
g2d.setColor(color);
g2d.fillOval((int)position.x() - (int)radius, (int)position.y() - (int)radius, (int)size, (int)size);
//this.drawCenter(g2d, Color.RED);
}
public void drawCenter(Graphics2D g2d, Color color){
g2d.setColor(color);
g2d.drawLine((int)position.x() - 2, (int)position.y(), (int)position.x() + 2, (int)position.y());
g2d.drawLine((int)position.x(), (int)position.y() - 2, (int)position.x(), (int)position.y() + 2);
}
public void bounceWall(int Screen_W, int Screen_H){
if(position.x() - radius() <= 0 || position.x() + radius() >= Screen_W + 10)
velocity.setX(velocity.x() * (-1));
if(position.y() - radius() <= 0 || position.y() + radius() >= Screen_H - 20)
velocity.setY(velocity.y() * (-1));
}
public void move(){
// add acceleration to velocity
velocity.setX(velocity.x() + acceleration.x());
velocity.setY(velocity.y() + acceleration.y());
position.setX(position.x() + velocity.x());
position.setY(position.y() + velocity.y());
// maybe it is important to correct the position by using MathCalc
position.setX((new MathCalc()).roundDouble(position.x(), 13));
position.setY((new MathCalc()).roundDouble(position.y(), 13));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment