Zur Themenübersicht        

Billardprojekt: Fangboxen und Reflexionboxen

Lösungen

Fangboxen

Es gibt auch hier nicht DIE richtige Lösung. Ein mögliches Lösungsprojekt mit zwei Spielfeldern mit jeweils einer Fangbox und zwei Bällen findet sich hier.

Das zu dieser Lösung gehörende UML-Diagramm:

Die Kugel hat ein zusätzliches Attribut (als kleine graue Gedächtniszelle) : kenntFangbox.

Damit die Kugel sich die Fangbox merken kann, gibt es die Methode lerneFangboxKennen

Um die geistige Flexibilität der Leserin/des Lesers zu stärken, unterscheidet sich die Klasse TSpielfeld ein wenig von den bisherigen Lösungen und auch von der Klasse TFangbox.

In der Kugelklasse muss nun natürlich die bewege-Methode geändert werden.

 

Klasse TKugel, Methode bewege bei einer Fangbox



Dies ist
der
bisherige
Code
der
bewege-
Methode














Am neuen Teil ist nur die Bedingung
für das Anhalten interessant:

Der linke Rand der Kugel ist rechts
  vom linken Rand der Fangbox. 

Der rechte Rand der Kugel ist links
  vom rechten Rand der Fangbox. 

Der obere Rand der Kugel ist unterhalb
  des oberen Randes der Fangbox. 

Der untere Rand der Kugel ist oberhalb
  des unteren Randes der Fangbox. 

stehen
bleiben
procedure TKugel.bewege;
begin

  //Kugel an alter Stelle löschen
  self.loesche;

  //Kugle an neue Stelle bewegen
  xPos := xPos + zxGeschwindigkeit;
  yPos := yPos + zyGeschwindigkeit;

  //Kugel neu zeichnen
  self.zeichne;

  //Reflexion an den Spielfeldrändern
  if self.xPos - 11 <= kenntSpielfeld.GibXPos
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));
  if self.xPos + 11 >= kenntSpielfeld.GibXPos + kenntSpielfeld.GibBreite
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));

  if self.yPos - 11 <= kenntSpielfeld.Gibypos
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));

  if self.yPos + 11 >= kenntSpielfeld.Gibypos + kenntSpielfeld.gibHoehe
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));


  //Fangbox
  if (self.xPos - 11 > kenntFangbox.gibLinkenRand)  and


     (self.xPos + 11 < kenntFangbox.gibRechtenRand) and
     

     (self.yPos - 11 > kenntFangbox.gibOberenRand) and


     (self.yPos + 11 < kenntFangbox.gibUnterenRand)
  then
    begin
       self.zXGeschwindigkeit := 0;
       self.zYGeschwindigkeit := 0;
    end;
end;

Download des zugehörigen Projektes : Billard mit Fangbox

Reflexionsboxen

Es gibt auch hier nicht DIE richtige Lösung. Ein mögliches Lösungsprojekt mit zwei Spielfeldern mit jeweils einer Reflexionsbox und zwei Bällen findet sich hier.

Das zu dieser Lösung gehörende UML-Diagramm entspricht dem der Fangboxen. Daher hier nur einige Erläuterungen zum geänderten Code der bewege-Methode:

Klasse TKugel, Methode bewege bei einer Reflexionsbox



Dies ist
der
bisherige
Code
der
bewege-
Methode














Am neuen Teil ist nur die Bedingung
für die Reflexion interessant:

Am linken Rand der Raflexionsbox braucht
nur refelektiert werden, wenn die
Kugel sich nach rechts bewegt

der rechte Rand der Kugel ist rechts
  vom linken Rand der Box. 

die Mitte der Kugel ist aber noch links
  vom linken Rand der Box.

Der Kugelmittelpunkt ist höchstens 
  die Hälfte ihres Radius oberhalb
  des oberen Randes der Box
und höchstens
  die Hälfte ihres Radius unterhalb
  des unteren Randes der Box.

Nur die horizontale Geschwindigkeit
wird umgekehrt. 

für die anderen Ränder
analog.
procedure TKugel.bewege;
begin

  //Kugel an alter Stelle löschen
  self.loesche;

  //Kugle an neue Stelle bewegen
  xPos := xPos + zxGeschwindigkeit;
  yPos := yPos + zyGeschwindigkeit;

  //Kugel neu zeichnen
  self.zeichne;

  //Reflexion an den Spielfeldrändern
  if self.xPos - 11 <= kenntSpielfeld.GibXPos
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));
  if self.xPos + 11 >= kenntSpielfeld.GibXPos + kenntSpielfeld.GibBreite
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));

  if self.yPos - 11 <= kenntSpielfeld.Gibypos
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));

  if self.yPos + 11 >= kenntSpielfeld.Gibypos + kenntSpielfeld.gibHoehe
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));

//Reflexionsbox
   //Reflexion am linken Rand:
  if (self.zxGeschwindigkeit > 0) and



     (self.xPos > kenntReflexionsbox.gibXPos-11)  and


     (self.xPos < kenntReflexionsbox.gibXPos) and


     (self.yPos < kenntReflexionsbox.gibYPos + kenntReflexionsbox.gibHoehe+5) and



     (self.yPos > kenntReflexionsbox.gibYPos-5)


  then self.zXGeschwindigkeit := -self.zXGeschwindigkeit;


   //rechter Rand
  if (self.zxGeschwindigkeit < 0) and
     (self.xPos < kenntReflexionsbox.gibxPos + kenntReflexionsbox.gibBreite+11) and
     (self.xPos > kenntReflexionsbox.gibxPos + kenntReflexionsbox.gibBreite) and
     (self.yPos < kenntReflexionsbox.gibyPos + kenntReflexionsbox.gibHoehe+5) and
     (self.yPos > kenntReflexionsbox.gibyPos-5)
  then self.zxGeschwindigkeit := -self.ZxGeschwindigkeit;

   //oberer Rand
  if (self.zYGeschwindigkeit > 0) and
     (self.yPos > kenntReflexionsbox.gibyPos-11)  and
     (self.yPos < kenntReflexionsbox.gibyPos) and
     (self.xPos < kenntReflexionsbox.gibxPos + kenntReflexionsbox.gibBreite+5) and
     (self.xPos > kenntReflexionsbox.gibxPos-5)
  then self.ZyGeschwindigkeit := -self.ZyGeschwindigkeit;

    //unterer Rand
  if (self.zYGeschwindigkeit < 0) and
     (self.yPos < kenntReflexionsbox.gibyPos + kenntReflexionsbox.gibHoehe+11) and
     (self.yPos > kenntReflexionsbox.gibyPos + kenntReflexionsbox.gibHoehe) and
     (self.xPos < kenntReflexionsbox.gibxPos + kenntReflexionsbox.gibBreite+5) and
     (self.xPos > kenntReflexionsbox.gibxPos-5)
  then self.zyGeschwindigkeit := -self.ZyGeschwindigkeit;
end;

Download des zugehörigen Projektes : Billard mit Reflexionsbox