Input

tutorial processing basic

Now we know how to use variables, functions, and if statements. We know how to modify variables over time to create animations.

We know that Processing gives us predefined variables like width and height.

We also know that Processing automatically calls the setup() function once at the very beginning of the program, and then calls the draw() function 60 times per second.

So far our programs have mostly done stuff on their own, without responding to anything that the user does. This tutorial shows you how to get user input to make your programs more interactive.

When I say user input, I mean things like mouse position, mouse clicks, and key typing.

The mouseX and mouseY Variables

We’ve already seen one of the easiest ways to get user input: the mouseX and mouseY variables. Processing automatically updates these variables to hold the current location of the mouse cursor in the window. You can use these in the draw() function to get the position of the mouse.

void draw(){
  background(200);
  ellipse(mouseX, mouseY, 25, 25);
}

This program draws a circle wherever the mouse cursor is.

circle at mouse

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

But you don’t have to draw things right on top of the cursor. Instead, you can get creative and use the mouseX and mouseY variables in calculations to do more interesting things.

For example, here’s the same program, but with mouseX and mouseY reversed:

void draw(){
  background(200);
  ellipse(mouseY, mouseX, 25, 25);
}

Now the circle mirrors the cursor instead of following it, which ends up feeling pretty weird.

circle mirroring mouse

Here’s a slightly more complicated example:

float circleX = 50;
float circleY = 50;

void draw(){
  background(200);
  
  circleX = (circleX*9 + mouseX)/10;
  circleY = (circleY*9 + mouseY)/10;
  
  ellipse(circleX, circleY, 25, 25);
}

This program uses a weighted average to move the circle towards the cursor. That might sound complicated, but really all it’s doing is giving more weight to the old position, so the circle moves slower instead of staying right on top of the cursor.

circle following mouse

The point is, don’t be afraid to use the mouseX and mouseY variables to do interesting things, other than drawing stuff wherever the mouse is.

The mousePressed Variable

The mouseX and mouseY variables point to int values that hold the current value of the mouse.

Similarly, the mousePressed variable points to a boolean value that is true when the mouse is pressed, and false when it’s not. We can use the mousePressed function in an if statement to do stuff when the mouse is held down:

void draw() {
  if (mousePressed) {
    background(0, 255, 0);
  } 
  else {
    background(200);
  }
}

This program uses an if statement to check whether mousePressed is true. If it is, then it draws a green background. If not, then it draws a gray background.

gray background that turns green when mouse is pressed

In other words, the program displays gray unless the mouse is pressed, then it displays green.

We could combine the mousePressed variable with the mouseX and mouseY variables to create a basic drawing program:

void draw() {
  if (mousePressed) {
    ellipse(mouseX, mouseY, 25, 25);
  }
}

This program uses an if statement to check whether mousePressed is true. If it is, then it draws an ellipse at mouseX,mouseY.

basic drawing program

In other words, the program lets you draw with circles whenever the mouse is pressed.

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

The pmouseX and pmouseY Variables

Let’s say we want to improve our basic drawing program. Instead of drawing circles, we want to draw a continuous line whenever the user is pressing the mouse. We might try calling the point() function instead of the ellise() function:

void draw() {
  if (mousePressed) {
    point(mouseX, mouseY);
  }
}

But if you run that, you’ll notice that the points aren’t connected:

disconnected points

This is because the cursor doesn’t pass through every single pixel in its path. If you’re moving the mouse very fast, the cursor might jump over a bunch of pixels. Our eyes don’t notice this because we fill in the gaps in our brain, but the computer only knows the current position of the cursor, not its path.

To fix this problem, we need to keep track of the previous position of the cursor, and then draw a line from that position to the new position. (In other words, we need to connect the dots that we’re drawing.) We could do this ourselves by creating variables and then setting them to mouseX and mouseY at the end of the draw() function, but Processing already does this for us.

The pmouseX and pmouseY variables hold the previous position of the cursor. By itself that might not sound very useful, but they help solve the problem we just saw. Now we can draw our line from the previous position to the new position:

void draw() {
  if (mousePressed) {
    line(pmouseX, pmouseY, mouseX, mouseY);
  }
}

By connecting the dots as we draw them, our program looks like it’s drawing one continuous line.

