Reputation: 1
For my project in school we have to make a game.
I'm trying to make an object move with the arrow keys but nothing happens if I run it and press one of the keys.
Have I maybe implemented the addKeyListener(this);
in the wrong spot?
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();
}
}
Upvotes: 0
Views: 2055
Reputation: 37845
This is probably because KeyListener
only receives a KeyEvent
if the component is focused. There are some suggestions here which might solve the problem for you; however I don't recommend them because they're kludgy. Another kludgy solution that I don't see over there is to add the key listener to the JFrame
and then using setFocusable(false)
and setFocusTraversalKeysEnabled(false)
on any components which might steal the focus away. Key listeners are especially tricky if you're adding other components, like JButton
and JTextField
to your UI.
A better solution is to use Swing key bindings which don't have problems handling the focus system. Here's a Q&A which explains some of the motivation for them, and there's a tutorial here. You can use the WHEN_IN_FOCUSED_WINDOW
flag to guarantee that the key bindings always fire regardless of which component has the focus.
Upvotes: 1