KeyListener - dwa klawisze jednoczesnie

Odpowiedz Nowy wątek
2006-12-25 10:04
MKSB
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();
                }
            }
        );
    }

Pozostało 580 znaków

2006-12-25 10:06
MKSB
0

Przepraszam za format kodu, troche sie rozjechal na forum.

Pozostało 580 znaków

2006-12-26 20:50
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

Pozostało 580 znaków

2006-12-27 00:51
partyzant
0

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

Pozostało 580 znaków

2007-01-04 00:58
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

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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