# Quaxli's Heli Spiel läuft nicht nach Plan



## Sessiolog (25. Jul 2014)

System.out.println("Hallo Community!");

Seit gestern bin ich mit dem Bearbeiten von Quaxli's Game-Tutorial beschäftigt.
Das Tutorial an sich ist super, aber ich bin mir sicher, dass Quaxli schon öfter sowas gehört hat. 
Mittlerweile bin ich so ungefähr auf Seite 60 angekommen, habe es fast durch, aber so wirklich fertig werde ich damit nicht, denn irgendetwas funktioniert nicht so ganz nach Plan. Seitdem ich die Kollisionsabfrage in das Spiel eingebaut habe, passieren bei der Ausführung des Programmes mysteriöse Dinge. Der Helikopter verschwindet einfach und die Raketen verschwinden bei dem selben Punkt auf der X-Achse, an dem auch der Helikopter futsch gegangen ist.

Meinen Code habe ich mindestens 5 mal mit dem Originalen Quellcode verglichen. Alles ist da wo es sein sollte. Mein Code ist Wort für Wort, Zeile für Zeile mit dem Original identisch. Trotzdem ist der Fehler immer noch vorhanden, während die Ausführung des Originales einwandfrei läuft.
Geschrieben habe ich den Code mit Notepad++. Kompiliert und ausgeführt wird per KommandoZeile. Ich frage mich, ob es vielleicht andere Ursachen
für meine Fehlerhafte Version des Spieles gibt. Hätte da jemand Ideen? Für Lösungsvorschläge wäre ich sehr dankbar.


----------



## Androbin (30. Jul 2014)

Da du das Thema als "erledigt" markiert hast, scheinst du wohl den Fehler gefunden zu haben!
Könntest du uns bitte auch erklären, wo der Fehler lag, damit andere aus deinem Fehler lernen können?


----------



## Sessiolog (30. Jul 2014)

Klar, kann ich machen. Um das zu verstehen, wäre es sinnvoll, wenn man das Tutorial im PDF vorliegend hat. Googelt mal nach "Java Quaxli Tutorial", und ihr werdet fündig.
Die Klasse "Sprite", wie sie von Quaxli geschrieben wurde sieht wie folgt aus:


```
import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public abstract class Sprite extends Rectangle2D.Double implements Drawable, Movable{

	long delay;
	long animation = 0;
	GamePanel parent;
	BufferedImage[] pics;
	int currentpic = 0;
  
	protected double dx;
	protected double dy;
	
	int loop_from;
	int loop_to;
	
	boolean remove;
	
	public Sprite(BufferedImage[] i, double x, double y, long delay, GamePanel p ){
		pics = i;
		this.x = x;
		this.y = y;
		this.delay = delay;
		this.width = pics[0].getWidth();
		this.height = pics[0].getHeight();
	  parent = p;
	  loop_from = 0;
	  loop_to = pics.length-1;
	}
	
	public void drawObjects(Graphics g) {
		g.drawImage(pics[currentpic], (int) x, (int) y, null);
	}

	public void doLogic(long delta) {
		
		animation += (delta/1000000);
		if (animation > delay) {
			animation = 0;
			computeAnimation();
		}
		
	}

	private void computeAnimation(){
    
		currentpic++;

    if(currentpic>loop_to){
        currentpic = loop_from;
    }
		
	}
		
	public void setLoop(int from, int to){
		loop_from = from;
		loop_to   = to;
		currentpic = from;
	}
	
	public void move(long delta) {
		
    if(dx!=0){
      x += dx*(delta/1e9);
    }
    
    if(dy!=0){
      y += dy*(delta/1e9);
    }
    
	}
	
	public double getHorizontalSpeed() {
		return dx;
	}

	public void setHorizontalSpeed(double dx) {
		this.dx = dx;
	}

	public double getVerticalSpeed() {
		return dy;
	}

	public void setVerticalSpeed(double dy) {
		this.dy = dy;
	}

	public abstract boolean collidedWith(Sprite s);
	
  public boolean checkOpaqueColorCollisions(Sprite s){
    
    Rectangle2D.Double cut = (Double) this.createIntersection(s);
    
    if((cut.width<1)||(cut.height<1)){
      return false;
    }
    
    // Rechtecke in Bezug auf die jeweiligen Images
    Rectangle2D.Double sub_me = getSubRec(this,cut);
    Rectangle2D.Double sub_him = getSubRec(s,cut);
    
    BufferedImage img_me = pics[currentpic].getSubimage((int)sub_me.x,(int)sub_me.y,
    													(int)sub_me.width,(int)sub_me.height);
    BufferedImage img_him = s.pics[s.currentpic].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)&&isOpaque(rgb2)){
          return true;
        }
        
      }
    }
    
    return false;
  }
  
  protected Rectangle2D.Double getSubRec(Rectangle2D.Double source, Rectangle2D.Double part) {
    
    //Rechtecke erzeugen
    Rectangle2D.Double sub = new Rectangle2D.Double();
    
    //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;
  }
  
  protected boolean isOpaque(int rgb) {

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

    return true;
    
  }
}
```
Bei mir hat dieser Code allerdings nicht so funktioniert, weshalb ich probehalber noch Set/Get Methoden dazugeschrieben habe. Also:

```
public void setX(double x) {
		this.x = x;
	}
	
	public void setY(double y) {
		this.y = y;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
```
Mit den 4 neuen Methoden funktioniert alles einwandfrei. Seltsam, wenn ihr mich fragt, schließlich erbt Sprite ja von Rectangle2D.Double und sollte daher diese Methoden von vornherein implizieren. Mysteriös, mysteriös.


----------