continuous line

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

Mouse Input Functions

The mousePressed variable is useful when we want to do something continuously, as long as the user has the mouse pressed. But what if we want to detect one-time things like a mouse click?

These one-time things are called events, and Processing provides a bunch of functions that it will automatically call whenever an event happens. By writing code inside these functions, you can run code based on these events.

Inside these event functions, you can use the same variables and functions as you can in the draw() function. For example, we could add a mouseClicked() function to our drawing program to allow the user to draw individual circles whenever they click:

void draw() {
  if (mousePressed) {
    line(pmouseX, pmouseY, mouseX, mouseY);
  }
}

void mouseClicked(){
  ellipse(mouseX, mouseY, 10, 10);
}

Processing calls the draw() function 60 times per second, and in that we draw a continuous line if the mouse is held down. Processing calls the mouseClicked() function once, every time the mouse is clicked, and in that we draw a circle at the current cursor position. In other words, we draw a circle wherever the user clicks, and we draw a line wherever the user drags.

click to make circles

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

There are a bunch of mouse input functions that allow you to react to more specific events:

The keyPressed Variable

Similar to how the mousePressed variable is true whenever the user is pressing a mouse button, the keyPressed variable is true whenever the user is pressing a key on the keyboard.

You can use the keyPressed variable in an if statement to execute code whenever the user is pressing a key:

void draw(){
  if(keyPressed){
    background(0, 255, 0);
  }
  else{
    background(200);
  }
}

This program uses an if statement to check whether the keyPressed variable is true. If so, then it draws a green background, otherwise, it draws a gray background.

green background when key is pressed

In other words, the program shows green whenever the user presses a key.

The key Variable

The keyPressed variable is only useful if you just want to know whether any key is pressed. Most programs will also want to know which key is being pressed. For that, you can use the key variable.

The key variable is a char type. If you haven’t seen the char type yet, it’s similar to the String type, except it only holds a single character.

You can use char values by typing a single character inside single quotation marks '', like this:

char myCharVariable = 'A';

Anyway, the key variable points to a char value that holds the last key pressed.

You can use it directly:

void draw(){
  background(200);
  textSize(72);
  text(key, 25, 75);
}

This program passes the key variable into the text() function to draw the last key typed by the user.

alphabet

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

Or you can use it in an if statement to detect particular key presses:

void draw() {
  if (keyPressed) {
    
    if (key == 'r') {
      background(255, 0, 0);
    } 
    else if (key == 'g') {
      background(0, 255, 0);
    } 
    else if (key == 'b') {
      background(0, 0, 255);
    }
  } 
  else {
    background(200);
  }
}

This program uses an if statement to check whether keyPressed is true. If so, then it uses another if else-if block to check whether they key is r, g, or b. Depending on which key is pressed, it draws a different color background. If keyPressed is false, then we don’t bother checking the key and we just draw a gray background.

key press changing background

Notice that we’re only checking the key variable if we know that keyPressed is true. This is because key always holds the most recent key pressed by the user, even if the user has stopped pressing it.

The keyCode Variable

They key variable is useful if you want to check for letter or number keys. But what if you want to check for the shift or ctrl key, or the arrow keys? They don’t have char representations, so the key variable won’t work with them.

Instead, you can use the keyCode variable. You can check the keyCode variable against predefined variables like UP, DOWN, LEFT, RIGHT, SHIFT, CONTROL, and ALT (There are more, check the reference!) to do stuff when the user presses a specific key.

float circleX = 50;
float circleY = 50;

void draw() {
  
  background(200);
  
  if (keyPressed) {
    if (keyCode == UP) {
      circleY--;
    } 
    else if (keyCode == DOWN) {
      circleY++;
    } 
    else if(keyCode == LEFT){
      circleX--;
    }
    else if(keyCode == RIGHT){
     circleX++; 
    }
  } 
  
  ellipse(circleX, circleY, 20, 20);

}

This program checks whether one of the arrow keys is being pressed, and moves a circle based on that. This allows the user to move the circle around the screen.

arrow keys controlling circle

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

Keyboard Input Functions

The keyPressed, key, and keyCode functions are useful if you want to do something continuously, as long as a user presses a key. But what if you want to respond to one-time keyboard events?

