Kollision für Arkanoid

  • Themenstarter Themenstarter frozen-man
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
F

frozen-man

Gast
Hallo
Ich schreibe gerade einen Arkanoid Klon und bin aufgrund von problemen mit der Kollisionsüberprüfung schon ziemlich frustriert.
Ich poste einfach mal meinen Code, vieleicht hat ja irgendjemand eine Ahnung wieso das nicht richtig funktioniert.
Die Logik die dahinter steckt ist folgende:
Ich berechne von jedem stein die Kollisionszeiten mit oben, unten, links und rechts (Seiten vom Stein).
Dann prüfe ich ob das t >0 und <1 ist (1 bedeutet einen ganzen Bewegungsschritt und 0 keine Bewegung),
berechne die neue Position und überprüfe ob der Ball an einer der Kanten auftrifft und starte die kollisionsbehandlung

Vielen Dank schon mal im Vorraus

Gruß

Tobi

Code:
 public void pruefeKollisionStein(){
        double t=kleinstesT();
        this.ballxPos = neuePos(ballxPos, richtungx, t);
        this.ballyPos = neuePos(ballyPos, richtungy, t);
        ball.setxPos(ballxPos);
        ball.setyPos(ballyPos);
        
        kollisionStein();
            
    	
    	}


 public double kleinstesT(){
       double t, speicher =1;
       this.ballxPos = ballxPos - richtungx;
       this.ballyPos = ballyPos - richtungy;
       for(int i=0; stein[i]!=null; i++){
           if(stein[i].vorhanden == true){
               int oben = stein[i].getOben();
               int unten = stein[i].getUnten();
               int links = stein[i].getLinks();
               int rechts = stein[i].getRechts();
               
               // für Kollision mit "Unten"
               t = tBerechnen(ballyPos, richtungy, unten);
               if((t>0)&& (t < 1)){
                   if(imBereich(neuePos(ballxPos, richtungx, t),links, rechts)){
                       if(t<speicher){
                           speicher = t;
                       }
                   }
               }
	       // für Kollision mit "Oben"
               t=tBerechnen((ballyPos+ballRadius), richtungy, oben);
               if((t>0) && (t<1)){
                   if(imBereich(neuePos(ballxPos, richtungx, t),links, rechts)){
                       if(t<speicher){
                           speicher = t;
                       }
                   }
               }
 		
               if(richtungx!= 0){
		   // für Kollision mit "Links"
                   t=tBerechnen((ballxPos+ballRadius), richtungx, links);
                       if((t>0) && (t<1)){
                           if(imBereich(neuePos(ballyPos, richtungy, t), oben, unten)){
                               if(t<speicher){
                                   speicher=t;
                               }
                           }
                       }
		       // für Kollision mit "Rechts"
                       t=tBerechnen(ballxPos, richtungx, rechts);
                       if((t>0) && (t<1)){
                           if(imBereich(neuePos(ballyPos, richtungy, t), oben, unten)){
                               if(t<speicher){
                                   speicher=t;
                       
                   
                               	}
                           }
               
                       }
               }
           }
       }
       
       return speicher;
   }


private int neuePos(int aktPos, int richtung, double t) {
    
    return (int)(aktPos + (t*richtung));
}


private double tBerechnen(int aktPos, int richtung, int konst) {
    double wert = 0.0;
    wert+= ((konst-aktPos)/(double)richtung);
    return wert;
}
private boolean imBereich(int x, int kleinerWert, int großerWert){
    if(((x+ballRadius) >= kleinerWert) && (x <= großerWert)){
        return true;
    }
    else
        return false;
}
 
hm, also ich kenne jetzt das Spiel nicht, aber was passiert denn wenn sich zwei Steine aufeinander zubewegen? Ist das auch beruecksichtigt?
 
Hallo frozen-man!

Deine Aktion mit dem Arkanoid Clone finde ich eine coole Sache - bin selber ein großer Fan von alten Arkade-Spielen. Deshalb hab ich in den letzten Tagen auch noch einmal Galaga gecloned (ebenfalls in Java). Da dort auch die Kolision mit einem anderen Raumschiff berücksichtigt werden muss, sollten die Quellcodes also ähnlich aussehen. Die effizienteste und kürzeste Möglichkeit, einen Gegner (oder Stein in deinem Fall) zu realisieren erschien mir deshalb diese als Klasse zu definieren. Dies bietet dir den unschlagbaren Vorteil, dass jeder Stein eine Methode implementieren kann, die darauf aufpasst, ob er dein Raumschiff gerammt hat. Darüber hinaus kannst du auch noch rel. bequem am Anfang deines Codes ein Array an Steinen erzeugen.

In code übersetzt sähe dies dann wie folgt aus:

Code:
		public void lookup(int ship_x, int ship_y, int ship_w, int ship_h) {
			int current_x, current_y;
			for(current_x=this.s_x, current_y=this.s_y; current_x<this.s_x+this.s_width; current_x++)
				if(current_x>ship_x && current_x<(ship_x+ship_w) && current_y>ship_y && current_y<(ship_y+ship_w))
					looser_screen(myGraphics);
			for(current_x=this.s_x, current_y=this.s_y+this.s_height; current_x<this.s_x+this.s_width; current_x++)
				if(current_x>ship_x && current_x<(ship_x+ship_w) && current_y>ship_y && current_y<(ship_y+ship_w))
					looser_screen(myGraphics);
		}

Die Methode lookup könntest du theoretisch in eine Klasse "Stein" implementieren. Diese bräuchte als Argumente lediglich die aktuelle Positioin deines Schiffes (ship_x, ship_y) sowie dessen Breite und Höhe (ship_w, ship_h). Die Feldvariablen this.s_x, this.s_y sowie this.s_width und this.s_height geben dabei die Koordinaten sowie die Breite des Gegners an. Damit stehen dir alle Werte zur Verfügung, um eine mögliche Kolision abzufragen. Du müsstest alleine nur noch darüber nachdenken, ob du in die obige Methode noch zwei weitere Schleifen implementierst, um eine Kolision an der linken und an der rechten Seite abzufragen. Bei mir ging es aber auch ohne den Mehraufwand.

Noch viel Erfog bei deinem kleinen Projekt
Zaphod
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben