2017-04-15 55 views
0

對於我在學校的項目,我們必須製作一個遊戲。在Java中移動對象(KeyPressed)

我想使對象移動箭頭鍵但沒有任何反應,如果我運行它並按下其中一個鍵。

我可能在錯誤的地方實施了addKeyListener(this);嗎?

package VoorbeeldSpel; 

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.event.*; 


import javax.swing.*; 

public class PlayPanel extends JPanel implements ActionListener, KeyListener { 

    private static final long serialVersionUID = 584263623777101573 L; 
    final static String IMAGE_FOLDER = "images/"; 
    final static String FILE_FOLDER = "files/"; 

    private Timer spelTimer = new Timer(50, this); // elke 1000 milliseconden zal een event gelanceerd worden 

    private JButton menuKnop; 
    private MijnProject mainVenster; 


    MusicPlayer music; 
    private Image ninjaImage; 
    private Image BackgroundImage; 

    public int pos_x, pos_y; 
    public int v_x, v_y; 

    private String inputText = ""; 

    public PlayPanel(MijnProject mainVenster) { 
     this.mainVenster = mainVenster; 

     menuKnop = new JButton("Menu"); 
     menuKnop.addActionListener(this); 

     this.add(new JLabel("We are playing ... ")); 
     this.add(menuKnop); 


     addKeyListener(this); 

     // Music player laden 
     music = new MusicPlayer("nyancat-loop.wav", true); 


     // Prentjes laden 
     ninjaImage = new ImageIcon(getClass().getResource(IMAGE_FOLDER + "ninja.png")).getImage(); 
     BackgroundImage = new ImageIcon(getClass().getResource(IMAGE_FOLDER + "Backgroundmenu.jpg")).getImage(); 

     spelTimer.start(); // hier starten we de gameloop 
    } 

    // we gaan init aanroepen nadat we dit JPanel aan het frame hebben toegevoegd 
    // op dit moment zijn de hoogte en breedte van het panel bepaald en kunnen we de pos_x en pos_y variabelen initialiseren als het midden van het scherm 
    public void init() { 
     addKeyListener(this); 
     v_x = ; 
     v_y = 0; 
     pos_x = getWidth()/2; 
     pos_y = getHeight()/2; 
     addKeyListener(this); 
    } 
    public void gameloop() { 

     pos_x += v_x; 
     pos_y += v_y; 
     repaint(); 

    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     g.drawImage(BackgroundImage, this.getWidth()/50, this.getHeight()/50, mainVenster.getWidth(), mainVenster.getHeight(), this); 
     g.drawImage(ninjaImage, pos_x, pos_y, 60, 60, this); 

     g.drawChars(inputText.toCharArray(), 0, inputText.length(), 25, getHeight()/2); 
    } 

    public void actionPerformed(ActionEvent ae) { 
     if (ae.getSource() == menuKnop) { 
      mainVenster.switchPanel(); 
      music.stop(); 
      spelTimer.stop(); // stoppen van het spel 

     } else if (ae.getSource() == spelTimer) { 

      gameloop(); 
      addKeyListener(this); 
      System.out.println("De volgende stap van het spel wordt uitgevoerd..."); 
     } 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    public void keyPressed(KeyEvent e) { 
     switch (e.getKeyCode()) { 
      case KeyEvent.VK_UP: 
       v_x = 0; 
       v_y = -5; 
      case KeyEvent.VK_DOWN: 
       v_x = 0; 
       v_y = 5; 
      case KeyEvent.VK_RIGHT: 
       v_x = 5; 
       v_y = 0; 
      case KeyEvent.VK_LEFT: 
       v_x = -5; 
       v_y = 0; 
     } 

     repaint(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     int Keycode = e.getKeyCode(); 
     switch (Keycode) { 
      case KeyEvent.VK_UP: 
       v_x = 0; 
       v_y = 0; 
      case KeyEvent.VK_DOWN: 
       v_x = 0; 
       v_y = 0; 
      case KeyEvent.VK_RIGHT: 
       v_x = 0; 
       v_y = 0; 
      case KeyEvent.VK_LEFT: 
       v_x = 0; 
       v_y = 0; 
     } 
     repaint(); 
    } 
} 
+0

我懷疑你需要在每個循環迭代中添加關鍵的偵聽器,這是太多的偵聽器(或者如果內部代碼是理智的,它會忽略你的請求,並且只有一個偵聽器)。 –

回答

1

這可能是因爲,如果組件集中KeyListener只接收一個KeyEvent。有一些建議here可能會爲您解決問題;不過我不推薦他們,因爲他們很笨拙。我沒有看到的另一個Kludgy解決方案是將關鍵聽衆添加到JFrame,然後在可能竊取焦點的任何組件上使用setFocusable(false)setFocusTraversalKeysEnabled(false)。如果您要將其他組件(如JButtonJTextField)添加到您的用戶界面,則關鍵聽衆尤其棘手。

更好的解決方案是使用Swing鍵綁定,它在處理焦點系統時沒有問題。 Here's a Q & A解釋了他們的一些動機,並且有一個tutorial here。您可以使用WHEN_IN_FOCUSED_WINDOW標誌來確保無論哪個組件具有焦點,密鑰綁定始終會啓動。

+0

非常感謝你的回答,但是當我在想弄明白如何解決問題時,我看到了一些名爲this.requestFocusable()的東西; 。這爲我做了詭計。但是,非常感謝你幫助我的時間。 –

+0

是的,這是我不推薦的解決方案之一。例如,如果您向框架添加了JButton並且有人點擊了它,則JPanel將失去焦點並停止再次發送關鍵事件。 – Radiodef