Using WASD and arrow keys simultaneously

Brannon picture Brannon · Feb 12, 2013 · Viewed 12.9k times · Source

I am developing a two player game in Processing (running on Java). One user will control his character using the WASD keys and the other will control movement using the arrow keys. The problem I am having is that using keyPressed negates WASD when arrows are pressed and vice versa. I have been messing around with it for a really long time. Does anyone know a work around or notice something that I am doing wrong?

//global variables
int wide = 600; //canvas width
int tall = 600; //canvas height
int s = 50; //player size
float speed = 2.5; //player movement speed

//colors
int redColor = #CB4646; //player 1 color
int blueColor = #4652CB; //player 2 color
int backgroundColor = #DBE3B3; //background color
float player1X = 600/3-s;  //HOW COME width/3 DOESN'T WORK??????????
float player2X = 600*2/3;
float playerY = 600/2-(s/2);

//players
Player player1 = new Player(player1X, playerY, s, speed, "wasd", redColor); //player 1
Player player2 = new Player(player2X, playerY, s, speed, "arrows", blueColor); //player 2

//setup
void setup(){
  background(backgroundColor);
  size(wide, tall);
  smooth();
  println(player2.controls);
}

//draw
void draw(){
  background(backgroundColor);
  player1.usePlayer();
  player2.usePlayer();
}

class Player{

   //class variables
   float x; // x position
   float y; // y position
   int s; //size
   float speed; //speed
   String controls; //controls
   int colors; //player color
   char keyControls [] = new char [4];

   //construct
   Player(float tempX, float tempY, int tempS , float tempSpeed, String tempControls, int tempColors){
     x = tempX; 
     y = tempY; 
     s = tempS; 
     speed = tempSpeed; 
     controls = tempControls; 
     colors = tempColors; 
   }

   void usePlayer(){

     // draw player
     fill(colors);
     rect(x, y, s, s);

     //move player
     keyPressed();

     //wraparound
     boundaries();

   }

   void keyPressed(){

     //sets controls for wasd
     if(controls == "wasd"){ 
          if(key == 'w' || key == 'W'){ 
            y -= speed; //move forwards
          }
          if(key == 's' || key == 'S'){
            y += speed; //move backwards
          }
            if(key == 'd' || key == 'D'){
            x += speed; //move right
          }
          if(key == 'a' || key == 'A'){
            x -= speed; //move left
          }
         }

      //sets controls for arrows 
      if(controls == "arrows"){ 
        if(key == CODED){
          if(keyCode == UP){ 
            y -= speed; //move forwards
          }
          if(keyCode == DOWN){
            y += speed; //move backwards
          }
            if(keyCode == RIGHT){
            x += speed; //move right
          }
          if(keyCode == LEFT){
            x -= speed; //move left
          }
         }  
        }  
       }

    //pacman style wraparound
    void boundaries(){
     if(x == width) x = 2;
     if(y == height) y = 2;
     if(x == 0) x = width-s;
     if(y == 0) y = height-s;
    }
}

Answer

Mike 'Pomax' Kamermans picture Mike 'Pomax' Kamermans · Feb 12, 2013

Track your keys independently, don't rely on the event globals.

boolean[] keys = new int[255];

void keyPressed() {
  keys[keyCode] = true;
}

void keyReleased() {
  keys[keyCode] = false;
}

void draw() {
  updatePlayers();
  drawStuff();
}

void updatePlayers() {
  if(keys[LEFT]) { p1.move(-1,0); }
  if(keys[RIGHT]) { p1.move(1,0); }
  if(keys[UP]) { p1.move(0,-1); }
  if(keys[DOWN]) { p1.move(0,1); }

  if(keys['a']) { p2.move(-1,0); }
  if(keys['d']) { p2.move(1,0); }
  if(keys['w']) { p2.move(0,-1); }
  if(keys['s']) { p2.move(0,1); }
}

Note this has to be a series of if statements, because you want to handle all pressed keys. If someone's holding left and right, p1 will move left, and right.

Also note that this example code doesn't filter for the higher-than-255 codes you get for special keys, so you probably want to put an "if(keyCode>255) return" at the start of the event handlers.