【问题标题】:How to detect multiple keys at the same time using KeyListener?如何使用 KeyListener 同时检测多个键?
【发布时间】:2016-01-27 16:56:26
【问题描述】:

问题说明了一切!这是我的代码和我尝试使用嵌套的 if 语句,但最终失败了。我只想制作我的代码,以便当用户按住 shift 和 down 时,它会加载不同的图像:

package Michael;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class MyCanvas extends Canvas implements KeyListener /* Creates the     MyScreen method 
                                                        which extends (inherits) from 
                                                        Canvas and implements (uses) 
                                                        KeyListener. */
{
int myX = 100; // Set the initial x coordinate.
int myY = 100; // Set the initial y coordinate.

BufferedImage down; // Loads the Image.
{
    try
    {
        down = ImageIO.read(new File("Images/down.png")); /* Loads the image from 
                                                          'Images/down.png'.*/
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file."); /* If the file location is
                                                       non-existent, print on a new line
                                                       'Cannot find Image File'.*/
    }
} 

/* The exact same process is done for the next 9 images loaded, just with different,
appropriate, variable names and locations. */

BufferedImage downrun;
{
    try
    {
        downrun = ImageIO.read(new File("Images/downrun.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage left;
{
    try
    {
        left = ImageIO.read(new File("Images/left.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage right;
{
    try
    {
        right = ImageIO.read(new File("Images/right.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage runleft;
{
    try
    {
        runleft = ImageIO.read(new File("Images/runleft.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage runright;
{
    try
    {
        runright = ImageIO.read(new File("Images/runright.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage swoosh;
{
    try
    {
        swoosh = ImageIO.read(new File("Images/swoosh.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage swordraise;
{
    try
    {
        swordraise = ImageIO.read(new File("Images/swordraise.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage up;
{
    try
    {
        up = ImageIO.read(new File("Images/up.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

BufferedImage uprun;
{
    try
    {
        uprun = ImageIO.read(new File("Images/uprun.png"));
    }

    catch (IOException e)
    {
        System.out.println("Cannot find image file.");
    }
}

public MyCanvas() // The MyCanvas constructor.
{
    this.setSize(600, 400); // Makes the size of the canvas 600 x 400.
    this.addKeyListener(this); // Adds KeyListener.
    this.setBackground(Color.WHITE); // Make the background white.
    this.setFocusable(true); // Make the window automatically focused.
}

String image; // Creates the image variable as a string.

public void paint(Graphics g) // The paint method using Graphics.
{
    if (image == "down")
    {
        g.drawImage(down, myX, myY, 55, 55, null);
    }

    else if (image == "up")
    {
        g.drawImage(up, myX, myY, 55, 55, null);
    }

    else if (image == "left")
    {
        g.drawImage(left, myX, myY, 55, 55, null);
    }

    else if (image == "right")
    {
        g.drawImage(right, myX, myY, 55, 55, null);
    }

    else if (image == "swoosh")
    {
        g.drawImage(swoosh, myX, myY, 55, 55, null);
    }

    else if (image == "swordraise")
    {
        g.drawImage(swordraise, myX, myY, 55, 55, null);
    }

    else if (image == "downrun")
    {
        g.drawImage(downrun, myX, myY, 55, 55, null);
    }

    else
    {
        g.drawImage(right, myX, myY, 55, 55, null);
    }

}

@Override
public void keyPressed(KeyEvent e) // When the key is pressed:
{   
    if (e.getKeyCode() == KeyEvent.VK_DOWN) // If the down arrow is pressed:
    {
        image = "down";
        myY += 10; // Increase the y coordinate by 10 (moves down).
    }

    else if (e.getKeyCode() == KeyEvent.VK_UP) // If the up arrow is pressed:
    {
        image ="up";
        myY -= 10; // Decrease the y coordinate by 10 (moves up).
    }

    else if (e.getKeyCode() == KeyEvent.VK_LEFT) // If the left arrow is pressed:
    {
        image = "left";
        myX -= 10; // Decrease the x coordinate by 10 (moves left).
    }

    else if (e.getKeyCode() == KeyEvent.VK_RIGHT) // If the right arrow is pressed:
    {
        image = "right";
        myX += 10; // Increase the x coordinate by 10 (moves right)
    }

    else if (e.getKeyCode() == KeyEvent.VK_1) // If the 1 button is pressed:
    {
        image = "swordraise";
    }

    else if (e.getKeyCode() == KeyEvent.VK_SHIFT)
    {
        if (e.getKeyCode() == KeyEvent.VK_DOWN)
        {
            image = "downrun";
            myY += 50;
        }
    }

    repaint(); // Refresh the Images.
}

@Override
public void keyTyped(KeyEvent e) // When the key is typed:
{
    // TODO Auto-generated method stub
}

@Override
public void keyReleased(KeyEvent e) // When the key is released:
{
    if (e.getKeyCode() == KeyEvent.VK_1) // If the 1 button is released:
    {
        image = "swoosh";
    }

    repaint();
}
}

非常感谢!

【问题讨论】:

  • 对于example。您的代码中几乎没有表明需要Canvas,这无法通过使用JPanel 来解决,它提供了使用键绑定API 的能力,它克服了KeyListener 的一些烦人的限制

标签: java awt keylistener


【解决方案1】:

这个答案为 Michael 提供了一种稍微不同的方法,将所有按键的键码存储在 ArrayList 数据结构中,而不是布尔数组。

ArrayList<int> keys=new ArrayList();
//This ArrayList will hold all the key codes of currently pressed keys.

@Override
public void keyPressed(KeyEvent k){
    if(!keys.contains(k.getKeyCode())){
        keys.add(k.getKeyCode());
    }
}

@Override
public void keyReleased(KeyEvent k){
    if(keys.contains(k.getKeyCode())){
        keys.remove(keys.indexOf(k.getKeyCode()));
    }
}

要测试当前是否按下了 shift 键,请运行此代码,因为 shift 的键代码是 16:

    keys.contains(16);

【讨论】:

    【解决方案2】:

    您可以创建一个布尔数组,表示一个键是一个还是关闭现在

    boolean[] keys = new boolean[500];//whatever the highest keycode is
    //....
    public void keyPressed(KeyEvent e){
        keys[e.getKeyCode] = true;
    }
    
    public void keyReleased(KeyEvent e){
        keys[e.getKeyCode] = false;
    }
    

    然后,在您的更新(或者在这种情况下,您的 paint)方法中,您可以像这样使用您的数组:

    public void update(){
        if (keys[KeyEvent.VK_SHIFT] && keys[KeyEvent.VK_DOWN]){
            //user is holding down both shift and down arrow key
        }
    }
    

    【讨论】:

    • KeyCode.VK_Whatever@McGovno 的最高值
    • //用户同时按住两者..什么? :)
    • 那么我的最高键码是多少?我的 keycode 没有数字,所以我有点困惑...
    • KeyEvent.VK_SHIFT 一个数字;一个int 具体来说。因此,为确保您在访问keys[e.getKeyCode] 时永远不会越界,请确保将其设置得足够大以容纳最大的KeyEvent.VK 值@McGovno
    • @Michael Code 有点工作,除了当我按住 shift 并点击 down 键时,没有任何反应,但如果我按住 down 键并点击 shift,它会冲刺。我希望它是相反的方式,但我似乎无法弄清楚如何做到这一点。
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 2015-07-09
    • 2011-07-09
    • 2011-02-07
    • 2019-09-07
    • 2013-12-16
    相关资源
    最近更新 更多