KeyListener-Problem nach dem "Gedrückthalten" einer Taste

DarXun

Aktives Mitglied
Heyho!

Ich bin gerade dabei 'n bisschen rumzuprobieren, was die Spieleprogrammierung angeht, hab da eher was retro-mäßiges im Sinne und will's grafisch usw. auch recht simpel halten.

Ich denke mal, dass so ziemlich jeder hier Pokémon kennt.
In Pokémon, oder auch diversen anderen Spielen wie z.B. Dragon Quest Monsters, steuert der Spieler seine Spielfigur über die Pfeiltasten (bzw. eigentlich das Steuerkreuz am Gameboy).
Drückt man die entsprechende Taste bewegt sich die Figur langsam auf das nächste Feld, man kann sich also eigentlich nur in einem vorgegebenen Gitter bewegen.

Das hab ich soweit auch umgesetzt. Ich hab meine Figur die sich ohne weiteres in ihrem 16px x 16px Gitter bewegt.
Mein Problem ist jedoch, dass, wenn ich die entsprechende Pfeiltaste gedrückt halte für kurze Zeit, dann aber loslasse, sich die Figur immernoch weiterbewegt.
Ich glaube, dass ganze liegt am KeyListener, der bei mir bei eben entsprechendem Tastendruck, die Figur passend bewegt.

Das Optimum wäre für mich, dass wenn ich eine Pfeiltaste gedrückt halte, die Figur sich bewegt und wenn ich wieder loslasse, die Figur aufhört sich zu bewegen, bzw. noch eben die Bewegung in's Gitter abschließt.

Ich hab schon versucht, den KeyListener wieder zu entfernen und nach der Bewegung wieder hinzuzufügen.
Ich hab natürlich auch schon versucht, einfach per Abfrage, ob die Figur sich grade bewegt, das ganze zu steuern.

Fazit: Will alles nicht!

Ich hab den ganzen Quatsch mal hochgeladen, damit Ihr euch ein Bild davon machen könnt.
Einfach die main-Methode der Klasse Game ausführen, und mal nach links und rechts usw. bewegen.
Die Figur kann noch außerhalb des Bildschirms kommen... das führt leider noch zu einer Exception, hab mich noch nicht drum gekümmert, aber kommt alles noch.
Wenn ihr die Bewegung dann mal gesehen habt, haltet die Tasse einfach mal gedrückt und lasst wieder los nach kurzer Zeit... genau DAS ist mein Problem ;)

Link: Klick mich :3
 
Zuletzt bearbeitet von einem Moderator:

DarXun

Aktives Mitglied
Dafür hab ich ja extra den Quellcode hochgeladen...
Aber hier ist nochmal der KeyListener:

Java:
package Main;

import java.awt.event.*;

public class GameKeyAdapter extends KeyAdapter
{
    private GameField gf;

    public GameKeyAdapter(GameField gf)
    {
        this.gf = gf;
    }
    
    public void keyPressed(KeyEvent e)
    {                    
        switch(e.getKeyCode())
        {
            case(KeyEvent.VK_UP):
                Game.getInstance().getPlayer().move(1);
                break;
                            
            case(KeyEvent.VK_RIGHT):
                Game.getInstance().getPlayer().move(2);
                break;
                            
            case(KeyEvent.VK_DOWN):
                Game.getInstance().getPlayer().move(3);
                break;
                            
            case(KeyEvent.VK_LEFT):
                Game.getInstance().getPlayer().move(4);
                break;
        }
        gf.repaint();
    }
}
 
S

SlaterB

Gast
du kannst nicht einfach auf jedes Event reagieren, woher willst du wissen, ob pro Sekunde 5 Events oder 5000 kommen?
vielleicht variiert das auch je nach Systemlast, schön wird das nicht, auch wenn dein aktueller Fehler nicht direkt erklärbar ist,


da sollte generell ein anderes Konzept her:
ein Thread läuft, macht relativ kontrollierbare 30ms-Pausen und bewegt dann SOLANGE der ensprechende Status gesetzt ist,
was bei Beginn und Ende des Maus-Drückens je einmal geändert wird

