# Runnable + KeyListener?



## StickToFreak (7. Mrz 2009)

Hey Leute,

also mal ne Frage, vielleicht geht das garnicht so einfach wie ich es mir vorstelle.
Ich möchte - Snake-like - Ein Objekt (in meinem Fall ein Kreis) per Tasten-Druck, weiterlaufen lassen Geht ja per Runnable, aber doch nicht per Tastendruck oder?

Also so sieht das ganze bisher aus:

[HIGHLIGHT="Java"]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Snake extends Applet implements KeyListener {


       private int mouseX;
       private int mouseY;
       private int radius, diameter = 20;
       private Color circleColor = Color.black;
       private Color rectColor= Color.black;





       public void init() {
              Dimension full = getSize();
              mouseX = full.width/2;
              mouseY = full.height/2;
              radius=diameter/2;
              addKeyListener(this);
       }


       public void paint (Graphics g) {
       g.drawRect(10,10,300,200);
       g.setColor(rectColor);
              g.setColor (circleColor);
              g.fillOval ((mouseX-radius), (mouseY-radius),diameter, diameter);

       }



       public void keyPressed(KeyEvent ev) {

         if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX <300) {
                 mouseX = mouseX+2;
                 mouseY = mouseY;

                 repaint();
              }
              if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY <200) {
                 mouseX = mouseX;
                 mouseY = mouseY+2;

                 repaint();
              }
              if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY >20) {
                 mouseX = mouseX;
                 mouseY = mouseY-2;

                 repaint();
              }
              if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX >20) {
                 mouseX = mouseX-2;
                 mouseY = mouseY;

                 repaint();


              }
              if (mouseX == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
                   System.out.println("Game Over!");
                   repaint();
                 }

               if (mouseY==20 && ev.getKeyCode() == KeyEvent.VK_UP){
                 System.out.println("Game Over!");

               }

               if (mouseX==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
                 System.out.println("Game Over!");
               }

               if (mouseY==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
                 System.out.println("Game Over!");
               }





       }


       public void keyTyped(KeyEvent ev) {

       }
       public void keyReleased(KeyEvent ev) {

       }

}

[/HIGHLIGHT] 

Als weiteres wollte ich ncoh fragen, wenn ich das ganze per GameLoop mache, wie würde das funktionieren? einfach while(true){ davor setzen? Wäre ja ganz schön. Nur wenn ich das mache, dann bewegt sich der Kreis kein Stück, sondern er bleibt stehen (im Applet) und unten kommt die ganze Zeit per System.out.println("Game Over!") :-D sieht alles sehr lustig aus, aber funktionieren tut es nicht .

Bin ich komplett auf dem Holzweg, oder gibt es da eine einfache Lösung?


----------



## hdi (7. Mrz 2009)

Also erstmal musst du aufpassen was du im Listener in welcher Reihenfolge machst.

Du sagst zB if x > 20 then moveLeft. Dabei erniedrigst du x um 2, also ist es jetzt 18.
*Danach* prüfst du ob x == 20, was nicht der Fall ist. D.h. ein Gameover
wird es nur mit etwas Glück geben, und zwar wenn er genau bei 22 nach links drückt.

Besser also if x < 20, und noch besser das VOR der Bewegung prüfen.

Ansonsten:
Ein KeyListener nimmt nur tatsächlich Aktionen wahr, die DU als User drückst.
Ein GameLoop arbeitet direkt mit der Logik, d.h. dort veränderst du die Position
halt direkt (der gleiche Code wie in deiner Listener-Methode).
Es gibt zwar etwas dass sich "Robot" nennt, und der simuliert Tastendrücke, aber
das is eig. nicht nötig.

Ein GameLoop ist eigentlich immer while(!gameover){...}, und diese Variable wird
eben auf true gesetzt wenn du mit einer Wand kollidierst oder sonst was.

Dein Problem, dass sofort GameOver erscheint ist wohl, dass du kein sleep verwendest.

Ein while(true) wird pro Sekunden hunderttausendfach aufgerufen. 

Du solltest also Pausen einbauen, dafür gibt es die Methode

Thread.sleep(long);

long ist dann der Wert in Millisekunden, der geschlafen werden soll.
zB long = 1000 würde heissen, dass sich dein Wurm jede Sekunde mal verschiebt,
und der GameLoop dann ne Pause einlegt usw.


----------



## Fu3L (7. Mrz 2009)

Am besten mal Quaxlis Tutorial lesen. Is zwar auf ne Fensteranwendung ausgelegt, sollte aber in nem Applet genauso ablaufen. (Allerdings würd ich JApplet empfehlen)

http://www.ralf-bauer.org/java/tutorial/Tutorial.zip


----------



## StickToFreak (8. Mrz 2009)

@hdi

d.H. ich muss boolean benutzen?




[HIGHLIGHT="Java"] 
boolean gameover;


//[...]

 public void keyPressed(KeyEvent ev) {

                if (mouseX1 == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
                             System.out.println("Game Over!");
                              this.gameover = true;
                       }

                     if (mouseY1==20 && ev.getKeyCode() == KeyEvent.VK_UP){
                            System.out.println("Game Over!");
                         this.gameover = true;
                       }



                     if (mouseX1==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
                       System.out.println("Game Over!");
                        this.gameover = true;
                     }


                     if (mouseY1==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
                       System.out.println("Game Over!");
                               this.gameover = true;
                     }

                     while(!gameover){




               if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX1 <300 ) {
                       mouseX1 = mouseY1+2;
                       mouseY1 = mouseY1;


                       repaint();
                    }

                    if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY1 <200) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1+2;


                       repaint();
                    }

                    if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY1 >20) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1-2;
                       repaint();
                    }

                     if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX1 >20) {
                                         mouseX1 = mouseX1-2;
                                          mouseY1 = mouseY1;
                                           repaint();
                       }
                       }


       }[/HIGHLIGHT]

Das Problem ist, dass wenn ich dies mache, passiert bei mir garnichts. -> ?Weil ich kein Runnable nutze?? <- 
Oder ist sonst noch ein Fehler drinne?


----------



## hdi (8. Mrz 2009)

Du bringst da was durcheinander.

Die keyPressed-Methode soll ja nicht deinen Game-Loop enthalten.
So wie du es im Moment gemacht hast, bleibt dein Programm beim ersten Tastendruck
hängen (keyPressed wird aufgerufen, dort while(!gameover) -> Endlosschleife).

Die Methode selbst enhält nur die if-Abragen (welche Taste gedrückt wurde) und
dann je nachdem entweder die Repositionierung deines Objekts oder eben, und das hast
du richtig gemacht - ein gameover = true.

Das war's. 

Dein GameLoop ist dann ein eigener Thread/Runnable (ist das gleiche).
und dieser enthält in seiner run()-Methode, die du ja überschreiben musst, 
die while(!gameover)-Schleife.
Da kommt übrigens auch das repaint() rein, nicht in die keyPressed-Methode!

Der boolean gameover muss also sowohl in der keyPressed
Methode als auch im GameLoop sichtbar sein. Kommt jetzt drauf an wie du das designest, wenn
du eh alles in eine Klasse klatscht sollte es ja kein Problem sein.

Du wirst aber evlt demnächst auf ein anderes Problem stossen, ich schmeiss dir
mal den Begriff "Event Dispatch Thread" vor die Füsse. Aber dazu kommen wir,
wenn es soweit ist


----------



## StickToFreak (8. Mrz 2009)

:-D Ist ja lustig^^. Okay also wenn ich das jetzt richtig verstanden hab, muss ich das in die keyTyped methode reintun?

Wie meinst du das mit dem Der boolean muss in keyPressen sowie im Gameloop sichtbar sein?


----------



## hdi (8. Mrz 2009)

Nein Nein Nein 

Ich schreib dir jetz mal das etwas ausführlicher, könnte etwas dauern, edit kommt dann in ~30 mins


----------



## StickToFreak (8. Mrz 2009)

Och du jemine 
Find ich gut. Bis in 30min. 
Achja wenn ich schon dabei bin dir Aufwand zu machen, wie sähe das ganze aus, wenn ich dann beim "Game Over" das ganze stoppen will. Also das sich nen Dialog öffnet mit Game Over.
Du verstehen  ?


----------



## hdi (8. Mrz 2009)

Ok, here we go:

Diese Methoden keyPressed,keyTyped etc. sind ja Methoden vom Interface KeyListener.
Sobald du einen KeyListener an eine Komponente hängst, ist er aktiv und "lauscht" (to listen)
dort auf etwas - in deinem Fall auf Tastatur-Eingaben.

Diese Methoden werden von Java automatisch aufgerufen, wenn du jetzt ne Taste drückst,
wie du sicher schon gemerkt hast.

Vllt kurz der Unterschied zwischen keyTyped und keyPressed:
keyPressed = wird aufgerufen, wenn du ne Taste runterdrückst.
keyTyped = wird aufgerufen, wenn du einen kompletten "Drückvorgang" auslöst, d.h.
du drückst eine Taste und lässt sie auch wieder los.
...das nur nebenbei, überleg dir wie dein Spiel reagieren soll damit du weisst welche
Methode du verwenden willst.

Was jetzt in dieser Methode passieren soll, ist ja: Entweder deine Figur wird bewegt,
oder das spiel soll game Over sein, weil du in ne Wand gerannt bist oder sowas.

Und genau das soll diese Methode machen: Entweder repositionieren, oder einfach nur
das Spiel beenden, und dafür setzt man eben normalerweise einen boolean-Wert,
hier gameOver = true;

Soo, deine Spiel-Logik, also der Game-Loop, der hat mit dieser Aktion erstmal aktiv nix zu tun.

Du musst wissen, dass jedes Programm anfangs nur einen Thread hat. D.h. beim Ausführen 
des Programms wird Zeile für Zeile ausgewertet, und dein Programm kann immer nur
eine Sache auf einmal tun.

Wenn du nun also eine while-Schleife in die KeyListener Methode reinbaust, dann heisst das
dass diese Methode nicht "zurückkehrt", also das Programm während der Laufzeit dort
festhängt und die Methode nicht zum Ende bearbeitet.

Das führt dazu, dass dein Listener blockiert -- weitere Tastendrücke können nicht ausgewertet
werden, weil die Methode nicht neu aufgerufen werden kann, solange du noch drinsteckst.

Deshalb trennt man den Gameloop von einem Listener.
Und der Game-Loop ist ein eigener Thread, ein _neuer_ Thread.
Warum? Na ganz einfach: Du willst doch, dass der Computer fortlaufend etwas tut,
zB eine Figur bewegen, und du _gleichzeitig_ deine Figur umlenken kannst, oder?

Weil ein Thread wie oben erwähnt nur zeilenweise, streng sequentiell, arbeiten kann,
klappt das nicht mit einem Thread. Du brauchst zwei.

Der GameLoop ist also ein Thread, d.h. ja nur dass du von der Klasse Thread erbst, bzw.
das Interface Runnable implementierst.

So, wie du vermutlich auch eine Klasse á la:

[HIGHLIGHT="Java"]class MeinSpielFenster extends JFrame {...}[/HIGHLIGHT]

hast, brauchst du jetzt also eine *neue Klasse* á la:

[HIGHLIGHT="Java"]class MeinGameLoop extends Thread {...}[/HIGHLIGHT]

Und wenn du die gemacht hast, musst du in dieser Klasse die run-Methode überschreiben.
Dort kommt das rein, was dein GameLoop tun soll, also:

[HIGHLIGHT="Java"]@Override
public void run(){ 
     while(!gameover){
            // tue, was du halt tun sollst...
     }
}[/HIGHLIGHT]

Und jetzt verstehst du wohl auch, was ich meinte als ich sagte, der boolean muss
sowohl im GameLoop als auch im KeyListener sichtbar sein: Du hast ja jetzt 2 verschiedene
Klassen.

Zwar designtechnisch nicht schön, aber für den jetzigen Zweck einfacher, solltest
du diese 2 Dinge also nicht in zwei verschiedene .java Dateien schreiben, sondern 
in eine.

Die GameLoop-Klasse schreibst du dann innerhalb von deiner Haupt-Klasse
(darf in diesem Fall aber nicht public sein, einfach weglassen)

Und wenn du dein Programm startest, also in der main-Methode oder meinetwegen
im Konstruktor deines Frames oder so, musst du eine Instanz von deinem GameLoop erzeugen:

[HIGHLIGHT="Java"]GameLoop game = new GameLoop();[/HIGHLIGHT]

die run()-Methode ruft man nicht direkt auf, sondern man macht:

[HIGHLIGHT="Java"]game.start();[/HIGHLIGHT]
(das führt dazu, dass intern die run-Methode aufgerufen wird).

So, wenn du das soweit machst, dann läuft dein GameLoop in einer Endlosschleife,
und tut bisher noch nix sinnvolles. Dafür tut er etwas extrem nicht-sinnvolles:
Er drescht die CPU-Auslastung auf 100%, und legt deinen PC halb lahm.

Der Grund liegt darin, dass eine while(true)-Schleife (!gameover ist ja anfangs true)
in der Sekunde SEHR oft aufgerufen wird, und zwar pausenlos.
Deswegen bauen wir eine Pause ein:

[HIGHLIGHT="Java"]@Override
public void run(){ 
     while(!gameover){
            // tue, was du halt tun sollst...
            // und dann chill erstmal ne Runde:
            Thread.sleep(50);
     }
}[/HIGHLIGHT]

Diese sleep-Methode nimmt einen long-Wert in Millisekunden entgegen. D.h. hier
würde der GameLoop immer 50ms "schlafen", bevor er die Schleife wieder durchläuft.
Das langt erstmal, um deine CPU wieder in den grünen Bereich zu kriegen.

Kleine Anm.: Der Aufruf der sleep-Methode kann eine Exception werfen, d.h. das musst
du in einen try-catch Block hauen. Wenn du ne IDE wie zB Eclipse nutzt, wird der dir
das automtaisch machen wenn du auf die Fehler-Meldung klickst.

Für den Fall dass das nicht der Fall ist, das muss am Ende also so aussehen:

[HIGHLIGHT="Java"]try {
	Thread.sleep(100);
} catch (InterruptedException e) {
	 e.printStackTrace();
}[/HIGHLIGHT]

Nochmal zur Erinnerung: Es laufen jetzt 2 Threads: Dein Hauptprogramm, und
dieser GameLoop. Denn wenn du den GameLoop erstellst und startest, springt
dein Hauptprogramm nicht in die run()-Methode, sondern macht einfach in seinem
eigenen Code weiter.

Jetzt setzt du noch nen Listener wie gehabt, und nun läuft der GameLoop, und der
KEyListener steht jederzeit zur Verfügung, um Tastatur-Eingaben zu bearbeiten.

Sobald du gameover auf true setzt, endet der GameLoop, weil seine run()-Methode
zu Ende geht, und damit ist der Thread "tot".

Verstanden? Dein Gameloop macht in gewissen Abständen (druch das sleep festgelegt)
eine bestimmte Aktion. Und der Listener ist einfach "da", und reagiert bei jedem 
Tastendruck.

Man muss das jetzt halt alles schlau zusammenbauen können. Wie ich zB sagte
sollte der GameLoop das repaint() machen, dafür braucht er das Panel/Frame, auf
dem das passieren soll. 

Du musst also kucken dass du gewisse Variablen global zur Verfügung stellst, damit
beide Klassen drauf zugreifen können.

...ist n bisschen happig, da kommt viel zusammen. Das ganze GUI/Thread Zeugs ist
wirklich alles andere als leichte Kost. Aber versuch einfahc mal deinen Code so umzuschreiben wie du es jetzt verstanden hast.

Viel Spass (und Glück )


----------



## StickToFreak (8. Mrz 2009)

Nochmal ne frage, den listener in gameloop setzen oder in die Hauptklasse?

Edit:
Und das@Override bedeutet?


----------



## hdi (8. Mrz 2009)

Überleg nochmal und beantworte dir die Frage selber.
Nochmal n kleiner Denkanstoss:

*Ein* Thread läuft streng sequentiell ab, d.h. wenn du in Methode A steckst,
kann Methode B nicht aufgerufen werden, wenn beide Methoden vom dem selben
Thread bearbeitet werden (sollen).

edit: Das @Override kann man weglassen. Man schreibt es für gewöhnlich hin,
damit man als Programmierer sieht: Aha, hier *überschreibe* ich eine Methode, die
ich geerbt habe.
Bei deinen ganzen KeyListener-Methoden könntest du das also auch hinschreiben.


----------



## StickToFreak (8. Mrz 2009)

d.H. listener in hauptklasse, richtig?


----------



## hdi (8. Mrz 2009)

Richtig! Sonst blockiert die while(true)-Schleife alle Listener-Methoden.


----------



## StickToFreak (8. Mrz 2009)

und des
GameLoop game = new GameLoop();
kommt ganz an den anfang, zu den Variabeln?
und das game.start();
dann vor das gameloop?


----------



## hdi (8. Mrz 2009)

GameLoop ist nur eine Klasse, wo du die hinschreibst ist egal. Eine Klasse selbst
"macht" ja noch nix, die ist nur verfügbar.

Das Erstellung und Starten deines Gameloops kannst du eigentlich auch machen,
wann immer du Lust hast. 
Als erste Zeile deiner main-Methode, oder innerhalb deines Fenster-Konstruktors.
Wie du willst.

edit: Wenn du die Erstellung am Anfang zu den Variablen schreibst, wird er erstellt
sobald du das Objekt (Fenster) erstellst. Ist also durchaus auch möglich.


----------



## StickToFreak (8. Mrz 2009)

Hm. OKay. 
Also nochmal wenn ihc das richtig verstanden ahbe kommt das ganze:

[HIGHLIGHT="Java"]  { if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX1 <300 ) {
                       mouseX1 = mouseY1+2;
                       mouseY1 = mouseY1;


                       repaint();
                    }

                    if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY1 <200) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1+2;


                       repaint();
                    }

                    if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY1 >20) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1-2;
                       repaint();
                    }

                     if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX1 >20) {
                                         mouseX1 = mouseX1-2;
                                          mouseY1 = mouseY1;
                                           repaint();
                       }[/HIGHLIGHT]

nicht in den GameLoop sondern in die HauptKlasse. Die Überprüfung:
[HIGHLIGHT="Java"]
                if (mouseX1 == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
                             System.out.println("Game Over!");
                              this.gameover = true;
                       }

                     if (mouseY1==20 && ev.getKeyCode() == KeyEvent.VK_UP){
                            System.out.println("Game Over!");
                         this.gameover = true;
                       }



                     if (mouseX1==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
                       System.out.println("Game Over!");
                        this.gameover = true;
                     }


                     if (mouseY1==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
                       System.out.println("Game Over!");
                               this.gameover = true;
                     }
                     }[/HIGHLIGHT]
doch auch oder? Was kommt denn dann genau in den GameLoop. In den GameLoop kommt doch das, was ich ständig wiederholen will, das ist nunmal das obere (Code oben). Aber dann mäckert der Editor, dass Variable ev nicht definiert ist.. ( KeyEvent ev)


----------



## hdi (8. Mrz 2009)

Moment mal, einen GameLoop benötigst du ja nur, wenn du automatisch in gewissen
Abständen etwas tun willst. Also nicht durch den User ausgelöst.

Wenn dein Spiel wirklich nur die Figur bewegen soll, wenn du was drückst, und das spiel
ansonsten stillstehen soll, dann brauchst du überhaupt keinen GameLoop...

Zu dem Fehler dass er ev nicht findet: Das ist eine lokale Variable, die ist nur innerhalb
der Listener-Methode sichtbar, ausserhalb gibt es die nicht.


----------



## StickToFreak (8. Mrz 2009)

Nein nein. Es soll ja ein Snake-Spiel werden. Deshalb ist die typed methode schon gut am platz.
Also es soll sich ja von selbst bewegen, per tastendruck hatte ich das ganze ja schon...


----------



## hdi (8. Mrz 2009)

...und mal nebenbei:

[HIGHLIGHT="Java"]mouseX1 = mouseX1;[/HIGHLIGHT]

da fühlt sich der Compiler verarscht  Nimm das doch raus...


----------



## hdi (8. Mrz 2009)

sry ich hab keinen Instant Messanger.

Aber da hast du doch dann die Antwort auf deine Frage, was in den GameLoop reinsoll:
Und zwar soll dort in gewissen Abständen mouseX1 und mouseX2 geändert werden.
Jetzt musst du nur noch die Info reinkriegen, in welche Richtung sich der Wurm grad
bewegt.
Dazu kannst du eine Variable

[HIGHLIGHT="Java"]int currentDirection;
[/HIGHLIGHT]
erstellen (oben, also "global"), und innerhalb der keyTyped da immer das KeyEvent
reinlegen, das grad aufgetreten ist.
Der GameLoop kann dann nachschauen was zuletzt gedrückt wurde.


