2017-10-08 78 views
0

嗨,这可能是非常愚蠢的,但请尝试了解我是Java编程的绝对初学者。我一直试图通过互联网自己学习。如何使矩形一次移动多个方向键?

我试图做一个简单的小程序,可以使用KeyListener移动一个正方形。

首先我做了一次只能检测一个键的版本。于是我查找了YouTube上的教程(https://www.youtube.com/watch?v=5UaEUrbpDPE)。它使用ArrayList以某种方式处理被称为“重影”的问题。该教程显示了完美的结果,但我的代码导致了一些奇怪的问题:

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

任何人都可以请指导我我做错了什么或者如何可以完成?

这里是我开始(在一时间检测的一个按钮),代码:

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

欢迎来到Stack Overflow!你已经在你的问题中发布了很多代码,这使得我们(以及未来的读者)不清楚问题出在哪里。请将您的问题代码减少到10行或更少。请参阅:[如何创建最小,完整和可验证示例](http://stackoverflow.com/help/mcve)和[如何调试小程序](https://ericlippert.com/2014/03/05 /如何调试的小程序/)。 –

+2

您可能会考虑切换为使用[JavaFX](https://docs.oracle.com/javase/8/javafx/api/toc.htm),这是'java.awt'上的后续操作。通过使用['Rectangle'](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/Rectangle.html)类和['KeyEvent'](https:// docs .oracle.com/javase/8/javafx/api/javafx/scene/input/KeyEvent.html),您可以创建简化问题的解决方案。还要考虑* applets *已经过时。 –

回答

0

你的代码和之间的性差异教程是,该教程使用当前按下的键列表,而您只检出,按下哪个键。 制作一个像教程中的按键的ArrayList,然后在按下时添加每个按键,并在释放后立即将其删除。然后,您可以移动列表中包含的每个键的矩形。

0

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

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