# Applet - Geschicklichkeitsspiel programmieren



## Henrik93 (14. Dez 2009)

*Hallo,*

das hier ist mein erster Post und ich hoffe ihr könnt mir deswegen folgenden Fehler verzeihen 
Ich programmiere seit gut einem halben Jahr mit Java in der Schule.
Nun muss ich ein "Geschicklichkeitsspiel" (als Applet) programmieren. Diese Aufgabe ist zeitbegrenzt und wird auch benotet. Ich habe schon angefangen und habe die ersten 3 von 5 Aufgaben erledigt (Aufg. poste ich nach der Einleitung). Aber jetzt habe ich nurnoch bis Freitag Zeit und ich bin am verzweifeln ???:L 

Hier die Aufgaben:

*1.* Lassen Sie ein leeres Rechteck mit den Eckpunkten (20|20) und (120|120) zeichnen. Füllen Sie es mit einem 5-Punkte breiten grünen Rahmen.
_Erledigt_

*2.* Lassen Sie das Rechteck sich Schön langsam von links nach rechts über den Bildschirm bewegen. 
_Erledigt_

*3.* Wenn das Rechteck den Rand berührt soll es anhalten.
_Erledigt_

*4. *Bei jedem Mouseklick (Ereignis _MouseUp_) soll das sich bewegende Rechteck seine Richtung ändern: erst nach rechts, dann nach unten, dan nach links, dann nach oben, wieder nach retchs,...
_???_ Ich weiß nicht wo ich das Mouse-Ereignis einfügen soll? und ich verstehe nicht wie ich dir Richtung ändern kann? Ich weiß nur wie mein Rechteck nach rechts fliegen kann... Aber wie fliegt es beim Mouseklick nach links, oder nach unten? (Unten poste ich meinen Anfang, bezügl. der Variablen etc.)

*5. *Zufallsgesteuert soll das Rechteck seine Geschwindigkeit stufenweise mit der Zeit erhöhen. Versuchen Sie möglichst lange "im Spiel zu bleiben"!
_???_ Wie kann ich die Geschwindigkeit per Zufall erhöhen?

So das sind die Aufgaben. Aufgabe 4 und 5 habe ich nicht hinbekommen. Ich hoffe jemand kann mir da weiterhelfen.
Hier der Beginn meines Programmes.

*Ich bitte euch mir zu helfen, aber ihr müsst bitte auch kommentieren was ihr an dem jeweiligen Schritt unternommen habt, da ich es sonst möglicherweise nicht nachvollziehen kann.
*

```
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 08.12.2009
  * @author
  */

public class spiel extends Applet {
  // Anfang Variablen
  
  int x;  //deklariern der Variablen
  int y;
  int vx;
  int vy;
  
  // Ende Variablen

  public void init() {
    
    // Anfang Komponenten
    x= 40;   //Startwerte des Rechteckes
    y= 40;
    vx= 1;   //Geschwinfigkeit des Rechteckes
    vy= 1;
    

    // Ende Komponenten


  }
  
  public void paint(Graphics g){
     g.setColor(Color.green);       //Farbe des Rahmens = grün
     g.fillRect(x-5,y-5,110,110);   //Bestimmung der Größe des Rechteckes + anmalen
  
    g.setColor(Color.red);          //Farbe des Rechteckes = rot
    g.fillRect(x,y,100,100);        //Bestimmung der Größe des Rechteckes + anmalen
    
     pruefen();                     //Funktion wird unten erläutert
     schritt();                     //Funktion wird unten erläutert
     bremsen(10);                   // verlangsamt das Rechteck


    repaint();                      //Vorgang wiederholt sich
  }
  
  private void bremsen (int ms){      //Bremsfunktion, um die Geschw. des Rechteckes zu kontrollieren
    try{
      Thread.sleep(ms);
    }
    catch(InterruptedException e){}
  }
  
  public void schritt(){             // Rechteck fliegt nach Rechts
      x = x+ vx;

    }
  
  public void pruefen(){            // prüft ob das Rechteck den Rand erreicht hat, fallss dies erfolgt hält das Rechteck an
    if (y>= 645 || y < 0){
      vy = 0;
    }
    if (x>= 645 || x < 0){
      vx = 0;
    }

}
  

  
  // Anfang Ereignisprozeduren
  // Ende Ereignisprozeduren

}
```


----------



## javimka (14. Dez 2009)

Um Mausklicks abfangen zu können, musst du dem Applet einen MouseListener anfügen. Darin definierst du dann, was passieren soll. Schreib folgendes in die init() Methode.

```
addMouseListener(new MouseAdapter() {
	public void mouseClicked(MouseEvent e) {
		// ändere Richtung
	}
});
```

Das Rechteck bewegt sich immer in die Richtung von vx. Um die Richtung zu ändern, müsstest du vx negieren: [c]vx = -vx[/c]. Um auch eine Bewegung nach unten und oben zu implementieren, musst du vy analog verwenden.

Um die Geschwindigkeit zu erhöhen, erhöhe den Wert von vx und vy.


----------



## Henrik93 (14. Dez 2009)

javimka hat gesagt.:


> Um Mausklicks abfangen zu können, musst du dem Applet einen MouseListener anfügen. Darin definierst du dann, was passieren soll. Schreib folgendes in die init() Methode.
> 
> ```
> addMouseListener(new MouseAdapter() {
> ...



*Was meinst du mit negieren und anlog?*
*und zur Geschw. sie soll sich zufällig mit der Zeit erhöhen, d.h. ich kann nich einfach den Wert für vx und für vy erhöhen...? Hast du da vllt noch eine andere Lösung?

Ich habe das Mouse Event jetzt eingefügt und ich habe es  mit deinem Beispiel von [c]vx = -vx[/c] laufen lassen. Jetzt läuft das Rechteck ja wieder nach links. Kannst du mir bitte noch sagen wie es nach unten läuft und wie nach oben?
nach unten ist es dann: [c]vy=-vy[/c] ?


Ansonsten bin ich dir sehr dankbar 

*


----------



## javimka (14. Dez 2009)

Wenn vx positiv ist, bewegt sich das Rechteck nach rechts.
Wenn vx negativ ist, bewegt sich das Rechteck nach links.
Wenn vx gerade 0 ist, bewegt es sich nicht mehr horizontal.

Wenn vy positiv ist, bewegt sich das Rechteck nach unten.
Wenn vy negativ ist, bewegt sich das Rechteck nach oben.
Wenn vy gerade 0 ist, bewegt es sich nicht mehr vertikal.

Was du machen musst (im MouseListener), ist vx und vy so zu setzen, dass sich das Rechteck in die richtige Richtung bewegt. Soll es z.B. nach oben, musst vy>0 und vx=0 sein.

Eine Zufällige Zahl generierst du folgendermassen:

```
Random rand = new Random();
int r = rand.nextInt(1000); // Zahl zwischen 0 und 999
```

Du könntest im MouseListener eine solche Zufallszahl generieren und wenn sie 0 ist, dann erhöhst du den Wert von vx und vy. So werden sie schneller.


----------



## Henrik93 (14. Dez 2009)

'tschuldige, das ich es immer noch nicht ganz verstanden habe.
Aber wenn das rechteck z.B. nach oben soll (nach dem klicken), müsste der befehl doch so aussehen, oder?

```
if(vy>0 && vx=0){
        vy = -vy;
        }
```

oder wie?

ich wäre dir sehr ergeben wenn du mir einfach klar aufschreibst,
oben
unten

das wäre nett. dann verstehe ich es auch besser. 
es geht mir nicht nur darum das ich ein ergebnis habe, ich möchte es auch selber verstehen 
und im moment bin ich überfordert.
ich verstehe zwar die liste mit den positiven und negativen vx und vy werten, aber ich kann damit nicht programmieren...


----------



## javimka (14. Dez 2009)

Ich würde folgendes machen.
Definiere eine Variable [c]int speed = ...[c], die angibt, wie schnelld das Rechteck sein soll.
Ausserdem definierst du eine Variabel direction, welche angibt, in welche Richtung sich das Rechteck gerade bewegt.
0 = rechts, 1 = unten, 2 = links, 3 = oben

Im Mouselistener führst du nun folgendes aus:

```
direction = (direction+1)%4; // gibt die neue Richtung an.
if (direction==0) {
  vx = -speed; // nach rechts
  vy = 0; // keine vertikale Bewegung
} else if (direciton==1) {
  vx = 0; // keine horizontale Bewegung
  vy = speed; // nach unten
} else if.....
  // hier noch für links und für oben
}
```

Wenn du jetzt noch die Geschwindigkeit ändern willst, musst du nur speed erhöhen. Du könntest z.B. schreiben

```
if (new Random().nextInt(4)==0) {
  speed = speed + 20;
}
```
Dies erhöht die Geschwindigkeit bei etwa jedem 4. Klick zufällig.


----------



## Henrik93 (14. Dez 2009)

So nun habe ich noch 2 letzte Fragen (ist echt schwer mir mir )
1. wie deklariere ich "direction"?
2. wie lasse ich das Rechteck nach oben fahren?

Ich habe deswegen noch eine Menge an Errors und deshalb habe ich hier nochmal den wichtigen Ausschicnt. Ich wollte dich bitten mich auf Fehler hinzuweisen.
Guck es dir am besten mal in Ruhe durch.
Du weist gar nicht wie dankbar ich dir bin 
Hoffe ich gehe dir nicht zu sehr auf den Sack...


```
public class spiel extends Applet {
  // Anfang Variablen
  
  int x;  //deklariern der Variablen
  int y;
  int vx;
  int vy;
  int speed = 1
  int direction
  // Ende Variablen

  public void init() {
    
    // Anfang Komponenten
    x= 40;   //Startwerte des Rechteckes
    y= 40;
    vx= 1;   //Geschwindigkeit des Rechteckes
    vy= 1;
    
    
    addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {

        direction = (direction+1)%4; // gibt die neue Richtung an.
        if (direction==0) {
        vx = -speed; // nach rechts
        vy = 0; // keine vertikale Bewegung
        } else if (direciton==1) {
        vx = 0; // keine horizontale Bewegung
        vy = speed; // nach unten
        } else if (){
         vx = -vx;// nach links
        }

}
    }
});

    // Ende Komponenten


  }
```


----------



## javimka (14. Dez 2009)

Deklariert hast du directen prinzipiell richtig.
In Ziele 8 und 9 fehlen ; am Ende.
In Zeile 28 ist direction falsch geschrieben.
Die Zeilen 31 und 32 habe ich dir selbst zum programmieren überlassen, die sind nicht mehr so schweirig, nachdem ich die beiden ersten Richtungen 0 und 1 bereits geschrieben habe.
Die Klammer aus Zeile 36 kommt in die Zeile 39


----------



## Henrik93 (14. Dez 2009)

Ich habe das jetzt richtig. Großes Danke.
Aber jetzt habe ich ein anderes Problem.
Hier mein Mouse Event (no Errors).


```
addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {

        direction = (direction+1)%4; // gibt die neue Richtung an.
        if (direction==0) {
        vy = 0; // keine vertikale Bewegung
        vx = -speed; // nach rechts
        } else if (direction==1) {
        vx = 0; // keine horizontale Bewegung
        vy = speed; // nach unten
        } else if (direction==2){
        vy = 0; //keine vertikale Bewegung
        vx = -vx;// nach links
        } else if (direction==3){
        vx = 0;  // keine horizontale Bewegung
        vy = -speed; //nach oben
        }

       }
    }
```

*Problem: wenn ich klicke bleibt das Rechteck einfach nur stehen und macht gar nix mehr -.- vielleicht liegt es an meiner Funktion schritt();*


```
public void schritt(){             // Rechteck fliegt nach Rechts
      x = x+ vx;
```

*die Funktion wird in public void paint aufgerufen:*


```
schritt();
```

Das wäre meine letzte Frage/Problem. Rechteck ändert nicht seine Richtung, obwohl es richtiug programmiert ist....


----------



## javimka (14. Dez 2009)

Zeile 13 in deinem MouseListener stimmt noch nicht. Was, wenn vx==0 ist?

Deine Methode schritt() berechnet ja nur eine neue x Koordinate. natürlich musst du dasselbe auch mit y machen.


----------



## Henrik93 (14. Dez 2009)

Vielen, vielen Dank.
Esfunktioniert jetzt.

Du hast mir echt weitergeholfen 
Ich hoffe ich kann dich bald nochmal was fragen, aber fürs erste sollte dies reichen 

Nochmalls Danke.


----------



## Henrik93 (15. Dez 2009)

So ich habe es mal heute meinem Lehrer gezeigt und er meinte das es sehr gut wäre,
aber ich habe halt die Aufgabe mit der Geschwinfigkeit und der Zeit nicht hinbekommen...

5. Zufallsgesteuert soll das Rechteck seine Geschwindigkeit stufenweise mit der Zeit erhöhen. Versuchen Sie möglichst lange "im Spiel zu bleiben"!
??? Wie kann ich die Geschwindigkeit per Zufall erhöhen?

Du hast mir ja schonmal was von random geschrieben, aber es hat nicht geklappt.
*Könntest du das nochmals preziser erläutern?*

*und  eine letzte Frage zum verständnis,
was hast du in der folgendes Zeile gemacht? Ich kenne den Befehl mit dem Zeichen "%" nicht*


```
direction = (direction+1)%4;
```


----------



## javimka (15. Dez 2009)

% ist der Modulo Operator. Er gibt den Divisionsrest zweier Zahlen zurück: 11%4 = 3
Sinn davon ist, das nach Richtung 3 wieder Richtung 0 kommen muss, deswegen %4.

Um die Geschwindigkeit zu erhöhen, musst du speed erhöhen. Wie hier beschrieben:



javimka hat gesagt.:


> ```
> if (new Random().nextInt(4)==0) {
> speed = speed + 20;
> }
> ...


----------



## Henrik93 (15. Dez 2009)

Ok das mit dem "%" habe ich verstanden.

Aber wo muss ich den random befehl einfügen?
In das Mouse Event oder weiter oben in init()?


----------



## javimka (15. Dez 2009)

Wo denkst du denn, dass die Geschwindigkeit erhöht werden sollte? Einmal in init() oder bei jedem Klick im MouseListener?


----------



## Henrik93 (15. Dez 2009)

Das ist mir selber überlassen,
aber ich möchte das so programmieren, dass sich die Geschw. per Zufall bei jedem Mausklick erhöht bzw. verlangsamt.
Dann müsste ich den random Befehl also in jede if-Schleife einbauen?
oder nur einmal?


----------



## javimka (15. Dez 2009)

Dann machst du das so:

```
speed = speed + new Random().nextInt(Maximale Geschwindigkeitszunahme);
```


----------

