How should I move rectangles using keyPressed?

edited May 2017 in Questions about Code

I've tried a few methods, including this one:

int[] rectpos;
void setup() {
  fullScreen();
  rectpos= new int[] {width/2, height/2};
}

void draw() {
  rectMode(CENTER);
  background(0);
  fill(255);
  rect(rectpos[0], rectpos[1], 100, 20);
  if (keyPressed) {
    switch(keyCode) {
    case LEFT:
      rectpos[0] -=10;
      break;
    case RIGHT:
      rectpos[0] +=10;
      break;
    }
  }
}

But they all have at least one of these problems:

  1. They are dependent on the speed at which the operating system handles keystrokes

  2. They stop suddenly if you press the buttons too quickly (no variable is assigned to key or keyCode) or, in the case of the code I've placed here, they continue in the previous direction when you try to switch (the key or keyCode variable hasn't changed)

Is there any way to use the keyboard that gets around these issues? I have a feeling I'll have to stop using switch(), but other than that I don't quite know what to do...

Tagged:

Answers

  • edited May 2017

    try doing something like:

    void keyPressed() {
      switch(key) {
        case(UP)://do this for all arrow keys
        yourY --;
      }
    }
    

    doing it in draw looks for every frame a key is pressed

    in keyPressed, it only happens when you push down a key

    so what you got is you pressed a key (eg. 43 frames) and your rect moves all of them

    that is because it is in draw, wich just goes on all the time (the variable keyPressed is simply if there is a key being held or not)

  • edited May 2017

    While this does work, it also makes the rectangle move in in accordance to the rate at which the operating system triggers new keys, which makes the rectangle stutter slightly as it moves. I don't know, there may be a way to configure this in the operating system, but I'd really like to be able to make it work without fiddling with things outside of the code, since I want to send this code to other people, without them being forced to change settings on their computer...

  • edited May 2017 Answer ✓

    @Eiroth --

    Your problem is that you are expecting discrete key event signals to drive your sketch. That's the wrong way of thinking about keyboard input, because keyboard hardware isn't set up to do that -- it doesn't have anything like the repeat signal rate that could keep up with your sketch rate, and is both OS specific (as you noted) and hardware-specific.

    Instead, you sketch should be operating based on the last known input state, like this:

    int[] rectpos;
    boolean left, right;
    
    void setup() {
      fullScreen();
      rectpos= new int[] {width/2, height/2};
    }
    
    void draw() {
      rectMode(CENTER);
      background(0);
      fill(255);
      rect(rectpos[0], rectpos[1], 100, 20);
      if(left)  rectpos[0] -=10;
      if(right) rectpos[0] +=10;
    }
    

    ...and now, we change that last known state with the keyboard.

    void keyPressed(){
      if(keyCode==LEFT)  left=true;
      if(keyCode==RIGHT) right=true;
    }
    void keyReleased(){
      if(keyCode==LEFT)  left=false;
      if(keyCode==RIGHT) right=false;
    }
    

    ...or add multiple input modes, any or all of which can work simultaneously:

    void mousePressed() {
      if (mouseX<=width/2) { 
        left=true; 
        right=false;
      } else {
        left=false; 
        right=true;
      }
    }
    
  • @jeremydouglass

    Thanks! I'll definitely try this!

Sign In or Register to comment.