Similar to how Processing automatically calls the mousePressed(), mouseReleased(), and mouseClicked() functions based on mouse events, Processing also automatically calls the keyPressed(), keyReleased(), and keyTyped() functions based on keyboard events.

You can define these functions to run code based on these keyboard events.

float circleX = 50;
float circleY = 50;

void draw() {
  background(200);  
  ellipse(circleX, circleY, 20, 20);
}

void keyReleased() {
  if (keyCode == UP) {
    circleY--;
  }
  else if (keyCode == DOWN) {
    circleY++;
  }
  else if (keyCode == LEFT) {
    circleX--;
  }
  else if (keyCode == RIGHT) {
    circleX++;
  }
}

This program moves our logic for checking the keyCode variable to move the circle into the keyReleased() function, which Processing automatically calls whenever the user stops pressing a key.

circle controlled by key release

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

The keyboard input functions are useful for detecting typing, since fast typers might type faster than Processing calls the draw() functions. They’re also useful for handling multiple keys being pressed at the same time.

Handling Multiple Keys

The key and keyCode variables only hold the most recent key pressed (or released or typed). This limits us to only knowing about one key at a time. But what if the user is holding down multiple keys at the same time?

To track multiple keys, we need to do four things:

boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;

float circleX = 50;
float circleY = 50;

void draw() {
  background(200);  
  
  if (upPressed) {
    circleY--;
  }
  
  if (downPressed) {
    circleY++;
  }
  
  if (leftPressed) {
    circleX--;
  }
  
  if (rightPressed) {
    circleX++;
  }
  
  ellipse(circleX, circleY, 20, 20);
}

void keyPressed() {
  if (keyCode == UP) {
    upPressed = true;
  }
  else if (keyCode == DOWN) {
    downPressed = true;
  }
  else if (keyCode == LEFT) {
    leftPressed = true;
  }
  else if (keyCode == RIGHT) {
    rightPressed = true;
  }
}

void keyReleased() {
  if (keyCode == UP) {
    upPressed = false;
  }
  else if (keyCode == DOWN) {
    downPressed = false;
  }
  else if (keyCode == LEFT) {
    leftPressed = false;
  }
  else if (keyCode == RIGHT) {
    rightPressed = false;
  }
}

This code uses four boolean values to hold whether any of the array keys are pressed. In the keyPressed() function, the corresponding variable is set to true, and in the keyReleased() function, the corresponding variable is set to false. Then the draw() function uses those variable to move the circle depending on which arrow keys are currently pressed.

circle controlled by multiple keys

Code Editor

See the Pen by Happy Coding (@KevinWorkman) on CodePen.

If this seems confusing, think about exactly what happens when you press two keys at the same time: it might seem like you’re pressing them at the same time, but you’re actually pressing one a split second before the other. Same with releasing them.

Cheat Sheet

This program shows a bunch of the variables and event functions you can use to get user input:

void setup(){
  size(300, 300);
}

void draw() {
  background(200);  
  
  textSize(18);
  fill(0);
  
  text("mousePressed: " + mousePressed, 20, 20);
  text("mouseButton: " + mouseButton, 20, 40);
  text("mouseX: " + mouseX, 20, 60);
  text("mouseY: " + mouseY, 20, 80);
  text("pmouseX: " + pmouseX, 20, 100);
  text("pmouseY: " + pmouseY, 20, 120);
  text("keyPressed: " + keyPressed, 20, 140);
  text("key: " + key, 20, 160);
  text("keyCode: " + keyCode, 20, 180);
}

void keyPressed() {
  println("keyPressed: " + key);
}

void keyReleased() {
  println("keyReleased: " + key);
}

void keyTyped(){
  println("keyTyped: " + key);
}

void mousePressed(){
  println("mousePressed");
}

void mouseReleased(){
  println("mouseReleased");
}

void mouseClicked(){
  println("mouseClicked");
}

void mouseMoved(){
  println("mouseMoved");
}

void mouseDragged(){
  println("mouseDragged");
}

void mouseWheel(){
  println("mouseWheel");
}

Notice that it doesn’t really make sense to display the value of some of these variables (like keyCode or mouseButton). It only makes sense to compare them to other preexisting variables (like SHIFT or LEFT).

Homework

Next: Using Objects

Go back up