Hey, in folgendem Programm soll eine zufällige Anzahl an 2D-Bällen erstellt werden, diese sollen wenn sie mit anderen Bällen kollidieren mit diesen verschmelzen und im Falle, das sie am Rand der Frame kommen, abprallen.
Vor allen Dingen die korrekte Kollisionsabfrage am Rand ist mir wichtig, leider geschieht es nicht selten, dass die Bälle am Rande "kleben" bleiben, da sie nicht mehr die Grenze in das Spielfeld überschreiten.
Dafür suche ich bessere Kollisionabfragen. Könnte jemand Code- oder theoretische Vorschläge geben?
Vor allen Dingen die korrekte Kollisionsabfrage am Rand ist mir wichtig, leider geschieht es nicht selten, dass die Bälle am Rande "kleben" bleiben, da sie nicht mehr die Grenze in das Spielfeld überschreiten.
Dafür suche ich bessere Kollisionabfragen. Könnte jemand Code- oder theoretische Vorschläge geben?
Java:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TheWalkerAI {
JFrame frame;
AIPanel panel;
JLabel label;
ArrayList<Walker> was;
long lastTime;
public TheWalkerAI() {
init();
while(true) {
long before = System.currentTimeMillis();
double delta = (System.currentTimeMillis() - lastTime)*0.001;
calculate(delta);
lastTime = before;
repaint();
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
label.setText( was.size() + " Walkers initialized," + " running by " + Math.round((1/delta)) + " FPS");
}
}
private void calculate(double deltatime) {
for(int i = 0; i < was.size(); ++i) {
was.get(i).checkObjectCollision(was, i);
was.get(i).step(deltatime);
}
}
private void repaint() {
label.repaint();
panel.repaint();
frame.repaint();
}
private void init() {
lastTime = System.currentTimeMillis();
frame = new JFrame();
frame.setBounds(0, 0, 1000, 1000);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.BLACK);
frame.setResizable(true);
frame.setTitle("Ellipses rolling...");
panel = new AIPanel();
frame.add(panel);
frame.addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
// TODO Auto-generated method stub
}
@Override
public void componentResized(ComponentEvent e) {
label.setLocation(0, frame.getHeight()-60);
}
@Override
public void componentMoved(ComponentEvent e) {
// TODO Auto-generated method stub
}
@Override
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
});
label = new JLabel();
label.setBounds(0, frame.getHeight()-60, 280, 20);
label.setForeground(Color.WHITE);
label.setBackground(Color.BLACK);
label.setOpaque(true);
panel.add(label);
panel.setLayout(null);
createWalkers(600, 1000, 1000,40);
}
public void createWalkers(int max, double maxspeedy, double maxspeedx, double maxradius) {
long length = (Math.round((max)*Math.random()));
was = new ArrayList<Walker>();
for(int i = 0; i < length; ++i) {
double xspeed = maxspeedx * Math.random() - 0.5*maxspeedx;
double yspeed = maxspeedy * Math.random() - 0.5*maxspeedy;
double radius = maxradius * Math.random() + 10;
was.add(new Walker(frame,new Vector(xspeed, yspeed), radius, new Vector(frame.getWidth() * Math.random(), frame.getHeight()*Math.random())));
}
}
public static void main(String[] args) {
new TheWalkerAI();
}
public class AIPanel extends JPanel {
public void paintComponent(Graphics g) {
for(int i = 0; i < was.size(); ++i) {
was.get(i).display(g);
}
}
}
}
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
public class Walker {
JFrame motherframe;
Vector pos;
double radius;
Vector speed;
Color color;
public Walker(JFrame frame, Vector speed, double radius) {
double x = frame.getWidth()/2;
double y = frame.getHeight() / 2;
pos = new Vector(x, y);
this.radius = radius;
motherframe = frame;
Random ra = new Random();
int r = ra.nextInt(256);
int cg = ra.nextInt(256);
int b = ra.nextInt(256);
color = new Color(r, cg, b);
}
public Walker(JFrame frame, Vector speed, double radius, Vector position) {
this.speed = speed;
this.radius = radius;
motherframe = frame;
this.pos = position;
Random ra = new Random();
int r = ra.nextInt(256);
int cg = ra.nextInt(256);
int b = ra.nextInt(256);
color = new Color(r, cg, b);
}
public void step(double time) {
double posaddx = speed.getX()*time;
double posaddy = speed.getY()*time;
if(pos.getX() + posaddx + radius < motherframe.getWidth() && pos.getX() + posaddx > 0 ) {
pos.setX(pos.getX()+posaddx);
}
else {
//Abstand zu Ende berechnen
//Addieren Teil von posaddx hinzu
//Subtrahieren den rest hinzu
//Negieren der Geschwindigkeit
if (speed.getX() > 0){
double r = motherframe.getWidth() - (pos.getX() + radius);
pos.setX(pos.getX()+r);
posaddx = posaddx - r; //Übriger Teil
pos.setX(pos.getX()+posaddx);
speed.setX(-speed.getX());
} else {
double r = pos.getX() - radius;
pos.setX(pos.getX()+r);
posaddx = posaddx - r; //Übriger Teil
pos.setX(pos.getX()+posaddx);
speed.setX(-speed.getX());
}
}
if(pos.getY() + posaddy + radius < motherframe.getHeight() && pos.getY() + posaddy > 0) {
pos.setY(pos.getY()+posaddy);
} else {
//Abstand zu Ende berechnen
//Addieren Teil von posaddx hinzu
//Subtrahieren den rest hinzu
//Negieren der Geschwindigkeit
if(speed.getY() >= 0) {
double r = motherframe.getHeight() - (pos.getY() + radius);
pos.setY(pos.getY()+r);
posaddy = posaddy - r; //Übriger Teil
pos.setY(pos.getY()+posaddy);
speed.setY(-speed.getY());
} else {
double r = pos.getY() - radius;
pos.setY(pos.getY()+r);
posaddy = posaddy - r; //Übriger Teil
pos.setY(pos.getY()+posaddy);
speed.setY(-speed.getY());
}
}
}
public void display(Graphics g) {
g.setColor(color);
g.fillOval((int)Math.round(pos.getX()-radius*0.5), (int)Math.round(pos.getY()-radius*0.5), (int)radius, (int)radius);
}
public void checkObjectCollision(ArrayList<Walker> was, int himself) {
for(int i = himself+1; i < was.size(); ++i) {
if(i != himself){
if((this.pos.distance(was.get(i).pos) <= this.radius + was.get(i).radius)) {
Walker wa = was.get(i);
was.remove(i);
int g = (int) Math.round((wa.color.getGreen() + this.color.getGreen()) * 0.5);
int r = (int) Math.round((wa.color.getRed() + this.color.getRed()) * 0.5);
int b = (int) Math.round((wa.color.getBlue() + this.color.getBlue()) * 0.5);
color = new Color(r,g,b);
this.radius = Math.pow(this.radius*this.radius + wa.radius*wa.radius, 0.5);
this.pos.setX((this.pos.getX()+wa.pos.getX())*0.5);
this.pos.setY((this.pos.getY()+wa.pos.getY())*0.5);
this.speed.setX((this.speed.getX()+wa.speed.getX())*0.5);
this.speed.setY((this.speed.getY()+wa.speed.getY())*0.5);
}
}
}
}
}
Java:
public class Vector extends java.awt.Point{
private static final long serialVersionUID = 5704073610770567171L;
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
double x,y;
public Vector(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public double getX() {
// TODO Auto-generated method stub
return x;
}
@Override
public double getY() {
// TODO Auto-generated method stub
return y;
}
@Override
public void setLocation(double x, double y) {
this.x = x;
this.y = y;
}
public void rotate(double angle) {
double rx = (this.x * Math.cos(angle)) - (this.y * Math.sin(angle));
double ry = (this.x * Math.sin(angle)) + (this.y * Math.cos(angle));
x = rx;
y = ry;
}
public void add(Vector v) {
this.y += v.getY();
this.x += v.getX();
}
}