在Java游戏中,按一个键取消仍然按下的另一个键

时间:2014-01-01 09:33:22

标签: java swing sprite paintcomponent keylistener

我在java中制作2D游戏。

在游戏中,按左右箭头键可旋转精灵并操纵名为“角度”的变量。按向上箭头键,根据'角度计算精灵应该移动的方向。变量

这样可行,但我在移动时无法操纵角度,也就是在按下向上箭头的同时按下左或右键。

按向上箭头使程序忽略按下其中一个箭头键的事实。

我搜索了论坛,发现了一个如何处理这个问题的建议,但我不确定它对我的计划是最好的。 (我找到了:How do I handle simultaneous key presses in Java?

这里有一些代码:

Thing类的相关方法:

    public void keyPressed(KeyEvent e){

    int key = e.getKeyCode();

    if(key==KeyEvent.VK_LEFT){ setAngle(getAngle()-5); 
            leftPressed=true; // *new* }
    if(key==KeyEvent.VK_RIGHT)setAngle(getAngle()+5);{
            rightPressed=true; // *new* }
    if(key==KeyEvent.VK_UP){

        dy = (float) ( Math.sin( getAngle() ) ) * 5;
        dx = (float) ( Math.sin( 90-getAngle() ) ) * 5;
                    if(leftPressed==true)angle-=5; // *new*
        if(rightPressed==true)angle+=5; // *new*

    }

public void move(){
    x += dx;
    y += dy;
}

}

Board类(管理游戏的类:)

package learningMovement;

import java.util.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener, KeyListener {

    Thing t;

    Timer timer;

    public Board(){
        setBackground(Color.BLACK);
        timer = new Timer(10,this);
        t = new Thing();
        setFocusable(true);
        timer.start();
        addKeyListener(this);
    }

    public void paintComponent(Graphics g)
    {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.rotate( Math.toRadians(t.getAngle()), t.getX() + (t.getWidth()/2), t.getY() + (t.getHeight()/2) );
        g2d.drawImage(t.getImage(),(int)t.getX(),(int)t.getY(),this);

    }

    public void actionPerformed(ActionEvent e){

        t.move();
        repaint();

    }

    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if(key==KeyEvent.VK_LEFT)t.keyPressed(e);
        if(key==KeyEvent.VK_RIGHT)t.keyPressed(e);
        if(key==KeyEvent.VK_UP)t.keyPressed(e);

    }

    public void keyReleased(KeyEvent e) {

        int key = e.getKeyCode();

        if(key==KeyEvent.VK_LEFT)t.keyReleased(e);
        if(key==KeyEvent.VK_RIGHT)t.keyReleased(e);
        if(key==KeyEvent.VK_UP)t.keyReleased(e);

    }

    public void keyTyped(KeyEvent arg0) {}



}

我该如何解决这个问题?感谢

2 个答案:

答案 0 :(得分:2)

KeyListener只会举起一个活动。这意味着,当调用keyPressed时,它代表单个键事件。

相反,您需要做的是,每次触发keyPressed时,您需要设置一个标志,指示按下了哪个键。触发keyReleased时,您需要重置标记。

然后你需要一个方法来处理这些标志并决定基于这些标志的状态做什么......

最后避免KeyListener,焦点问题只是一个难以处理的问题。相反,我建议您使用Key Bindings代替

例如......

答案 1 :(得分:1)

你应该把钥匙包起来。

创建keys[],如果按下某个键,则keys[]不会激活移动等事件:

void keyPressed(){
     if(key==KeyEvent.VK_something)keys[something]=true;
}
void keyReleased(){
     if(key==KeyEvent.VK_something)keys[something]=false;
}

并在循环内部,当您更新游戏逻辑时,请检查关键事件:

if(keys[up] == true)moveUp();
if(keys[right] == true)rotateRight();

这样,旋转和移动都会同时处于活动状态,而不会相互抵消。