schau dir einfach folgendes Tutorial an, da kommt das vor
http://www.ralf-bauer.org/java/tutorial/Tutorial.zip
 

Momolin

Aktives Mitglied
Hallo,

bei mir hat es gereicht, wenn ich in Deinem Code in der Klasse GameWindow folgende Änderung gemacht habe:

Java:
package Main;

import javax.swing.JFrame;

/**
 *
 */
public class GameWindow extends JFrame
{
    private GameField gf;
    private GameKeyAdapter k;

    public GameWindow(String title)
    {
        super(title);
        /* folgende zwei Zeilen habe ich getauscht */
        // gf muss vor der Übergabe an GameKeyAdapter
        // instantiiert werden 
        gf = new GameField();
        k = new GameKeyAdapter(gf);


        addKeyListener(k);
        add(gf);
    }

    public GameField getGameField()
    {
        return gf;
    }
}

dann musst Du in der Klasse Level an folgender Stelle noch die Arraygrenzen von o prüfen, bevor Du neu zeichnest.

Java:
for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (objects[x][y] != null) {
					int i = objects[x][y].getX();
					int j = objects[x][y].getY();	
					o[i][j] = objects[x][y];
				}
			}
		}

Viele Grüße
Momolins
 

DarXun

Aktives Mitglied
@Momolin

Vielen Dank für die Hilfe, leider ging's garnicht darum >.<
Aber halb so wild ;-)

@SlaterB

Also es kommen, wie du gesagt hast, natürlich etliche Events an, und wie du ebenfalls sagtest, kann ich nicht auf jedes reagieren.
Genau das ist mein Problem, ich will diese Events ja praktisch abfangen, bzw. alle nicht ausführen, wenn der Player eh noch in der Methode move(int dir) ist...
Es sollte praktisch erst dann nach weiteren Events gefragt werden, wenn move fertig ist, bzw. alle Events, die während move ankommen, sollten verworfen werden!

Dein Vorschlag, das gesamte Movement abzuändern finde ich nicht so schön.
Es ist ja gerade mein Ziel, so ein Movement-System hinzubekommen... ganz so wie bei den alten Gameboy-Spielen, wie eben Pokémon oder Dragon Quest Monsters
 
S

SlaterB

Gast
> Es ist ja gerade mein Ziel, so ein Movement-System hinzubekommen

was meinst du mit 'so ein System', hast du das andere so genau verstanden, dass du da Unterschiede erkennen kannst?

das was ich vorschlage bedeutet auch Bewegung solange gedrückt ist (nicht Aufhören bei einem zweiten Klick oder so),
nur viel sauberer implementiert, arbeite einfach das Tutorial durch, selbst wenn du das nicht magst hast du eine gute andere Sicht kennengelernt
 

Momolin

Aktives Mitglied
Hi ich schlage vor die Klasse Player mit einer stopMotion Methode und einem Timer für die Bewegung auszustatten:
Java:
public class Player extends DisplayableObject implements Moveable,
		ActionListener {
	private int speed;

	private Timer moveTimer;

	public Player() {
		super();
		sprite = new MovingSprite("Data/player");

		direction = 1;
		solid = true;

		speed = sprite.getWidth(); // because width and height are equal
                //der erste Parameter bestimmt die Geschwindigkeit
		moveTimer = new Timer(50, this);
		moveTimer.setInitialDelay(0);
	}

	public void move(int dir) {
		direction = dir;
// so könnte man während der Bewegung neue Events übergehen 
           if (!moveTimer.isRunning())
		moveTimer.restart();
	}

	public void stopMotion() {
		moveTimer.stop();
	}

	public void turn(int dir) {
	}
/**
entspricht der "GameLoop"
*/
	@Override
	public void actionPerformed(ActionEvent arg0) {

		sprite.setDirection(direction);
		Game g = Game.getInstance();
		Level l = g.getLevel();

		switch (direction) {
		case 1:
			setY(getY() - 2);
			break;

		case 2:
			setX(getX() + 2);
			break;

		case 3:
			setY(getY() + 2);
			break;

		case 4:
			setX(getX() - 2);
			break;
		}

		l.refresh();
		g.repaintField();
	}
}

