Hi Leute,
ich beschäftige mich nun schon seit geraumer Zeit mit mit der Kollisionserkennung aus dem Tutorial hier. Prinzipiell hab ich die Funktionsweiße auch verstanden, allerdings gibt es einige kleine Probleme bei der Kollisionserkennung.
Ich lasse Autos "fahren" und vor ihnen ein Kollisionsobjekt, welches überprüft, ob eine Kollision stattfinden würde, demnach stoppt das Auto...
In X-Richtung funktioniert das ganze auch Prima, allerdings kommt es zu Problemen bei den Autos, welche sich auf den Y-Koordinaten bewegen. Vllt. habt ihr ja einen Rat:
GamePanel:
Vehicle:
Collision:
Das sind meine bisherigen Klassen - wahrscheinlich stehe ich einfach aufm Schlauch xD
ich beschäftige mich nun schon seit geraumer Zeit mit mit der Kollisionserkennung aus dem Tutorial hier. Prinzipiell hab ich die Funktionsweiße auch verstanden, allerdings gibt es einige kleine Probleme bei der Kollisionserkennung.
Ich lasse Autos "fahren" und vor ihnen ein Kollisionsobjekt, welches überprüft, ob eine Kollision stattfinden würde, demnach stoppt das Auto...
In X-Richtung funktioniert das ganze auch Prima, allerdings kommt es zu Problemen bei den Autos, welche sich auf den Y-Koordinaten bewegen. Vllt. habt ihr ja einen Rat:
GamePanel:
Java:
package kreuzung;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
public JFrame frame;
public double delta=0; //zur Errechnung der Zeit, die für den letzten Durchlauf benötigt wurde
public double last=0; //Speicherung der letzten Systemzeit
public double fps=0; //Bilder pro Sekunde
public boolean debug=true;
public boolean gameflag=false;
public ArrayList<Vehicle> cars;
public ArrayList<Collision> collisions;
public ArrayList<BufferedImage> carpics;
public ArrayList<BufferedImage> tiles;
public static void main(String[] args) {
new GamePanel(715, 715);
}
public GamePanel(int w, int h) {
doInitializations();
this.setBackground(Color.LIGHT_GRAY);
frame = new JFrame("Vekehrssimulation - by Nicolas Maier - FPS: "+fps);
frame.setLocation(100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setSize(w, h);
frame.setVisible(true);
gameflag=true;
Thread GameLoop=new Thread(this);
GameLoop.start();
}
public void doInitializations() {
last=System.nanoTime(); //Messe aktuelle Systemzeit in Nanosekunden (notwendig für die Berechnungn von delta)
carpics=new ArrayList<BufferedImage>(); //Erzeuge konkrete Liste (Autobilder)
carpics.add(loadPic("gfx/Car1.png")); //Füge der Liste 1 Autobild hinzu
carpics.add(loadPic("gfx/Car2.png")); //Füge der Liste 1 Autobild hinzu
carpics.add(loadPic("gfx/Car3.png")); //Füge der Liste 1 Autobild hinzu
carpics.add(loadPic("gfx/Car4.png")); //Füge der Liste 1 Autobild hinzu
cars=new ArrayList<Vehicle>(); //Erzeuge konkrete Liste (Autos)
cars.add(new Vehicle(-55, 385, 2, carpics.get(0))); //Füge der Liste 1 Auto hinzu
cars.add(new Vehicle(-115, 385, 1, carpics.get(1))); //Füge der Liste 1 Auto hinzu
cars.add(new Vehicle(-175, 385, 1, carpics.get(1))); //Füge der Liste 1 Auto hinzu
cars.add(new Vehicle(220, -55, 6, carpics.get(2))); //Füge der Liste 1 Auto hinzu
cars.add(new Vehicle(220, -115, 7, carpics.get(3))); //Füge der Liste 1 Auto hinzu
BufferedImage collision=loadPic("gfx/Collision.png");
collisions=new ArrayList<Collision>();
for(int i=0;i<cars.size();i++) {
collisions.add(new Collision((int) cars.get(i).x, (int) cars.get(i).y, cars.get(i).getPath(), collision));
}
tiles=new ArrayList<BufferedImage>(); //Erzeuge konkrete Liste (Tiles)
tiles.add(loadPic("gfx/RightArrow.png")); //Füge der Liste den, Rechtspfeil hinzu
tiles.add(loadPic("gfx/Tree1.png")); //Füge der Liste den, Busch #1 hinzu
tiles.add(loadPic("gfx/Tree2.png")); //Füge der Liste den, Busch #2 hinzu
}
public void run() {
while(gameflag) {
repaint();
moveObjects();
doLogic();
computeDelta();
frame.setTitle("Vekehrssimulation - by Nicolas Maier - FPS: "+fps);
try {
Thread.sleep(1);
} catch (InterruptedException e) {}
}
}
public void doLogic() {
for(int i=0;i<cars.size();i++) {
collisions.get(i).changeSpeed(+1);
cars.get(i).setSpeed(collisions.get(i).getSpeed());
}
for(int j=0;j<collisions.size();j++) {
for(int i=0;i<cars.size();i++) {
if(i!=j) {
if(collisions.get(j).checkCollision(cars.get(i))) {
collisions.get(j).changeSpeed(-2);
cars.get(j).setSpeed(collisions.get(j).getSpeed());
}
}
}
}
}
public void moveObjects() {
for(int i=0;i<collisions.size();i++) {
collisions.get(i).move(delta);
}
for(int i=0;i<cars.size();i++) {
cars.get(i).move(delta);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g); //Führe Konstruktor der Methode aus
//Zeichnen der Debug-Linien
if(debug) {
g.setColor(Color.black);
for(int i=0;i<=715;i+=55) {
g.drawLine(i, 0, i, 715);
}
for(int i=0;i<=715;i+=55) {
g.drawLine(0, i, 715, i);
}
}
//Zeichnen der Straßen
g.setColor(Color.gray);
g.fillRect(4*55, 4*55, 5*55, 5*55);
for(int j=0;j<4;j++) {
for(int i=4;i<9;i++) {
g.setColor(Color.gray);
if(i==6)
g.setColor(Color.LIGHT_GRAY);
g.fillRect(i*55, j*55, 55, 55);
}
}
for(int j=0;j<4;j++) {
for(int i=4;i<9;i++) {
g.setColor(Color.gray);
if(i==6)
g.setColor(Color.LIGHT_GRAY);
g.fillRect(i*55, 660-j*55, 55, 55);
}
}
for(int j=0;j<4;j++) {
for(int i=4;i<9;i++) {
g.setColor(Color.gray);
if(i==6)
g.setColor(Color.LIGHT_GRAY);
g.fillRect(660-j*55, i*55, 55, 55);
}
}
for(int j=0;j<4;j++) {
for(int i=4;i<9;i++) {
g.setColor(Color.gray);
if(i==6)
g.setColor(Color.LIGHT_GRAY);
g.fillRect(j*55, i*55, 55, 55);
}
}
//Zeichnen der Debug-Pfade
g.setColor(Color.red);
//path 1
for(int x=165;x<=385;x++) {
int y=165+(int) (Math.pow(Math.pow(221, 2)-Math.pow(x-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
for(int y=385;y>165;y--) {
int x=165+(int) (Math.pow(Math.pow(221, 2)-Math.pow(y-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 2
for(int x=165;x<=440;x++) {
int y=165+(int) (0.8*Math.pow(Math.pow(276, 2)-Math.pow(x-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
for(int y=385;y>165;y--) {
int x=165+(int) (Math.pow(Math.pow(276, 2)-Math.pow((y-165)*1.25, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 3
for(int x=165;x<=495;x++) {
int y=440;
g.fillRect(x, y, 2, 2);
}
//path 4
for(int x=165;x<=220;x++) {
int y=495-(int) (Math.pow(Math.pow(55, 2)-Math.pow(x-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 5
for(int x=165;x<=275;x++) {
int y=495-(int) (0.5*Math.pow(Math.pow(110, 2)-Math.pow(x-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 6
for(int x=275;x<=495;x++) {
int y=(int) (165+1.25*Math.pow(Math.pow(221, 2)-Math.pow(x-495, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
for(int y=165;y<=440;y++) {
int x=(int) (495-Math.pow(Math.pow(221, 2)-Math.pow((y-165)*0.8, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 7
for(int x=275;x<=495;x++) {
int y=165+(int) (Math.pow(Math.pow(221, 2)-Math.pow(x-496, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
for(int y=165;y<=385;y++) {
int x=(int) (496-Math.pow(Math.pow(221, 2)-Math.pow(y-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
//path 8
for(int y=165;y<=495;y++) {
int x=220;
g.fillRect(x, y, 2, 2);
}
for(int y=165;y<=220;y++) {
int x=165+(int) (Math.pow(Math.pow(55, 2)-Math.pow(y-165, 2), 0.5));
g.fillRect(x, y, 2, 2);
}
g.drawImage(tiles.get(2), 310, -10, this);
g.drawImage(tiles.get(2), 310, 65, this);
g.drawImage(tiles.get(2), 310, 140, this);
g.drawImage(tiles.get(2), 570, 310, this);
g.drawImage(tiles.get(1), 480, 310, this);
g.drawImage(tiles.get(1), 640, 310, this);
for(int i=0;i<cars.size();i++) {
cars.get(i).draw(g); //Zeichne die Autos
if(debug)
((Graphics2D)g).draw(cars.get(i));
}
if(debug) {
for(int i=0;i<collisions.size();i++) {
collisions.get(i).draw(g); //Zeichne die Kollisionsobjekte
((Graphics2D)g).draw(collisions.get(i));
}
}
}
public void computeDelta() {
delta = System.nanoTime()-last;
last = System.nanoTime();
fps = ((double) 1e9)/delta;
}
public BufferedImage loadPic(String path) {
BufferedImage source = null;
try {
source = ImageIO.read(new File(path));
} catch(IOException e) {}
return source;
}
}
Vehicle:
Java:
package kreuzung;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
public class Vehicle extends Rectangle2D.Double {
protected int path=0;
protected int speed=80;
protected int speedmax=150;
protected final int VMAX=180;
protected BufferedImage pic=null;
protected double degrees=0;
public Vehicle(int x, int y, int path, BufferedImage carpic) {
this.x=x;
this.y=y;
this.path=path;
this.pic=carpic;
this.width=55;
this.height=55;
}
public void changeSpeed(int multiplier) {
speed+=multiplier*10;
if(speed>speedmax)
speed=speedmax;
if(speed<0)
speed=0;
}
public int getPath() {
return path;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed=speed;
}
public void draw(Graphics g) {
g.drawImage(rotateImage(pic), (int) x, (int) y, null);
g.setColor(Color.red);
g.fillRect((int) x, (int) y, 2, 2);
}
public BufferedImage rotateImage(BufferedImage image) {
AffineTransform affineTransform = AffineTransform.getRotateInstance(Math.toRadians(degrees), image.getWidth() / 2, image.getHeight() / 2);
BufferedImage rotatedImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
g.setTransform(affineTransform);
g.drawImage(image, 0, 0, null);
return rotatedImage;
}
public void move(double delta) {
speedmax=VMAX;
if(path==1) {
if(x<165) {
y=385;
x+=speed*(delta/1e9);
degrees=90;
}
if(x>=165 && y>=165) {
speedmax=100;
degrees=90+Math.toDegrees(Math.atan((-x+165)/Math.pow(Math.pow(221, 2)-Math.pow(x-165, 2), 0.5)));
if(degrees>=45) {
x+=speed*(delta/1e9);
y=165+Math.pow(Math.pow(221, 2)-Math.pow(x-165, 2), 0.5);
} else {
x=165+Math.pow(Math.pow(221, 2)-Math.pow(y-165, 2), 0.5);
y-=speed*(delta/1e9);
}
}
if(y<165) {
x=385;
y-=speed*(delta/1e9);
degrees=0;
}
}if(path==2) {
if(x<165) {
y=385;
x+=speed*(delta/1e9);
degrees=90;
}
if(x>=165 && y>=165) {
speedmax=100;
degrees=90+Math.toDegrees(Math.atan((0.8*(-x+165))/Math.pow(Math.pow(276, 2)-Math.pow(x-165, 2), 0.5)));
if(degrees>=45) {
x+=speed*(delta/1e9);
y=165+0.8*Math.pow(Math.pow(276, 2)-Math.pow(x-165, 2), 0.5);
} else {
x=165+Math.pow(Math.pow(276, 2)-Math.pow((y-165)*1.25, 2), 0.5);
y-=speed*(delta/1e9);
}
}
if(y<165) {
x=440;
y-=speed*(delta/1e9);
degrees=0;
}
}
if(path==6) {
if(y<165) {
x=275;
y+=speed*(delta/1e9);
degrees=180;
}
if(y>=165 && y<440) {
speedmax=100;
degrees=90+Math.toDegrees(Math.atan((1.25*(-x+495))/Math.pow(Math.pow(221, 2)-Math.pow(x-495, 2), 0.5)));
if(degrees>=135) {
x=496-Math.pow(Math.pow(221, 2)-Math.pow((y-165)*0.8, 2), 0.5);
y+=speed*(delta/1e9);
} else {
x+=speed*(delta/1e9);
y=165+1.25*Math.pow(Math.pow(221, 2)-Math.pow(x-495, 2), 0.5);
}
}
if(y>=440) {
x+=speed*(delta/1e9);
y=440;
degrees=90;
}
}
if(path==7) {
if(y<165) {
x=275;
y+=speed*(delta/1e9);
degrees=180;
}
if(y>=165 && y<385) {
speedmax=100;
degrees=90+Math.toDegrees(Math.atan((-x+495)/Math.pow(Math.pow(221, 2)-Math.pow(x-495, 2), 0.5)));
if(degrees>=135) {
x=495-Math.pow(Math.pow(221, 2)-Math.pow(y-165, 2), 0.5);
y+=speed*(delta/1e9);
} else {
x+=speed*(delta/1e9);
y=165+Math.pow(Math.pow(221, 2)-Math.pow(x-495, 2), 0.5);
}
}
if(y>=385) {
x+=speed*(delta/1e9);
y=385;
degrees=90;
}
}
if(path==8) {
if(y<220) {
x=220;
y+=speed*(delta/1e9);
degrees=180;
}
if(y>=220 && y<=495) {
x=220;
y+=speed*(delta/1e9);
degrees=180;
}
if(y>495) {
x=220;
y+=speed*(delta/1e9);
degrees=180;
}
}
if(path==9) {
if(y<220) {
x=220;
y+=speed*(delta/1e9);
degrees=180;
}
if(y>=220 && x>=165) {
y=220;
x-=speed*(delta/1e9);
if(degrees<270)
degrees+=270*(delta/1e9);
}
if(x<165) {
y=220;
x-=speed*(delta/1e9);
degrees=270;
}
}
}
}
Collision:
Java:
package kreuzung;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
public class Collision extends Vehicle {
public Collision(int x, int y, int path, BufferedImage pic) {
super(x, y, path, pic);
this.width=55;
this.height=55;
calculateXY();
}
public void calculateXY() {
switch((int) (this.path/6)) {
case 0:
this.x+=20;
break;
case 1:
this.y+=20;
break;
}
}
public boolean checkCollision(Vehicle sprite) {
Rectangle2D.Double cut=(Double)this.createIntersection(sprite);
if(cut.width<1 || cut.height<1)
return false;
Rectangle2D.Double sub_me=getSubRec(this, cut);
Rectangle2D.Double sub_him=getSubRec(sprite, cut);
BufferedImage img_me=pic.getSubimage((int) sub_me.x, (int) sub_me.y, (int) sub_me.width, (int) sub_me.height);
BufferedImage img_him=pic.getSubimage((int) sub_him.x, (int) sub_him.y, (int) sub_him.width, (int) sub_him.height);
for(int i=0;i<img_me.getWidth();i++) {
for(int j=0;j<img_him.getHeight();j++) {
int rgb1=img_me.getRGB(i, j);
int rgb2=img_him.getRGB(i, j);
if(isOpaque(rgb1) && isOpaque(rgb2))
return false;
}
}
return true;
}
private Rectangle2D.Double getSubRec(Rectangle2D.Double source, Rectangle2D.Double part) {
Rectangle2D.Double sub=new Rectangle2D.Double();
if(source.x>part.x)
sub.x=0;
else
sub.x=part.x-source.x;
if(source.y>part.y)
sub.y=0;
else
sub.y=part.y-source.y;
sub.width=part.width;
sub.height=part.height;
return sub;
}
private boolean isOpaque(int rgb) {
int alpha=(rgb>>24)&0xff;
if(alpha==0)
return false;
return true;
}
}
Das sind meine bisherigen Klassen - wahrscheinlich stehe ich einfach aufm Schlauch xD