2016-07-29 23 views
1

Ich mache ein klassisches "move Bild auf dem Bildschirm" Programm. Statt eines Keylisteners versuche ich Tastaturbefehle zu bekommen, aber bisher ohne Erfolg.Wo und wie man Inputmaps und Actionmaps instanziiert

Meine Objekte sind in einer LinkedList

public LinkedList<GameObject> object = new LinkedList<GameObject>(); 

und

public void addObject(GameObject object){ 
    this.object.add(object); 
} 

Meine KeyBinding Klasse über zu dieser Liste hinzugefügt ist als

public class KeyBindings extends JPanel{ 

private static final String accelerate = "accelerate"; 

public KeyBindings(){ 
    System.out.println("test"); 
    registerKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP-press", new ShuttleMove(accelerate)); 
} 

public void registerKeyBinding(KeyStroke keyStroke, String name, Action action) { 
    InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
    ActionMap am = getActionMap(); 

    im.put(keyStroke, name); 
    am.put(name, action); 
} 

class ShuttleMove extends AbstractAction { 

    public ShuttleMove(String movement) { 

      if (movement.equals("accelerate")){ 
       //this.setVelocityForward(this.getVelocityForward() + 0.1); 
       System.out.println("accelerate"); 
      } 
    } 
    public void actionPerformed(ActionEvent e) { 
    } 
} 

}

folgt

Mein Spieler Klasse s, die die Gameobject Klasse aussehen (leicht kondensiert) als erstreckt:

public class Player extends GameObject { 

Handler handler; 

public Player(int x, int y, ID id, int width, int height, int rotation,double totalRotation, Handler handler, double velocityForward, double velocityRotate){ 
    super(x, y, id, width, height, rotation, totalRotation); 
    this.handler = handler; 

} 

public void tick(){ 
    x += this.getVelocityForward(); 
    y += this.getVelocityForward(); 
} 
public void render(Graphics2D g2d){ 

    try { 
     player = ImageIO.read(new File("src/Game/images/shuttle3.png")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    AffineTransform old = g2d.getTransform(); 
    AffineTransform at = AffineTransform.getTranslateInstance(x,y);  

    g2d.drawImage(player, at,null); 
    g2d.setTransform(old); 
} 
} 

obwohl ich bin mir nicht sicher, wie man „aktivieren“, um die Tastenkombination. Sollte es in der Hauptschleife sein? Sollte es in der player.tick -Methode sein, die aufgerufen wird, um das Spielerbild zu aktualisieren und es anschließend zu zeichnen?

Wie sind die inputmap und die actionmap mit dem player-Objekt verknüpft? Ich habe versucht, so etwas wie dies zu tun, was nicht funktioniert hat:

public void registerKeyBinding(KeyStroke keyStroke, String name, Action action) { 
    for (int i = 0; i < handler.object.size(); i++){ 
     GameObject player = handler.object.get(i); 
     //find player 
     if (player.getID() == ID.Player){ 
      InputMap im = player.getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      ActionMap am = player.getActionMap(); 

      im.put(keyStroke, name); 
      am.put(name, action); 
     } 
    } 
} 

ich einige denken, wie meine Spieler zu einem JComponent geworfen werden sollen, aber ich bin nicht sicher, wie dies geschehen ist (wie Eclipse-mir sagt, es ist nicht kompatibel mit meine GameObject-Klasse). Kann mich jemand in die richtige Richtung führen? Lassen Sie es mich wissen, wenn ich versehentlich einige wichtige Informationen ausgelassen habe (was ich ganz sicher getan habe)

Antwort

0

Sie müssen die Tastenkombination nicht aktivieren, sie ist bereits aktiviert, sobald Sie die ActionMap auffüllen. Was Sie do tun müssen, ist die actionPerfomed-Methode des Objekts Action zu implementieren. Das Objekt Action ist im Wesentlichen eine Aktion Handler. Es sollte nichts tun, sobald es erstellt wurde, es sollte nur Dinge tun, sobald die Aktion tatsächlich ausgeführt wird.

+0

Auch, als Follow-up, denke ich, dass Sie hier die Bedeutung von _register_ falsch interpretieren. Das "Registrieren" eines Schlüssel-Handlers bedeutet das Hinzufügen der Funktionalität des Abhörens für den Tastendruck, ** nicht ** das Registrieren des Klicks selbst. Daher sollten Sie Ihre Schlüsselfunktionalität in die actionPerformed-Methode verschieben und keine Logik in der Funktionalität ausführen, die den Handler registriert - als was es im Wesentlichen nur sagt "Starten Sie den entsprechenden Tastendruck zu hören". –

+0

Das haben Sie bereits getan, indem Sie getActionMap für das Player-Objekt aufgerufen haben. Wenn das Ereignis ausgelöst wird, sollte das ActionEvent den Player als Quelle enthalten - Sie müssen es nur in Player umwandeln. –

+0

Entschuldigung für das Löschen meines Kommentars. War Bearbeitung. Ich wollte etwas versuchen, wie Klasse ShuttleMove erweitert Abstract { \t \t öffentlichen ShuttleMove (Object-Spieler) { \t \t \t this.player = Spieler; \t \t} \t \t public void actionPerformed (Action e) { \t \t \t this.setVelocityForward (this.getVelocityForward() + 0.1); \t \t} \t} Ich kann etwas konzeptionell obwohl vermissen, da ich unsicher bin, wie man es auf den Spieler wirft. Wie auch immer, ich werde es so schnell wie möglich nachlesen. Danke für die Antwort. – user2913053