und dann in der Klasse GameKeyAdapter beim Loslassen eine Pfeiltaste den Player zu stoppen:

Java:
public class GameKeyAdapter extends KeyAdapter {
	private GameField gf;

	public GameKeyAdapter(GameField gf) {
		this.gf = gf;
	}

	@Override
	public void keyReleased(KeyEvent e) {
		Game.getInstance().getPlayer().stopMotion();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {

		case (KeyEvent.VK_UP):
			Game.getInstance().getPlayer().move(1);
			break;

		case (KeyEvent.VK_RIGHT):
			Game.getInstance().getPlayer().move(2);
			break;

		case (KeyEvent.VK_DOWN):
			Game.getInstance().getPlayer().move(3);
			break;

		case (KeyEvent.VK_LEFT):
			Game.getInstance().getPlayer().move(4);
			break;
		}
		gf.repaint();
	}
}

meine Änderunge aus dem ersten Posting sind aber weiter erforderlich.

Viele Grüße
Momolin
 
Zuletzt bearbeitet:

DarXun

Aktives Mitglied
Erstmal: Vielen Dank für die freundliche und lehrreiche Hilfe.
Ich bin das Tutorial teilweise durchgegangen und hab den Quellcode selbstständig programmieren können, kam etwa auf's gleiche raus...

Ein Problem habe ich jedoch noch.
Ich hatte ja anfangs erläutert, dass der Player nach einer Bewegung in einem 16px x 16px Gitter landen soll.
Durch das Movement-System, wie es jetzt besteht, landet der Spieler aber in einem 2px x 2px Gitter.
Was ich aber vermeiden will, ist, dass ich den Player um 16px bewege, also zumindest bei jedem Schritt.

Mein Ansatz das zu lösen wäre, sobald die Taste gelöst wurde, zu schauen, ob der Spieler sich in dem Gitter befindet, und falls nicht, ihn eben je nach `direction` weiter in 2er Schritten so zu bewegen, dass er in eben genannten Gitter landet.

Ich bin mir nur nicht sicher, wo ich das ganze einbauen soll. Ich denke, dass es wohl in die stopMotion()-Methode gehört, kann das ganze aber auch gerade nicht ausprobieren, werd' ich aber, sobald ich die Zeit dazu habe!

Vielen Dank nochmal!!
 

Momolin

Aktives Mitglied
Hallo,
Mein Ansatz das zu lösen wäre, sobald die Taste gelöst wurde, zu schauen, ob der Spieler sich in dem Gitter befindet, und falls nicht, ihn eben je nach `direction` weiter in 2er Schritten so zu bewegen, dass er in eben genannten Gitter landet.

Ich bin mir nur nicht sicher, wo ich das ganze einbauen soll. Ich denke, dass es wohl in die stopMotion()-Methode gehört, kann das ganze aber auch gerade nicht ausprobieren, werd' ich aber, sobald ich die Zeit dazu habe!
würde ich genau so machen, da diese Methode ja am Ende der Bewegung steht und das ist doch der richtige Zeitpunkt Position (oder auch andere Eigenschaften) des Players zu korrigieren.

