KeyListener - dwa klawisze jednoczesnie

0

Pisze mala gre, w ktorej oprocz poruszania gora-dol i prawo-lewo potrzebuje tez poruszania na ukos czyli gora-prawo itd. Pronlem w tym, ze keyPressed lapie mi tylko jeden przycisk kiedy naciskam oba jednoczesnie. W jaki sposob temu zaradzic ?

	Test()
	{
		setPreferredSize(new Dimension(800, 600));
		setFocusable(true);
		
		
	    this.addKeyListener
		(
			new KeyAdapter()
			{
				public void keyPressed(KeyEvent ev)
				{
					int code = ev.getKeyCode();
					
					if (code == KeyEvent.VK_UP)
					{
						y-=5;
					}
				    else if (code == KeyEvent.VK_DOWN)
				    {
				    	y+=5;
				    }
					else if (code == KeyEvent.VK_LEFT)
					{
						x-=5;
					}
				    else if (code == KeyEvent.VK_RIGHT)
				    {
				    	x+=5;
				    }			    
				    repaint();
				}
			}
		);
	}
0

Przepraszam za format kodu, troche sie rozjechal na forum.

0

Naraz możesz odczytać tylko jeden kod klawisza, wiec aby wykorzystać sekwencje klawiszy można zastowosać własność interfejsu KeyListner i to że ma dwie metody keyPressed i keyReleased.

Każda akcja wcisniecia klawisza powoduje wywołanie po kolei metod keyPressed a po zwolnieniu keyReleased. Zastosował bym tu cztery zmienne boolowskie odpowiadajace każdej ze strzałek. Ustawiał bym wartości na true w metodzie keyPressed i false w keyReleased. Operacje jakie ma wykonać program w zależności od wcisnietych klawiszy uzaleznilbym od wartosci zmiennych.
Zmienna np. up i left ustawione na true mowiło by nam ze trzeba wykonać operacje poruszania na ukos(gora lewo).

Pozdrawiam BookaYashee

0

czyli nie ma opcji 2x klawisz ? (jak to mozliwe?)

0

Sprawdziłem jak są tworzone zdarzenia z tak zwanymi modyfikatorami czyli shift, control itd. Z tego co sie pobierznie przyjrzałem metody isShiftDown(), isControlDown() ,... działaja podobnie do mojego sposobu przedstawionego wyżej z ta rożnicą, że zdarzenie nie jest zapamiętywanie przez zmienna boolwska tylko zmienna int.
I tak deklaracja stałej SHIFT_MASK i CTRL_MASK w klasie InputEvent wyglada

public static final int SHIFT_MASK = Event.SHIFT_MASK;
public static final int CTRL_MASK = Event.CTRL_MASK;

a SHIFT_MASK i CTRL_MASK z kalsy Event

public static final int SHIFT_MASK		= 1 << 0;
public static final int CTRL_MASK		= 1 << 1;

czyli po prostu 1 i 2.
Wcisnięcie np shifta powoduje wywołanie obiektu InputEvent i dodanie do zmiennej modifiers wartości wcisniętego klawisza(oczywiscie tylko klawisze shift, ctrl, alt, meta(modyfikatory)), czyli odpowiedanio shift +1, ctrl +2. Zwolnienie klawisza wywołuje odjęcie od zmiennej modifiers wartości klawisza, czyli shift -1, ctrl -2.
Sama metoda sprawdzająca czy jest wcisnięty np shift wyglada następująco

public boolean isShiftDown() {
        return (modifiers & SHIFT_MASK) != 0;
    }

jest to suma bitowa zmiennych modifieres i shift_mask, czyli jeśli suma bitowa jest rożna od zera to znaczy, że shift jest wcisnięty, metoda zwraca true. Załuzmy, że w czasie wywołania tej metody mamy wcisnięte np klawisze shift i ctrl, wtedy zmienna modifiers rowna sie 3 a stała SHIFT_MASK wynosi 1 co w bitach wyglada tak:
(tylko 3 ostanie bity)
011
&001
=001
czyli wynik jest jeden, metoda zwraca true.
Metody isCtrlDown(), ..., działaja analogicznie.
Dlaczego taki sposób na dwa i wiecej przyciskow, zapewnie dlatego, że komputer jest w stanie odsłużyć tylko jedną instukcję na raz

Dla zabawy stworzyłem program który przechwytuje kombinacje strzałek na ukos. Wyświetlanie informacji jakie strzałki są wcisnięte zawarłem w wątku na podstawie zmiennych boolowskich zmienianych w metodach keyPressed i keyRelesed. Sam watek ma zaimplementowany opozniacz ustawiony standardowo na opuznienie 50 milisekund, ktorym można dynamicznie sterować za pomoca klawiszy: q + 100, w + 50, e +10, a -100, s -50, d-10 milisekund. Przedział w jakim można sie poruszac to 1-1000 milisekund. Dla ułatwienia jest klawisz pokazujacy aktualna predkość. Klawisz t.
A oto kod:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ArrowsKeysTest 
	extends JFrame
{
	public ArrowsKeysTest(){
		add(new JPanel());
		Arrows arr = new Arrows();
		arr.start();
		addKeyListener(arr);
		setSize(400,400);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		show();
	}
	
	public static void main(String[] args){
	        	new ArrowsKeysTest();
	}
}
class Arrows 
	extends Thread
	implements KeyListener
{
	private boolean up = false;
	private boolean down = false;
	private boolean left = false;
	private boolean right = false;
	private int speed = 50;
	
        
    public void keyPressed(KeyEvent ev){
    	int code = ev.getKeyCode();
            
        if(code == KeyEvent.VK_UP) up = true;
        else if(code == KeyEvent.VK_DOWN) down = true;
        else if(code == KeyEvent.VK_LEFT) left = true;
        else if(code == KeyEvent.VK_RIGHT) right = true;    
    }
    
    public void keyReleased(KeyEvent ev){
    	int code = ev.getKeyCode();
            
        if(code == KeyEvent.VK_UP) up = false;
        else if(code == KeyEvent.VK_DOWN) down = false;
        else if(code == KeyEvent.VK_LEFT) left = false;
        else if(code == KeyEvent.VK_RIGHT) right = false;             
    }
    
    public void keyTyped(KeyEvent ev){
        int code = ev.getKeyChar();
        
        if(code == 'w') speed += 50;
        else if(code == 's') speed -= 50;
        else if(code == 'q') speed += 100;
        else if(code == 'a') speed -= 100;
        else if(code == 'e') speed += 10;
        else if(code == 'd') speed -= 10;
        else if (code == 't') System.out.println(speed);
        
        if(speed < 1) speed = 1;
        else if(speed > 1000) speed = 1000;  
    }
    
    private void action(){
    	
	   if(up && right)System.out.println("skos gora prawo"); 
       else if(up && left)System.out.println("skos gora lewo");
       else if(down && right)System.out.println("skos dol prawo"); 
       else if(down && left)System.out.println("skos dol lewo");
       else if(up)System.out.println("gora");
       else if(down)System.out.println("dol");
       else if(right)System.out.println("prawo");
	   else if(left)System.out.println("lewo");
    }
        
    public void run(){
    	while(true){
    		try{
    			Thread.sleep(speed);
    			action();	
    		}catch(Exception e){}
    		 
    	}
    }
}

Pozdrawiam BookaYashee

1 użytkowników online, w tym zalogowanych: 0, gości: 1