# Kollisionserkennung



## Mr. P (1. Okt 2007)

hi liebe java-community

ich möchte ein spiel ähnlich turrican programmieren also son jump'n'run mit pistole die man in drei stufen ausbauen kann blablablabla was mich auch schon zu meiner frage bringt
gibt es irgendeine methode mit der ich feststellen kann ob sich zwei jLabels berühren :?:  :?: 

wenn ja währe ich sehr dankbar wenn irgendwer diese hier postet im sinne von: label.mehode(benötigte attribute);

wenn nein währe ich dankbar wenn irgendwer schon mal ne klasse dafür geschrieben hat und diese mir zukommen lässt

mfg


----------



## SlaterB (1. Okt 2007)

hey, keine Hausaufgaben 

grobe Idee: weg von JIrgendwas, es geht um zwei Rechtecke auf einer Ebene,
x/y-Koordinaten vergleichen

oder geht es dir nicht um Elemente im Spiel sonder doch eher um deine GUI?
sortiere die JLabels geeignet in einem Array, dann weißt du wo welches ist


----------



## Marco13 (1. Okt 2007)

Mr. P hat gesagt.:
			
		

> gibt es irgendeine methode mit der ich feststellen kann ob sich zwei jLabels berühren :?:  :?:


 :shock: Du hast tatsächlich vor, dein Jump'n'Run aus JComponents zusammenzustricken?  :shock: Hömbl... Um die Frage zu beantworten: Man kann sich von beiden JLabels mit "getBounds" ein Rectangle holen, und die beiden dann mit rectangle0.intersects(rectangle1) auf Überschneidungen Testen aber... ich würde dir empfehlen, da etwas anders dran zu gehen... d.h. deine Objekte lieber nicht von JLabel erben zu lassen, sondern als eigene Klassen zu machen, die z.B. ein Image enthalten, sich selbst (d.h. das Image) auf ein gegebenes Graphics-Objekt zeichnen können, und ggf. auch eine Methode anbieten, die auf Kollisionen testet...

```
class Sprite
{
    private Image image ...

    public void paintSprite(Graphics g) { g.drawImage(image...) }

    public boolean collidesWith(Sprite other) { ... return thisRectangle.intersects(otherRectangle) ... }
}
```
Naja so in etwa eben...


----------



## Mr. P (1. Okt 2007)

naja ich weiß nicht ob ich zu deinem vorschlag schon in der lage bin
gehe jez den zweiten (von fünf) jahrgang an einer edv htl und fange gerade erst an mit arrays,  static dingens, final, und so zeuch an!!

ich könnt ja mal versuchen die objekte als eigene klasse zu machen


----------



## Quaxli (2. Okt 2007)

Ich liebe es. Mit den Basics gerade angefangen haben und gleich ein Jump 'n Run programmieren wollen. Schon mal daran gedacht, mit was Harmlosen anzufangen, z. B. ein Pong-Klon oder ähnliches?

Aber sei's drum. Weiter unten meine ganz persönliche Klasse Sprite, die ich für alle bewegten Objekte nehme - auch für Jump 'n Run. Sie ist vielleicht etwas groß und an der einen oder anderen Stelle verbesserungswürdig, aber sie funktioniert gut. Ich verwende Sie, wie gesagt für alle bewegten Objekte und zwar entweder so wie sie ist oder als Vaterklasse.

Sie ist auch kein bischen dokumentiert, so daß Du gleich noch was lernen kannst , wenn Du das Teil wirklich aufdröseln willst. 
Eigentlich habe ich sie nur gepostet, damit Du siehst, worauf Du dich einläßt, wenn Du wirklich gleich mit einem Jump 'n Run einsteigen willst.