Grüße
Momolin
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
GianaSisters JFrame mit JInternalFrames, Keylistener-Problem AWT, Swing, JavaFX & SWT 9
7 AWT problem: KeyListener/ test im Label umändern AWT, Swing, JavaFX & SWT 4
B SWT Problem: Wie kann man für jede TableColumn einen eigenen KeyListener registrieren. AWT, Swing, JavaFX & SWT 1
D Problem mit KeyListener AWT, Swing, JavaFX & SWT 2
L Snake in Java KeyListener Problem AWT, Swing, JavaFX & SWT 30
V Problem mit KeyListener im Fullscreen-Modus AWT, Swing, JavaFX & SWT 2
D KeyListener Problem bei JPanel wechsel AWT, Swing, JavaFX & SWT 2
F Swing Problem mit KeyListener||paintComponent() in JFrame AWT, Swing, JavaFX & SWT 12
Screen Focus Problem , KeyListener, TextField , Key AWT, Swing, JavaFX & SWT 4
L Problem mit KeyListener AWT, Swing, JavaFX & SWT 3
M problem mit keylistener/textarea AWT, Swing, JavaFX & SWT 6
M KeyListener Problem unter Firefox AWT, Swing, JavaFX & SWT 2
capgeti SWT KeyListener 2 Tasten Problem AWT, Swing, JavaFX & SWT 3
G KeyListener Problem AWT, Swing, JavaFX & SWT 4
J Problem mit KeyListener - Programm stürtzt ab AWT, Swing, JavaFX & SWT 2
G KeyListener Problem in GUI (macht einfach nichts) AWT, Swing, JavaFX & SWT 2
G Keylistener/Fokus Problem AWT, Swing, JavaFX & SWT 3
R KeyListener Problem AWT, Swing, JavaFX & SWT 7
J Problem mit KeyListener AWT, Swing, JavaFX & SWT 8
MaRkElE KeyListener Verzögerung deaktivieren AWT, Swing, JavaFX & SWT 1
P JTextfield Text durch Keylistener verändern AWT, Swing, JavaFX & SWT 4
N Keylistener & JComboBox AWT, Swing, JavaFX & SWT 5
B Swing JButton mit KeyListener AWT, Swing, JavaFX & SWT 3
H KeyListener funktioniert nicht AWT, Swing, JavaFX & SWT 1
Fridolin111 Der KeyListener Löst kein event aus AWT, Swing, JavaFX & SWT 6
B KeyListener auf JFrame reagiert nicht AWT, Swing, JavaFX & SWT 8
N Mit KeyListener ein rechteck zeichnen AWT, Swing, JavaFX & SWT 9
S Swing JPanel nimmt keinen KeyListener an AWT, Swing, JavaFX & SWT 7
P JPanel KeyListener hinzufügen AWT, Swing, JavaFX & SWT 8
B Swing KeyListener auf Container? AWT, Swing, JavaFX & SWT 1
T Event Handling KeyListener reagiert nicht AWT, Swing, JavaFX & SWT 10
K KeyListener ohne JFrame AWT, Swing, JavaFX & SWT 9
C Keylistener funktioniert nicht AWT, Swing, JavaFX & SWT 1
T KeyListener funktioniert nicht wenn ich ein JButton hinzufüge AWT, Swing, JavaFX & SWT 1
A Event Handling Muss ich 'KeyListener' tasuend mal zufügen? AWT, Swing, JavaFX & SWT 7
S mit keylistener frame schliessen AWT, Swing, JavaFX & SWT 8
S Keylistener reagiert bei Buttons nicht. AWT, Swing, JavaFX & SWT 8
S KeyListener funktioniert nicht AWT, Swing, JavaFX & SWT 2
R KeyListener in mehreren Panels AWT, Swing, JavaFX & SWT 5
V Tastatur KeyListener für mehrere Buttons AWT, Swing, JavaFX & SWT 1
J JLabel Visible setzen in KeyListener AWT, Swing, JavaFX & SWT 13
X KeyListener AWT, Swing, JavaFX & SWT 0
L KeyListener für JDialog AWT, Swing, JavaFX & SWT 7
N KeyListener funktioniert nicht richitg AWT, Swing, JavaFX & SWT 4
Z SnakeGame Schlange per KeyListener bewegen! AWT, Swing, JavaFX & SWT 10
T KeyListener AWT, Swing, JavaFX & SWT 2
7 KeyListener tastatur temporär blockieren AWT, Swing, JavaFX & SWT 7
U Mouse + Keylistener AWT, Swing, JavaFX & SWT 12
K ActionListener mit KeyListener AWT, Swing, JavaFX & SWT 7
J JWindow und keylistener AWT, Swing, JavaFX & SWT 1
F JavaFX KeyListener zum Fenster öffnen/schließen AWT, Swing, JavaFX & SWT 9
A Swing KeyEvent mit KeyListener und KeyAdapter kürzer schreiben AWT, Swing, JavaFX & SWT 7
D JTextArea auf KeyListener Command AWT, Swing, JavaFX & SWT 6
C KeyListener AWT, Swing, JavaFX & SWT 5
Doopy Event Handling KeyListener funktioniert nach Restart nicht mehr AWT, Swing, JavaFX & SWT 7
S KeyListener geht nicht AWT, Swing, JavaFX & SWT 12
C Swing KeyListener in JPanel AWT, Swing, JavaFX & SWT 2
A KeyListener Button wechseln & Programm beenden AWT, Swing, JavaFX & SWT 4
M Frage zu KeyListener bzgl. JApplet AWT, Swing, JavaFX & SWT 3
H Bild mit KeyListener verschieben AWT, Swing, JavaFX & SWT 2
C JTextField KeyListener AWT, Swing, JavaFX & SWT 6
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
bluerob Fehler bei Wertübermittlung über KeyListener AWT, Swing, JavaFX & SWT 3
E Swing KeyListener implementieren AWT, Swing, JavaFX & SWT 12
P KeyListener reagiert nicht AWT, Swing, JavaFX & SWT 11
M KeyListener richtig implementieren AWT, Swing, JavaFX & SWT 3
T KeyListener AWT, Swing, JavaFX & SWT 4
R KeyListener in JWindow AWT, Swing, JavaFX & SWT 7
T BlueJ KeyListener AWT, Swing, JavaFX & SWT 7
Z KeyListener AWT, Swing, JavaFX & SWT 2
M Swing KeyListener in JTextfield AWT, Swing, JavaFX & SWT 4
C Swing KeyListener für JPanel funktioniert nicht AWT, Swing, JavaFX & SWT 8
VfL_Freak Swing KeyListener, um einen Dialog per ESC zu schließen AWT, Swing, JavaFX & SWT 6
A Keylistener reagiert nicht AWT, Swing, JavaFX & SWT 10
J KeyListener um auf CTRL-Enter zu reagieren AWT, Swing, JavaFX & SWT 2
B "globaler" KeyListener? AWT, Swing, JavaFX & SWT 3
B JTable TableHeader KeyListener AWT, Swing, JavaFX & SWT 4
S Swing KeyListener und JList AWT, Swing, JavaFX & SWT 2
R KeyListener funzt nicht AWT, Swing, JavaFX & SWT 2
X KeyListener AWT, Swing, JavaFX & SWT 4
P KeyListener + Animation AWT, Swing, JavaFX & SWT 2
M Fokus für KeyListener AWT, Swing, JavaFX & SWT 9
M AWT KeyListener reagiert nicht AWT, Swing, JavaFX & SWT 10
C Swing KeyListener reagiert nicht AWT, Swing, JavaFX & SWT 7
K JFrame + KeyListener + Runnable = Fehler AWT, Swing, JavaFX & SWT 3
F Tastenabfrage (KeyListener) AWT, Swing, JavaFX & SWT 2
S Swing JTree mit KeyListener AWT, Swing, JavaFX & SWT 2
L AWT KeyListener, requestFocus und KeyBindings AWT, Swing, JavaFX & SWT 8
E JFrame akzeptiert den KeyListener nicht AWT, Swing, JavaFX & SWT 3
P Swing KeyListener hört nur manchmal zu AWT, Swing, JavaFX & SWT 2
earlgrey_tea AWT KeyListener bekommt keine Signale AWT, Swing, JavaFX & SWT 3
A KeyListener funktioniert nicht AWT, Swing, JavaFX & SWT 4
B Swing Keylistener fuer Dialog-Buttons AWT, Swing, JavaFX & SWT 2
B KeyListener Strg+s AWT, Swing, JavaFX & SWT 5
D Globaler Keylistener AWT, Swing, JavaFX & SWT 4
L AWT KeyListener, Taste gedrückt halten AWT, Swing, JavaFX & SWT 12
M Komisches Verhalten: JCombobox mit KeyListener AWT, Swing, JavaFX & SWT 13
R KeyListener - welcher Komponente hinzufügen AWT, Swing, JavaFX & SWT 5
Developer_X AWT KeyListener wird nicht ausgeführt! AWT, Swing, JavaFX & SWT 3
N JFrame und KeyListener AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben