【问题标题】:Moving an object in Java (KeyPressed)在 Java 中移动对象(KeyPressed)
【发布时间】:2017-09-11 16:35:59
【问题描述】:

对于我在学校的项目,我们必须制作一个游戏。

我正在尝试使用箭头键移动对象,但如果我运行它并按下其中一个键,则没有任何反应。

我是否可能在错误的位置实现了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();
    }
}

【问题讨论】:

  • 我怀疑您是否需要在每次循环迭代中添加关键侦听器,这太多了(或者如果内部代码正常,它会忽略您的请求并且无论如何只有一个侦听器)。

标签: java keypress keylistener


【解决方案1】:

这可能是因为KeyListener 仅在组件获得焦点时才会收到KeyEvent。有一些建议here可能会为您解决问题;但是我不推荐它们,因为它们很笨拙。我在那里看不到的另一个笨拙的解决方案是将关键侦听器添加到JFrame,然后在任何可能转移焦点的组件上使用setFocusable(false)setFocusTraversalKeysEnabled(false)。如果您要向 UI 添加其他组件(例如 JButtonJTextField),则关键侦听器会特别棘手。

更好的解决方案是使用在处理焦点系统时没有问题的 Swing 键绑定。 Here's 一个问答环节,解释了他们的一些动机,还有一个 tutorial here。您可以使用WHEN_IN_FOCUSED_WINDOW 标志来保证键绑定始终触发,无论哪个组件具有焦点。

【讨论】:

  • 非常感谢您的回答,但是当我在胡闹试图弄清楚如何解决问题时,我看到了一个叫做 this.requestFocusable(); 的东西。 .这对我有用。但仍然非常感谢您花时间帮助我。
  • 是的,这是我不推荐的解决方案之一。例如,如果您在框架中添加了一个 JButton 并且有人单击它,则 JPanel 将失去焦点并停止再次发送关键事件。
猜你喜欢
  • 2013-02-18
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多