Interactivity

Input Devices

Devices which allow us to interact with computers.

 

Examples:

  • Mouse
  • Keyboard
  • Scanner
  • Microphone
  • Webcam
  • Touchscreen
  • Controller

Our code needs to immediately (or almost immediately) handle external events, regardless of program state.

// Main Loop
void draw(){

  if (checkQuit()){
    exit_application;
  }

  doBigHeavyComputation();

}

Even short delays (~100ms) in processing input feel absolutely awful to the user. Extra FeelsBad points if the delay is variable.

DALL-E still can't quite do text correctly...

Events

Typically, when an event is triggered, the program will call a function. In most general-purpose languages, it is up to us to specify which functions are called on which events.

void handle_sigint(int signum) {
    printf("Received SIGINT signal. Exiting...\n");
    exit(0);
}

int main() {
    struct sigaction sa;
    sa.sa_handler = handle_sigint;

    sigaction(SIGINT, &sa, NULL) == -1;
    // Rest of the program
}

Fortunately, Processing handles most of this boilerplate for us!

Events in Processing

Events

When Processing receives an event, it sets several special variables and tries to call an event handler.

 

If no event handler exists, then the handler is not called.

 

Examples of event handlers:

  • mousePressed()
  • mouseReleased()
  • mouseMoved()
  • mouseDragged()
  • keyPressed()
  • keyReleased()

Mouse Variables

  • mousePressed: stores whether mouse button is pressed or not
  • mouseButton: stores the most recently pressed button, one of LEFT, CENTER, or RIGHT
  • mouseX,mouseY: The coordinates of the mouse cursor in the current window
  • pmouseX, pmouseY: The coordinate of the mouse cursor in the window on the previous frame (useful for determining the direction of mouse motion, e.g. for dragging).
void setup(){
  size(800,800);
}

void mousePressed(){
  if (mouseButton == LEFT){
    textSize(128);
    text("LEFT", mouseX, mouseY);
  } else {
    textSize(168);
    text("RIGHT",mouseX, mouseY);
  }
  
}

void draw(){}

Why is the draw() function empty?

Keyboard Variables

  • keyPressed: stores whether a key has is pressed or not
  • key: stores the most recently pressed key. Can take the value of an ASCII character or one of BACKSPACE, TAB, ENTER, RETURN, ESC, DELETE
  • keyCode: stores keypresses for non-ASCII characters. Useful values include ALT, CONTROL, SHIFT, UP, DOWN, LEFT, RIGHT
int x = 0;
int y = 0;
void setup(){
  size(800,800);
}

void keyPressed(){
  if(keyCode == DOWN){ y += 5; }
  else if (keyCode == UP){ y -= 5; }
  else if (keyCode == LEFT){ x -= 5; }
  // Why not else?
  else if (keyCode == RIGHT){ x += 5; } 
}

void draw(){
  fill(0);
  background(200);  // Reset the screen
  ellipse(x, y, 30, 30);
}

Draw Loop

A kind of system-generated event which is triggered every 16.66 ms (60 times per second).

 

When event triggers, calls the draw() function.

public static void main(String[] args){
  // Create a timer which fires every 16ms
  Trigger draw_tr = create_timer(16);
  // Tell the program that when the event
  // occurs, it should respond by calling draw()
  register_event_handler(draw_tr, draw());
  setup();
  wait_for_exit();
}

But we as the programmer can control when this happens!

Draw Loop Modification

  • noLoop() stops the draw() command
  • loop() resumes the draw() command
  • redraw() executes the draw() command exactly once

These should be thought of as efficiency tools. If your code relies on noLoop() or loop() for correctness, it is probably broken!

int x = 0;
int y = 0;
void setup(){
  size(200,200);
}

void keyPressed(){
  if(keyCode == DOWN){ y += 5; }
  else if (keyCode == UP){ y -= 5; }
  else if (keyCode == LEFT){ x -= 5; }
  // Why not else?
  else if (keyCode == RIGHT){ x += 5; } 
}

void draw(){
  fill(0);
  background(200);
  expensive_operation();
  ellipse(x, y, 30, 30);
}
int x = 0;
int y = 0;
void setup(){
  size(200,200);
  noLoop();
  redraw();
}

void keyPressed(){
  if(keyCode == DOWN){ y += 5; }
  else if (keyCode == UP){ y -= 5; }
  else if (keyCode == LEFT){ x -= 5; }
  // Why not else?
  else if (keyCode == RIGHT){ x += 5; }
  redraw();
}

void draw(){
  fill(0);
  background(200);  // Reset the screen
  expensive_operation();
  ellipse(x, y, 30, 30);
}

CPU Temp: 67 C

CPU Temp: 39 C

Hands-On: Interactivity

  1. Use the variables mousePressed and mouseButton in the draw() loop to control the background color of the sketch.
  2. Comment out the code in draw() and reimplement this in the mousePressed() function.
  3. Use mouseX and mouseY in the mouseMoved() function to draw a circle that follows the mouse.
  4. Display an object to the screen when the 'f' key is pressed using the keyPressed() function.
  5. Remove the object once the key is released using keyReleased() but keep the background color changes and color.

Project Time

Index Cards!

  1. Your name and EID.
     
  2. One thing that you learned from class today. You are allowed to say "nothing" if you didn't learn anything.
     
  3. One question you have about something covered in class today. You may not respond "nothing".
     
  4. (Optional) Any other comments/questions/thoughts about today's class.