```
package de.game.sprites;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import de.game.interfaces.*;
import de.game.master.GamePanel;



public class Sprite extends Rectangle2D.Double implements Movable, Drawable, Interactive{
  
  protected GamePanel master;
  protected Image[] pics;
  
  protected int angle = 0;
  protected double dx;
  protected double dy;
  
  protected double modx = 1000000000;
  protected double mody = 1000000000;
  
  protected boolean animated = true;
  protected boolean looping  = true;
  public boolean remove      = false;
  protected boolean visible  = true;
  
  long animation = 0;
  protected int delay   = 0;
  protected int current = 0;
  int from    = 0;
  int to      = 0;
  
  Color enemycolor;
  
  AffineTransform at;
  double rotationx;
  double rotationy;


  //Konstruktor mit SpriteArray
  public Sprite(Image[] i,double x, double y, int d, GamePanel gp){
    master = gp;
    pics   = i;  
    delay  = d;
    from   = 0;
    to     = i.length - 1;
    if(pics[0]!=null){
      width  = pics[0].getWidth(null);
      height = pics[0].getHeight(null);
    }
    super.x = x;
    super.y = y;
    at = new AffineTransform();
  }
  
  //Kontruktor mit single Sprite
  public Sprite(Image i,double x, double y, int d, GamePanel gp){
    master  = gp;
    pics    = new Image[1];
    pics[0] = i;
    delay   = d;
    from    = 0;
    to      = 0;
    setAnimated(false);
    if(pics[0]!=null){
      width  = pics[0].getWidth(null);
      height = pics[0].getHeight(null);
    }
    rotationx    = width/2;
    rotationy    = height/2;
    super.x = x;
    super.y = y;
    at = new AffineTransform();
  }
  
  public void setAngle(int i) {
    angle = i;  
  }

  public int getAngle() {
    return angle;
  }

  public void doLogic(long delta) {
    
    delta /= 1000000;
    
    if(pics.length==1){
    	return;
    }
    if(isAnimated()){
      animation += delta;
      if(animation>delay){
        animation = 0;
        doAnimation();
      }
    }
  }

  public boolean isAnimated() {
    return animated;
  }

  public void setAnimated(boolean animated) {
    this.animated = animated;
  }

  public void setVerticalSpeed(double d) {
    dy = d;
  }

  public void setHorizontalSpeed(double d) {
    dx = d;
  }
  
  public int getLoopFrom() {
    return from;
  }

  public int getLoopTo() {
    return to;
  }
  
  public void setLoopFrames(int f, int t){
    from = f;
    to = t;
    current = from;
  }
  
  public int getCurrent(){
  	return current;
  }

  public void setAngleSpeed(int degree, double speed) {
    
    double rad = Math.toRadians(degree-90);
    
    double rx = Math.cos(rad) * speed;
    double ry = Math.sin(rad) * speed;
    
    setHorizontalSpeed(rx);
    setVerticalSpeed(ry);
    
  }

  public double getHorizontalSpeed() {
    return dx;
  }

  public double getVerticalSpeed() {
    return dy;
  }

  public void setX(double tx) {
    super.x = tx;
  }

  public void setY(double ty) {
    super.y = ty;
  }

  public boolean getOutLeft() {
    if(x+width<=0){
      return true;
    }
    
    return false;
  }

  public boolean getOutRight() {
    if(x>=master.getX()){
      return true;
    }
    return false;
  }

  public boolean getOutUp() {
    if(y+height<=0){
      return true;
    }
    return false;
  }

  public boolean getOutDown() {
    if(y>=master.getY()){
      return true;
    }
    
    return false;
  }

  public void move(long delta) {
    
    if(dx!=0){
      x += dx*(delta/modx);
    }
    
    if(dy!=0){
      y += dy*(delta/mody);
    }

  }

  public Rectangle2D.Double getRectangle() {
    return this;
  }

  public boolean checkCollsion(Sprite s) {
    
    if(s.getRectangle().intersects(this)){
      return true;
    }
    
    return false;
  }
  
  public boolean checkOpaqueColorCollisions(Sprite s){
    
    Rectangle2D.Double cut = (Double) this.createIntersection(s.getRectangle());
    
    if(cut.width<0||cut.height<0){
      return false;
    }
    
    if((cut.width<1)||(cut.height<1)){
      return false;
    }
    
    // Rechtecke in Bezug auf die jeweiligen Images
    Rectangle2D.Double sub_me = getSubRec( getRectangle(),cut);
    Rectangle2D.Double sub_him = getSubRec(s.getRectangle(),cut);
    
    BufferedImage img_me = getCurrentPic().getSubimage((int)sub_me.x,(int)sub_me.y,(int)sub_me.width,(int)sub_me.height);
    BufferedImage img_him = s.getCurrentPic().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 n=0;n<img_him.getHeight();n++){

        int rgb1 = img_me.getRGB(i,n);
        int rgb2 = img_him.getRGB(i,n);

        
        if(isOpaque(rgb1)&&isOpaqueAndCheckRest(rgb2)){
          return true;
        }
        
      }
    }
    
    return false;
  }
  
  public boolean checkOpaqueColorCollisions(Rectangle rec){
    
    Rectangle2D.Double cut = (Double) this.createIntersection(rec);
    
    if(cut.width<0||cut.height<0){
      return false;
    }
    
    if((cut.width<1)||(cut.height<1)){
      return false;
    }
    
    // Rechtecke in Bezug auf die jeweiligen Images
    Rectangle2D.Double sub_me = getSubRec( getRectangle(),cut);
    
    BufferedImage img_me = getCurrentPic().getSubimage((int)sub_me.x,(int)sub_me.y,(int)sub_me.width,(int)sub_me.height);
    
    for(int i=0;i<img_me.getWidth();i++){
      for(int n=0;n<img_me.getHeight();n++){

        int rgb1 = img_me.getRGB(i,n);
        
        if(isOpaque(rgb1)){
          return true;
        }
        
      }
    }
    
    return false;
  }
  
  protected boolean isOpaque(int pixel) {

    int alpha = (pixel >> 24) & 0xff;  
    //red   = (pixel >> 16) & 0xff;  
    //green = (pixel >>  8) & 0xff;  
    //blue  = (pixel ) & 0xff;  
    
    if(alpha==0){
      return false;
    }

    return true;
    
  }
  
  protected boolean isOpaqueAndCheckRest(int pixel) {

    int alpha = (pixel >> 24) & 0xff;  
    int red   = (pixel >> 16) & 0xff;  
    int green = (pixel >>  8) & 0xff;  
    int blue  = (pixel ) & 0xff;
    
    enemycolor = new Color(red,green,blue);
    
    if(alpha==0){
      return false;
    }

    return true;
    
  }

  protected Rectangle2D.Double getSubRec(Rectangle2D.Double rec1, Rectangle2D.Double inter) {
    
    //Rechtecke erzeugen
    Rectangle2D.Double sub = new Rectangle2D.Double();
    Rectangle2D.Double source =  rec1;
    Rectangle2D.Double part  =  inter;
    
    //get X - compared to the Rectangle
    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;
  }
  
  public BufferedImage getCurrentPic(){
    return (BufferedImage) pics[current];
  }

  public void collidedWith(Sprite s){
    
  }

  public void drawObject(Graphics2D g) {
  	
    if (angle != 0) {
      at.rotate(Math.toRadians(angle), x + rotationx , y + rotationy);
      g.setTransform(at);
      g.drawImage(pics[current], (int) x, (int) y, this.master);
      at.rotate(-Math.toRadians(angle), x + rotationx , y + rotationy);
      g.setTransform(at);
    } else {
      g.drawImage(pics[current], (int) x, (int) y, this.master);
    }
  }
  
  public double getRotationX() {
    return rotationx;
  }

  public void setRotationX(double rx) {
    rotationx = rx;
  }

  public double getRotationY() {
    return rotationy;
  }

  public void setRotationY(double ry) {
    rotationy = ry;
  }

  public boolean isLooping() {
    return looping;
  }

  public void setLooping(boolean looping) {
    this.looping = looping;
  }

  public void doAnimation() {
 
    if(remove){
      return;
    }
    
    current++;
 
    if(current>to){
      if(isLooping()){
        current = from;
      }else{
        current--;
        remove = true;
      }
    }
    
    width = pics[current].getWidth(null);
    height = pics[current].getHeight(null);
    
  }// do Animation

  public Color getEnemyColor() {
    return enemycolor;
  }

  public void setRotationPoint(int x, int y){
  	rotationx = x;
  	rotationy = y;
  }
  
  public Point getRotationPoint(){
  	return new Point((int)rotationx,(int)rotationy);
  }

	public int getDelay() {
		return delay;
	}

	public void setDelay(int delay) {
		this.delay = delay;
	}
  
  
  
}
```


----------

