Je fais un jeu en utilisant les tutoriels de RealTutsGML, donc si vous avez vu certaines de ses vieilles vidéos de 2013, vous verrez d'où vient le contour de ce code. (En passant, je ne suis pas nouveau à Java, mais je suis assez nouveau pour AWT et Swing et tout ça parce que je faisais/je fais toujours du code pour les plugins Minecraft Bukkit/Spigot. de la langue/syntaxe régulière Java, mais AWT et Swing ...)KeyListener arrête de fonctionner au hasard. Raccourcis clavier?
Quoi qu'il en soit, j'utilise un KeyAdapter pour contrôler les clés. Cependant, cela fonctionne au début, puis s'arrête de fonctionner au hasard. Je l'ai débogué et il semble que ce n'est pas l'objet dans le jeu, c'est le KeyAdapter. J'ai recherché d'autres solutions à cela et les gens ont dit qu'il perd le focus ou quelque chose et que je devrais utiliser KeyBindings à la place. C'est bizarre parce que le KeyListener cesse de fonctionner pour moi.
Quoi qu'il en soit, voici le code que je utilise:
Handler handler;
public KeyInput(Handler handler){
this.handler = handler;
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player){
if (key == KeyEvent.VK_SPACE && !tempObject.isJumping()){
tempObject.setJumping(true);
tempObject.setVelY(-10);
}
if (key == KeyEvent.VK_Y){
tempObject.setY(100);
}
if (key == KeyEvent.VK_A){
System.out.println("Pressed A");
tempObject.setVelX(-5);
}
if (key == KeyEvent.VK_D){
System.out.println("Pressed D");
tempObject.setVelX(5);
}
}
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player) {
if (key == KeyEvent.VK_D) {
for (int velX = (int) tempObject.getVelX(); velX >= 0; velX--) {
tempObject.setVelX(velX);
}
}
if (key == KeyEvent.VK_A) {
for (int velX = (int) tempObject.getVelX(); velX <= 0; velX++) {
tempObject.setVelX(velX);
}
}
}
}
}
Comme vous pouvez le voir, je me sers d'un KeyAdapter pour le faire. Voici ma méthode d'initialisation dans la classe principale:
private void init(){
WIDTH = getWidth();
HEIGHT = getHeight();
handler = new Handler();
handler.addObject(new Player(100, 100, handler, ObjectId.Player));
handler.createTestLevel();
this.addKeyListener(new KeyInput(handler));
}
La méthode init est appelée avant « this.requestFocusInWindow() »
Je levais les yeux quelques informations sur ce sujet et je vis KeyBindings comme des solutions à d'autres les problèmes des gens. Cependant, je pense que vous devez ajouter des raccourcis clavier à JComponents, et je ne sais pas comment en obtenir un dans le jeu. new JComponent() ne fonctionne pas, et mon JFrame ajoute ma classe principale (qui est je crois agir comme un composant, pas JComponent).
Si quelqu'un peut aider, ce serait génial! Merci!
EDIT # 1:
je suis passé à KeyBindings! Voici la classe KeyInput:
Handler handler;
public JComponent component;
public KeyInput(Handler handler, JComponent component){
this.handler = handler;
this.component = component;
register();
}
public void register(){
Actions actions = new Actions();
component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressSpace");
component.getActionMap().put("pressSpace", actions.pressSpace());
component.getInputMap().put(KeyStroke.getKeyStroke("A"), "pressLeft");
component.getActionMap().put("pressLeft", actions.pressLeft());
component.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft");
component.getActionMap().put("releaseLeft", actions.releaseXMovement());
component.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight");
component.getActionMap().put("pressRight", actions.pressRight());
component.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight");
component.getActionMap().put("releaseRight", actions.releaseXMovement());
}
public JComponent finish(){
return component;
}
public class Actions{
public Actions() { }
public Action pressRight(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(5);
System.out.println("pressed right debug");
}
}
}
};
return action;
}
public Action releaseXMovement(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(0);
}
}
}
};
return action;
}
public Action pressLeft(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(-5);
}
}
}
};
return action;
}
public Action pressSpace(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
if (!temp.isJumping()){
temp.setJumping(true);
temp.setVelY(-10);
}
}
}
}
};
return action;
}
}
Cependant, j'ai toujours le même problème de congélation. Les messages de débogage ne sont pas envoyés, ce qui signifie que cela n'a rien à voir avec mes méthodes setVel. Je ne sais pas pourquoi la chose de l'auditeur cesse de fonctionner ... (Ca marche au début, mais comme je continue d'appuyer sur les touches, ça finit par s'arrêter).
Voilà comment je suis arrivé le JComponent:
JComponent comp = (JComponent) frame.getContentPane();
KeyInput input = new KeyInput(handler, comp);
frame.add(input.finish());
Si vous avez besoin d'une aide plus spécifique, alors, selon ma réponse, vous voudrez créer et publier un [mcve] valide en tant que modification de votre question actuelle. Comme toujours, le code doit être publié sous forme de texte au format code et non dans un lien. –
Voir Modifier pour répondre à la partie inférieure de votre question. Encore une fois, un MCVE aiderait énormément. –
@HovercraftFullOfEels que voulez-vous dire pas dans un lien? Je n'ai aucun lien dans mon message. – Blockhead7360