如何使用多个方向键一次移动矩形?

时间:2017-10-08 15:44:55

标签: java

嗨,这可能是非常愚蠢的,但请尝试理解我是Java编程的绝对初学者。我一直在尝试从互联网上学习它。

我试图创建一个可以使用KeyListener移动方块的简单Applet。

首先,我制作了一个只能一次检测到一个密钥的版本。所以我在YouTube上查了一个教程(https://www.youtube.com/watch?v=5UaEUrbpDPE)。它使用ArrayList以某种方式处理所谓的“Ghosting”问题。该教程显示了完美的结果,但我的代码导致了一些奇怪的问题:

最初,广场在任何方向上都能顺利移动一段时间。广场主要可以向下和向右移动。按下或离开几次后,方块就不能再移动了!

任何人都可以指导我做错了什么或者如何做到这一点?

以下是我开始使用的代码(一次检测到一个按钮):

package boxHero;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class boxGame extends Applet implements KeyListener {

private Rectangle rect;                          
private int x = 20, y = 20, recW = 50, recH = 50;


public void init() {
    setSize(600, 500);                           
    setBackground(Color.BLACK);

    this.addKeyListener(this);

    rect = new Rectangle (x, y, recW, recH);     
}

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setColor(Color.YELLOW);
    g2.fill(rect);
}

@Override
public void keyPressed(KeyEvent e) {
    // Can't detect more than one key at a time
    if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
        rect.setLocation(rect.x + 10, rect.y);
    }
    else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
        rect.setLocation(rect.x - 10, rect.y);
    }
    else if(e.getKeyCode() == KeyEvent.VK_UP) {
        rect.setLocation(rect.x, rect.y - 10);
    }
    else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
        rect.setLocation(rect.x, rect.y + 10);
    }


    repaint();
}

@Override
public void keyReleased(KeyEvent e) {


}

@Override
public void keyTyped(KeyEvent e) {


}


}

以下是YouTube教程中的代码:

package boxHero;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

public class boxGame2 extends Applet implements KeyListener {

private Rectangle rect;                          // Declaring a rectangle object

private ArrayList<Integer> keysDown;

private int x = 20, y = 20, recW = 50, recH = 50;


public void init() {
    setSize(600, 500);                           // Initial screen size
    setBackground(Color.BLACK);                  // Setting background

    this.addKeyListener(this);                   // Adding KeyListener

    keysDown = new ArrayList<Integer>();

    rect = new Rectangle (x, y, recW, recH);     // Instantiating and Initializing(setting values) for our Rectangle
}

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;

    // Graphics for our rectangle
    g2.setColor(Color.YELLOW);
    g2.fill(rect);
}

public void moveRect() {
    int x = rect.x;
    int y = rect.y;

    if(keysDown.contains(KeyEvent.VK_UP)) {
        y -= 10;
    }
    if(keysDown.contains(KeyEvent.VK_DOWN)) {
        y += 10;
    }
    if(keysDown.contains(KeyEvent.VK_LEFT)) {
        x -= 10;
    }
    if(keysDown.contains(KeyEvent.VK_RIGHT)) {
        x += 10;
    }

    rect.setLocation(x, y);

    repaint();
}

@Override
public void keyPressed(KeyEvent e) {

    if(!keysDown.contains(e.getKeyCode()) && e.getKeyCode() != 86) {
        keysDown.add(new Integer(e.getKeyCode()));
    }

    moveRect();


}

@Override
public void keyReleased(KeyEvent e) {
    keysDown.remove(e);

}


@Override
public void keyTyped(KeyEvent e) {


}


}

2 个答案:

答案 0 :(得分:0)

您的代码和教程之间的区别在于,教程使用当前按下的键列表,而您只检查,按下了WHICH键。 像教程中一样创建一个关键字的ArrayList,然后在按下时添加每个键并在释放后立即将其删除。然后,您可以为列表中包含的每个键移动矩形。

答案 1 :(得分:0)

keyPressed()事件中,您将e.getKeyCode()添加到keysDown列表中。但是在keyReleased()事件中,您只会尝试从列表中删除e,这样就不会导致任何内容被删除,并且所有按键都会被按下。因此,在几次按下之后它没有移动的原因是你基本上按下左,右,上和下,导致它们相互抵消。

此外,您应养成使用Integer.valueOf(x)而不是new Integer(x)的习惯,因为它会缓存[-128; 127]范围内的值,从而在为值创建包装器时获得更好的性能在那个范围内。