2017-10-08 30 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]的範圍內,從而在爲該範圍內的值創建包裝時帶來更好的性能。