----------



## StickToFreak (8. Mrz 2009)

Reine Absicht  Wollte ihn mal necken^^. 

Achja hab das langsam verstanden^^


Edit: Geklärt^^

Neue Frage: es passiert immer noch nichts ôÔ


----------



## hdi (8. Mrz 2009)

> Achja hab das langsam verstanden^^



Prima, dann darf ich jetz endlich ins Bett? Also ich geh dann mal :bae:

edit:

scheisse... xD Was geht denn nicht?


----------



## StickToFreak (8. Mrz 2009)

Sorry du darfst natürlich^^
Aber hier mal der Code:
Einfach mal alles:

[HIGHLIGHT="Java"]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Snake2 extends Applet implements KeyListener {



             private int mouseX;
             private int mouseX1=150;

              private int mouseY;
             private int mouseY1=150;

             private int radius, diameter = 20;
             private Color circleColor = Color.black;
             private Color rectColor= Color.black;
             int diameter1 = 5;
             int diameter2 = 6;
              boolean gameover;
              boolean links;
              boolean rechts;
              boolean up;
              boolean down;
              GameLoop game = new GameLoop();


               public void init() {
                    Dimension full = getSize();
                    mouseX = full.width/2;
                    mouseY = full.height/2;
                    radius=diameter/2;
                    addKeyListener(this);

                     }



             public void paint (Graphics g) {

                         g.drawRect(10,10,321,195);
                         g.setColor(rectColor);

             g.setColor(circleColor);
             g.fillRect((mouseX1),(mouseY1),diameter1,diameter2);

             }

              public void keyPressed(KeyEvent ev) {

                     }

             public void keyTyped(KeyEvent ev) {




                if (mouseX1 == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
                             System.out.println("Game Over!");
                              this.gameover = true;
                       }

                     if (mouseY1==20 && ev.getKeyCode() == KeyEvent.VK_UP){
                            System.out.println("Game Over!");
                         this.gameover = true;
                       }



                     if (mouseX1==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
                       System.out.println("Game Over!");
                        this.gameover = true;
                     }


                     if (mouseY1==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
                       System.out.println("Game Over!");
                               this.gameover = true;
                     }


                     if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX1 <300 ) {
                       mouseX1 = mouseY1+2;

                       this.rechts = true;



                    }

                    if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY1 <200) {

                       mouseY1 = mouseY1+2;
                       this.down = true;



                    }

                    if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY1 >20) {
                       mouseY1 = mouseY1-2;
                       this.up = true;

                    }

                     if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX1 >20) {
                                         mouseX1 = mouseX1-2;
                                         this.links = true;

                       }

             }
             public void keyReleased(KeyEvent ev) {
             }


class GameLoop extends Thread {

public void run(){

           game.start();

  while(!gameover)

  { if (rechts == true) {
                       mouseX1 = mouseY1+2;
                       mouseY1 = mouseY1;


                       repaint();
                    }

                    if (down == true) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1+2;


                       repaint();
                    }

                    if (up == true) {
                       mouseX1 = mouseX1;
                       mouseY1 = mouseY1-2;
                       repaint();
                    }

                     if (links == true) {
                                         mouseX1 = mouseX1-2;
                                          mouseY1 = mouseY1;
                                           repaint();
                       }

                       try{
  Thread.sleep(50);
}

catch (InterruptedException ev)
{

}
                       }


  }
}


}[/HIGHLIGHT]


----------



## hdi (8. Mrz 2009)

Das game.start() ruft man auf, damit die run() Methode aufgerufen wird.
Wie du dir jetzt denken kannst, ist das bei dir im Moment eher schlecht realisierbar oder 

Also: 

game.start()

ans Ende der init-Methode.


----------



## StickToFreak (8. Mrz 2009)

[HIGHLIGHT="Java"]
               public void init() {
                    Dimension full = getSize();
                    mouseX = full.width/2;
                    mouseY = full.height/2;
                    radius=diameter/2;
                    addKeyListener(this);
                      game.start();
                     }[/HIGHLIGHT]


Funktioniert ebenso nicht.

Edit:
Weißt du was? Lass uns das morgen- sorry Heute machen  auf jedenfall brauchen wir beide jetzt Schlaf  Ich glaube dann geht das besser^^


----------



## hdi (8. Mrz 2009)

Muss funktionieren, bau mal eine System.out.println() Meldung in die while-Schleife
vom GameLoop rein. 

Und mach das gleiche in der keyTyped-Methode. Das müsste beides reagieren,
aber vllt sind wir jetzt bei dem vorher angesprochenen Event Dispatch Problem.

Du erlaubst mir jetzt aber bitte, dass ich mich für heute verabschiede.
Versuch noch n bisschen rum, bau solche Meldungen an verschiedenen Stellen im Code
ein um zu sehen wo es hakt.

gute n8


----------



## StickToFreak (8. Mrz 2009)

Gut gemacht, getan. Mal ein paar System.out.println("Fehler-Test"); eingebaut. GameLoop funktioniert.

aber:

[HIGHLIGHT="Java"]public void keyTyped(KeyEvent ev) {

if (mouseX1 == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY1==20 && ev.getKeyCode() == KeyEvent.VK_UP){
System.out.println("Game Over!");
this.gameover = true;
                                                      }

if (mouseX1==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY1==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX1 <300 ) {
mouseX1 = mouseY1+2;
this.rechts = true;
System.out.println("Fehler-Test");
                                                           }
if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY1 <200) {
mouseY1 = mouseY1+2;
this.down = true;
 System.out.println("Fehler-Test");
                                                         }

if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY1 >20) {
mouseY1 = mouseY1-2;
this.up = true;
System.out.println("Fehler-Test");
                                                      }

if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX1 >20) {
mouseX1 = mouseX1-2;
this.links = true;
System.out.println("Fehler-Test");
                                                          }

                                                            }[/HIGHLIGHT]

funktioniert nicht. Ich drücke eine Taste dann sollte ja eigentlich Fehler-Test erscheinen. Tuts nicht.

Dann mal Gute nacht


----------



## hdi (8. Mrz 2009)

So dann flieg ich zwischen Badezimmer und Bett nochmal schnell vorbei:
Bau mal so ne Meldung als allererste Zeile in die keyTyped (ohne irgendein if)

Ich denke es liegt daran dass einfach kein if matcht, weil die mouseX1,mouseY1 Werte
wohl nicht dementsprechend gesetzt sind


----------



## StickToFreak (8. Mrz 2009)

Nein daran liegt es auch nicht siehe da:

[HIGHLIGHT="Java"]
public void keyTyped(KeyEvent ev) {
System.out.println("Fehler-Test");

if (mouseX1 == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY1==20 && ev.getKeyCode() == KeyEvent.VK_UP){
System.out.println("Game Over!");
this.gameover = true;
                                                      }

if (mouseX1==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY1==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX1 <300 ) {
mouseX1 = mouseY1+2;
this.rechts = true;
System.out.println("Fehler-Test");
                                                           }
if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY1 <200) {
mouseY1 = mouseY1+2;
this.down = true;
 System.out.println("Fehler-Test");
                                                         }

if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY1 >20) {
mouseY1 = mouseY1-2;
this.up = true;
System.out.println("Fehler-Test");
                                                      }

if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX1 >20) {
mouseX1 = mouseX1-2;
this.links = true;

                                                          }

                                                            }
[/HIGHLIGHT]

Wenn ich nun eine Taste drücke kommt auch keine Meldung.

Edit: Liegt das ganze vllt daran das ich das alles in einem Applet mache? ~.~


----------



## hdi (8. Mrz 2009)

Ach ein Applet? Ich denke dein Problem ist, dass dein Applet nicht den Fokus hat.
Ein Listener kann nur reagieren wenn er den Fokus hat.

Wenn du das Applet startest, klick nochmal explizit auf's Fenster, damit es aktiv ist.
Dann sollte das auch alles klappen.


----------



## StickToFreak (8. Mrz 2009)

Ja klar, das weiß ich^^. Nein ich klicke immer drauf. Funktioniert trotzdem nicht.. Keine Fehlermeldungen oder sonstiges. Es passiert einfach nichts *__*.
Hier mal der Code zum reinkopieren in den Editor:

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

public class Snake2 extends Applet implements KeyListener {



private int mouseX=150;
private int mouseY=150;
private int radius, diameter = 20;
private Color circleColor = Color.black;
private Color rectColor= Color.black;
private Color EssenColor = Color.red;
int diameter1 = 20;
int diameter2 = 7;
boolean gameover;
boolean links;
boolean rechts;
boolean up;
boolean down;
boolean schlangeplus;
GameLoop game = new GameLoop();
Image img = getToolkit().getImage("Apple-Logo-icon.jpg");




public void init() {
Dimension full = getSize();
mouseX = full.width/2;
mouseY = full.height/2;
radius=diameter/2;
addKeyListener(this);
game.start();

                     }
public void paint (Graphics g) {
g.drawRect(10,10,320,195);
g.setColor(rectColor);
g.setColor(circleColor);
g.fillRect((mouseX),(mouseY),diameter1,diameter2);

//Essen:
g.setColor(EssenColor);
g.drawImage(img,160,90,this);
g.setColor(EssenColor);
g.drawImage(img,100,40,this);
g.setColor(EssenColor);
g.drawImage(img,200,170,this);
g.setColor(EssenColor);
g.drawImage(img,280,60,this);
g.setColor(EssenColor);
g.drawImage(img,50,160,this);



                               }

public void keyPressed(KeyEvent ev) {}

public void keyTyped(KeyEvent ev) {
System.out.println("Fehler-Test");


if ((mouseX == 160 && mouseY == 90) || (mouseX == 100 && mouseY == 40) || (mouseX == 200 && mouseY == 190) || (mouseX == 280 && mouseY == 60) || (mouseX == 50 && mouseY == 180) ){
this.schlangeplus = true;
}

if (mouseX == 20 && ev.getKeyCode() == KeyEvent.VK_LEFT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY==20 && ev.getKeyCode() == KeyEvent.VK_UP){
System.out.println("Game Over!");
this.gameover = true;
                                                      }

if (mouseX==300 && ev.getKeyCode()== KeyEvent.VK_RIGHT){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (mouseY==200 && ev.getKeyCode() == KeyEvent.VK_DOWN){
System.out.println("Game Over!");
this.gameover = true;
                                                          }

if (ev.getKeyCode() == KeyEvent.VK_RIGHT && mouseX <300 ) {
mouseX = mouseY+2;
this.rechts = true;
System.out.println("Fehler-Test");
                                                           }
if (ev.getKeyCode() == KeyEvent.VK_DOWN && mouseY <200) {
mouseY = mouseY+2;
this.down = true;
 System.out.println("Fehler-Test");
                                                         }

if (ev.getKeyCode() == KeyEvent.VK_UP && mouseY >20) {
mouseY = mouseY-2;
this.up = true;
System.out.println("Fehler-Test");
                                                      }

if (ev.getKeyCode() == KeyEvent.VK_LEFT && mouseX >20) {
mouseX = mouseX-2;
this.links = true;
System.out.println("Fehler-Test");
                                                       }

                                                            }
public void keyReleased(KeyEvent ev) {}

class GameLoop extends Thread {

public void run(){

while(!gameover){

if (schlangeplus == true){
  diameter2=diameter2+5;
  System.out.println("Aufgesammelt.");
}


if (rechts == true) {
mouseX = mouseY+2;
repaint();
                    }

if (down == true) {
mouseY = mouseY+2;
diameter2 = diameter2+20;
diameter1 = diameter1-20;
repaint();
                    }

if (up == true) {
mouseY = mouseY-2;
diameter2 = diameter2-20;
diameter1 = diameter1-20;
repaint();
                  }

if (links == true) {
mouseX = mouseX-2;
repaint();
                   }

try{
Thread.sleep(50);
}

catch (InterruptedException ev){}

                       }


                         }
                         }


                         }

du musst dann nur noch das bild rausnehmen für das Essen...^^ (Apfel.jpg)


----------



## hdi (8. Mrz 2009)

Ach, ich hasse Applets. Sagen wir mal so: Ich kann Applets nicht, ich weiss nur dass da
immer irgendwas nicht funktioniert. (also so, wie es in Applications geht)

Hier is jetz Schluss für mich, *dir muss jmd weiterhelfen der sich mit Applets auskennt*.


----------



## StickToFreak (8. Mrz 2009)

Okay. Trotzdem danke^^. Ich werd mal nen neuen Thread eröffnen .


----------

