Problem mit KeyEvent

sirconflex

Grünschnabel
Ich soll Tetris programmieren, hab aber bisher noch keinerlei Erfahrung mit Grafikprogrammierung. Deshalb Nachsicht wenn der code etwas wirr aussieht.
Nun zum Problem ich habe eine Klasse erstellt die mir einen Block nach unten fallen lässt. das funktioniert auch wunderbar, jedoch möchte ich diesen nun noch nach links und rechts bewegen. Also dachte ich mir , ich führe eine variable left ein, die jeweils um eins erhöht wird, wenn ich die Pfeiltaste z.b.nach links drücke, diese variable sollte dann subtrahiert werden, von meiner x Position. NUr funktioniert das nicht weil er erst meien Grafik nach unten laufen lässt und erst danach den keyevent bearbeitet...

Hier mal wie ich das programmiert hab...

Methode um den Block fallen zu lassen(stört euch nicht an den Zahlen für die Pixel :-) )
is ne klasse die thread extended
Code:
while(counter1 < 2){
	for(y=0;y < 24-2*counter1;y++)
		 {			 
                        aktuellepositiony[i] = y; //für die abspeicherung wichtig
		      aktuellepositionx[i] = x;
		       System.out.println(y);	//damit ich weis welches feld er grad benutzt
			  if(y!=0)
			   {
				 g.setColor(Color.BLACK);
				 g.fillRect(208-left,30+16*y-16,16, 16); 
 		    	          g .fillRect(208-left+16,30+16*y-16,16, 16);
		    	          g.fillRect(208-left,30+16+16*y-16,16, 16);
		    	          g.fillRect(208-left+16,30+16+16*y-16,16,16);
		    	}
			  g.setColor(Color.RED);
	    	  g.fillRect(208-left,30+16*y,16, 16);
	    	  g.fillRect(208-left+16,30+16*y,16, 16);
	    	  g.fillRect(208-left,30+16+16*y,16, 16);
	    	  g.fillRect(208+16-left,30+16+16*y,16, 16);
	    	  try{Thread.sleep( 250 );}
	          catch(InterruptedException e){}
//left variable sollte dabei von der x-position subtrahiert werden...

Code für den keyevent(steht in einer anderen klasse, die von JFrame abgeleitet ist...)
Code:
public void keyPressed(KeyEvent ke)
	{
		if( ke.getKeyCode() == KeyEvent.VK_LEFT)
        {
			b.left++;  //zugriff auf die left variable
			System.out.println(b.left);
        }
		
	}
Ich bräucht also irgendwas wie ich die variable left zur laufzeit der while schleife ändern könnte, oder vielleicht habt ihr ja noch ne bessere idee
thx im vorraus
 
morgen!

probier mal das mit dem KeyEvent in die "hauptklasse"(also in die gleiche wie das mit der graphik ausgabe) zu geben.

mfg
besser
 
jo das hatte ich versucht nur leider kann ich dort keinen keyListener adden, weil ich nicht von jframe dort abgeleitet habe.
(extend ist schon verbraucht für thread)

Hab gelesen das sowas möglich ist mit den keystate funktionen, leider gibts die nur in
C/C++. Vielelicht gibts ja sowas ähnliches in java

Muss ja eigentlich irgendwie gehen das tasten gleichzeitig abgearbeitet werden und nicht erst nach nem prozess......


MFG
Sirc
 
Verstehe ich nicht so ganz, du kannst doch
Code:
public class deineRechtEcke extends Thread implements KeyListener{
...
public void keyPressed(KeyEvent ke){
}
public void keyReleased(KeyEvent ke){
}
public void keyTyped(KeyEvent ke){
}
}
schreiben dann hast du doch beides in einer Klasse...
mfg
 
und wo kann ich dann den KeyListener adden ? :confused:


Das Problem ist ja das die Methode in einer anderen Klasse ausgeführt wird, die nicht von Frame abgeleitet ist. Ich weis also nicht wo ich den keylistener adden kann....

MFG
Sirconflex
 
Zuletzt bearbeitet:
Sorry evt. stehe ich mal wieder auf dem Schlauch, aber was hat den dein Frame mit den KeyListenern zu tun? Es ist doch egal ob diese Listener in deiner Frame Klasse sind oder nicht...
Wenn du das so implementierst wie ich obern geschrieben habe musst du ja garkeine Listener registrieren...
 
Also ich hab gestern Abend mal die beiden Klassen zusammen gefügt, das ergebnis war das die taste erst nach der paint methode reagiert hat. Also erst als die paint Methode ausgeführt war.....
HIer nochmal die Klasse:

Code:
public void paint(Graphics g)
	{
		String buffer;

		buffer = "  " + level;
		g.drawString("Your Level:" + buffer.substring(buffer.length() - 2), 3, 29 + 16);

		buffer = "  " + lines;
		g.drawString("Full Lines:" + buffer.substring(buffer.length() - 2), 3, 29 + 32);

		buffer = "     " + score;
		g.drawString(" Score:" + buffer.substring(buffer.length() - 5), 3, 29 + 64);

		g.drawString("   H E L P", 3, 29 + 112);
		g.drawString("F1:Pause", 3, 29 + 144);
		g.drawString(" 7:Left", 3, 29 + 160);
		g.drawString(" 9:Right", 3, 29 + 176);
		g.drawString(" 8:Rotate", 3, 29 + 192);
		g.drawString(" 1:Draw next", 3, 29 + 208);
		g.drawString(" 6:Speed up", 3, 29 + 224);
		g.drawString(" 4:Drop", 3, 29 + 240);
		g.drawString("  SPACE:Drop", 3, 29 + 256);
		g.drawString("   Next:", 3, 29 + 304);

		g.drawLine(144,30,144,430); 	//Vertikale linke Linie
		g.drawLine(144,430,304,430);	//Horizontale Linie
		g.drawLine(304,430,304,30); 	//Vertikale linke Linie
		while(counter1 < 2){
			for(y=0;y < 24;y++)
				 {
				  aktuellepositiony[i] = y;
				  aktuellepositionx[i] = x-left;
				  System.out.println(y);	
				  if(counter1 >0)
				    {
					 if(aktuellepositiony[i-1]*16==32)counter1=20; //Spielfeld zu ende
					 if(counter1 ==1)c=16;
					 else c= 32;
					 if(aktuellepositiony[i-1]*16 == aktuellepositiony[i]*16+c)//Steine die im Weg sein könnten
					    {
						 break; //keine bessere abbruch bedingung gefunden
					    }
				    }
				 
				  if(y!=0)
				   {
					 g.setColor(Color.BLACK);
					 g.fillRect(208-left,30+16*y-16,16, 16);
			    	 g.fillRect(208-left+16,30+16*y-16,16, 16);
			    	 g.fillRect(208-left,30+16+16*y-16,16, 16);
			    	 g.fillRect(208-left+16,30+16+16*y-16,16,16);
			    	}
				  g.setColor(Color.RED);
		    	  g.fillRect(208-left,30+16*y,16, 16);
		    	  g.fillRect(208-left+16,30+16*y,16, 16);
		    	  g.fillRect(208-left,30+16+16*y,16, 16);
		    	  g.fillRect(208+16-left,30+16+16*y,16, 16);
		    	  try{Thread.sleep( 250 );}
		          catch(InterruptedException e){}
				 }
			score.linie[y]=score.linie[y]+2;	 
			score.linie[y+1]=score.linie[y+1]+2;
			i++;
			counter1++;
			}
			System.out.println("Ende:"+counter1);
			score.score();
			for(int h = 0; h < 2;h++)
			  {
				System.out.println(aktuellepositiony[h]);
			  }
			for(int h = 0; h < 2;h++)
			  {
				System.out.println(aktuellepositionx[h]);
			  }
	}

Könnte es vielleicht an dem Thread liegen ? Kenn mich mt dem Thread nicht so aus..
Ich müsste also wissen wie ich die paint methode (oder was auch immer) verändern muss, das die Taste während ablauf der Paint methode reagiert..

Hier noch die main:
Code:
public static void main(String[] args) {
		Thread t1 = new Thread(new Tetris());
		t1.run();

	}

MFG
Sirc
 
Du kannst für deinen JFrame und deinen KeyListener durchaus verschiedene Klassen nutzen. Ist beim MVC Pattern auch üblich, da kommt dann halt noch die Model Klassen hinzu. Anschließend registrierst du einfach den KeyListener beim View:
in JFrame Klasse:
addKeyListener(klasseMitKeyListenerObjekt);

Vielleicht liegt dein Problem eher in der for Schleife? Beim ersten Aufruf von paint wird der Stein gleich 24x neu gezeichnet (y Positionen nach unten), oder? Eigentlich müsstest du glaube ich den "Spieltakt" mit Thread.sleep woanders ablaufen lassen, dieser ruft dann jedes Mal repaint() auf, um die Component neu zu zeichnen. Das wird an paint weitergeleitet, du liest in paint den aktuellen y Wert aus und zeichnest nur EINE Position des Steins (nicht die gesamte Y-Achse).

Wenn du nicht jedes Mal die Schriften usw. mit neu zeichnen willst, kannste die ja auch in eine andere Component auslagern.
 
Wie gesagt ich kenn mich thread eigentlich so gut wie gar nicht aus!
Vielleicht könntest du mir sagen wo ich Thread.sleep aufrufen sollte, ich denke es wird die run methode sein. Waer nett wenn du mir gleich ein Bsp zeigen könntest...


Daweil probier ich die paint methode so abzuändern das wirklich nur für ein y gezeichnet wird...

MFG
Sirc
 
z.B.:
in einer beliebigen Klasse mit dem Thread:
public void run(){
while{abbruchBed){
Thread.sleep(time);
componentMitPaint.repaint();
}
}

in der Component Klasse mit paint (bei dir JFrame?):
public void paint(Graphics g){
y=getY();
g.drawRect(...);
}

zusätzlich noch irgendeine Klasse mit dem KeyListener (wie gesagt: registrieren):
public void keyPressed(KeyEvent e){
....e.getKeyCode()...
....switch....
--> setY(...);
}

Übrigens (wegen Problem oben): wenn du mal in Bedrängnis bist wegen der abgeleiteten Thread Klasse, kannste auch einfach das Interface Runnable implementieren um den Thread zu erstellen.

Gruß, Ben
 
Zurück