3
\$\begingroup\$

I am trying to allow players of my game to remap the controls (eventually from the menu). Currently, some of the buttons have been defined, but they can't be changed. They are hard-coded. For example, this is how I handle key events now:

    switch(e.getKeyCode())
    {
        case KeyEvent.VK_A:
            ...
            break;
        case KeyEvent.VK_D:
            ...
            break;
        ...et cetera...
    }
}

How can I build a system that allows the actual keys for various actions to be remapped by the user?

\$\endgroup\$
0
6
\$\begingroup\$

In your keyPressed and keyReleased you can use a Map<Integer, GameInput> to map the KeyEvent.VK_* to GameInput

Make a new enum with the actions you want to be controllable

enum GameInput{
    FORWARD, LEFT, RIGHT, BACK,PAUZE,...
}

And in Controller you have a Map<Integer, GameInput> that you use:

public void keyPressed(KeyEvent e)
{
    game.setKeyDown(keyMap.get(e.getKeyCode()));
}


public void keyReleased(KeyEvent e)
{
    game.setKeyUp(keyMap.get(e.getKeyCode()));
}

Then reassigning the keys is a simple matter of refilling the keyMap.

\$\endgroup\$
2
  • \$\begingroup\$ I fail to see how it will work, does the get method on keyMap return the enum so setKeyUp/Down interprets it? If so where are the keys mapped? \$\endgroup\$ – MVCDS Apr 8 '15 at 14:47
  • 1
    \$\begingroup\$ @MVCDS keyMap is a Map<Integer, GameInput> where the integers are KeyEvent values and it's filled by loading the config file or the user setting it in the menu. \$\endgroup\$ – ratchet freak Apr 8 '15 at 14:50
4
\$\begingroup\$

A summary

Instead of mapping the input direcly to the action (and using enums will keep doing that because you would still have to map the key to the enums), you should make the input consume a method it holds. If it was an X-Box, for example, the X button can perfom an action defined by the player

The command pattern as it is

Use the inferface above to create something like bellow from Game Design Patterns, about Command, and read this book by the way ;)

The Answer

I don't know java, but it seems to me that the Command pattern would help you. It is a behavirol pattern by the Gang of Four wich encapsulates your information to be executed, in your case this information is user input.

I'm copying/pasting wikipedia here

import java.util.List;
import java.util.ArrayList;

/* The Command interface */
public interface Command {
   void execute();
}

/* The Invoker class */
public class Switch {
   private List<Command> history = new ArrayList<Command>();

   public void storeAndExecute(Command cmd) {
      this.history.add(cmd); // optional 
      cmd.execute();
   }
}

/* The Receiver class */
public class Light {

   public void turnOn() {
      System.out.println("The light is on");
   }

   public void turnOff() {
      System.out.println("The light is off");
   }
}

/* The Command for turning on the light - ConcreteCommand #1 */
public class FlipUpCommand implements Command {
   private Light theLight;

   public FlipUpCommand(Light light) {
      this.theLight = light;
   }

   public void execute(){
      theLight.turnOn();
   }
}

/* The Command for turning off the light - ConcreteCommand #2 */
public class FlipDownCommand implements Command {
   private Light theLight;

   public FlipDownCommand(Light light) {
      this.theLight = light;
   }

   public void execute() {
      theLight.turnOff();
   }
}

/* The test class or client */
public class PressSwitch {
   public static void main(String[] args){
      Light lamp = new Light();
      Command switchUp = new FlipUpCommand(lamp);
      Command switchDown = new FlipDownCommand(lamp);

      Switch mySwitch = new Switch();

      switch(args[0]) {
         case "ON":
            mySwitch.storeAndExecute(switchUp);
         break;
         case "OFF":
            mySwitch.storeAndExecute(switchDown);
         break;
         default:
            System.out.println("Argument \"ON\" or \"OFF\" is required.");
       }
   }
}

Observation on Java

I was told that Java threats enums as classes so you could, in that language, keep using enums and combine it with the command pattern by passing references to the enum, I think ;)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.