嗨,这可能是非常愚蠢的,但请尝试理解我是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) {
}
}
答案 0 :(得分:0)
您的代码和教程之间的区别在于,教程使用当前按下的键列表,而您只检查,按下了WHICH键。 像教程中一样创建一个关键字的ArrayList,然后在按下时添加每个键并在释放后立即将其删除。然后,您可以为列表中包含的每个键移动矩形。
答案 1 :(得分:0)
在keyPressed()
事件中,您将e.getKeyCode()
添加到keysDown
列表中。但是在keyReleased()
事件中,您只会尝试从列表中删除e
,这样就不会导致任何内容被删除,并且所有按键都会被按下。因此,在几次按下之后它没有移动的原因是你基本上按下左,右,上和下,导致它们相互抵消。
此外,您应养成使用Integer.valueOf(x)
而不是new Integer(x)
的习惯,因为它会缓存[-128; 127]范围内的值,从而在为值创建包装器时获得更好的性能在那个范围内。