Processing Beginner Article 3

Conditionals & Logic

Control your sketch's behaviour with if/else, boolean operators, and a simple state machine.

⏱ 17 min conditionals if else boolean state machine bouncing ball

if / else if / else

Conditionals let your sketch make decisions at runtime. The simplest form:

if (mouseX > width / 2) {
  background(200, 100, 50);   // right half: warm
} else {
  background(50, 100, 200);   // left half: cool
}

Chain more branches with else if:

float speed = frameRate;

if (speed < 20) {
  fill(255, 60, 60);    // red — slow
} else if (speed < 50) {
  fill(255, 200, 50);   // yellow — medium
} else {
  fill(80, 220, 80);    // green — fast
}

ellipse(50, 50, 40, 40);

Only the first matching branch runs; the rest are skipped.

Comparison operators

Operator Meaning
== equal to
!= not equal to
< less than
> greater than
<= less than or equal to
>= greater than or equal to

When comparing float values, avoid == (floating-point precision makes exact equality unreliable). Instead test a range: abs(a - b) < 0.001.

Boolean operators

Combine conditions with && (and), || (or), and ! (not):

// Both must be true
if (mouseX > 100 && mouseX < 500) {
  fill(255, 200, 0);
}

// At least one must be true
if (keyPressed && (key == 'r' || key == 'R')) {
  background(200, 50, 50);
}

// Invert a condition
if (!mousePressed) {
  fill(80, 80, 80);
}

Short-circuit evaluation applies: in A && B, if A is false, B is never tested.

Ternary operator

For compact single-line choices:

float sz = mousePressed ? 80 : 30;
ellipse(mouseX, mouseY, sz, sz);

This is equivalent to:

float sz;
if (mousePressed) {
  sz = 80;
} else {
  sz = 30;
}

Use the ternary sparingly — only when both branches are short and the intent is clear.

Switch statement

switch is cleaner than a long chain of if / else if when you are comparing one variable against several exact values.

char tool = 'p';   // 'p' = pen, 'e' = eraser, 'f' = fill

void keyPressed() {
  switch (key) {
    case 'p':
      tool = 'p';
      break;
    case 'e':
      tool = 'e';
      break;
    case 'f':
      tool = 'f';
      break;
    default:
      println("Unknown tool key: " + key);
  }
}

The break at the end of each case is mandatory in Java — without it execution “falls through” into the next case.

Boundary detection: bouncing ball

Checking the edges of the canvas is one of the most common uses of conditionals in Processing.

float x, y, vx, vy, r;

void setup() {
  size(600, 400);
  x  = width / 2;
  y  = height / 2;
  vx = 3.5;
  vy = 2.2;
  r  = 24;
}

void draw() {
  background(20);

  // Move
  x += vx;
  y += vy;

  // Bounce off left and right walls
  if (x - r < 0 || x + r > width) {
    vx *= -1;
    x = constrain(x, r, width - r);   // prevent sticking inside wall
  }

  // Bounce off top and bottom walls
  if (y - r < 0 || y + r > height) {
    vy *= -1;
    y = constrain(y, r, height - r);
  }

  // Draw
  noStroke();
  fill(80, 160, 255);
  ellipse(x, y, r * 2, r * 2);
}

constrain(val, lo, hi) is a built-in that clamps a value — it prevents the ball from tunnelling through the wall when the velocity is high.

State machine: draw / erase / fill modes

Real interactive sketches need to track which “mode” they are in. A single int (or String) variable acting as a state is the simplest form of a state machine.

// States: 0 = draw, 1 = erase, 2 = fill
int state = 0;

void setup() {
  size(700, 500);
  background(245);
}

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

  // HUD
  fill(20);
  noStroke();
  textSize(14);
  String label = "";
  if (state == 0) label = "Mode: DRAW  (D / E / F to switch)";
  if (state == 1) label = "Mode: ERASE (D / E / F to switch)";
  if (state == 2) label = "Mode: FILL  (D / E / F to switch)";
  text(label, 10, 20);
}

void applyTool(float mx, float my) {
  if (state == 0) {
    // Pen: small black dot
    fill(20);
    noStroke();
    ellipse(mx, my, 8, 8);
  } else if (state == 1) {
    // Eraser: white rectangle
    noStroke();
    fill(245);
    rect(mx - 15, my - 15, 30, 30);
  } else if (state == 2) {
    // Flood-fill approximation: paint large area
    fill(random(100, 255), random(100, 255), random(100, 255), 60);
    noStroke();
    ellipse(mx, my, 100, 100);
  }
}

void keyPressed() {
  if (key == 'd' || key == 'D') state = 0;
  if (key == 'e' || key == 'E') state = 1;
  if (key == 'f' || key == 'F') state = 2;
}

The draw() loop reads state every frame. Pressing a key changes state, and the sketch immediately behaves differently. This pattern scales well — add more states without touching the core loop.

Key takeaways

  • if / else if / else routes execution based on runtime conditions.
  • &&, ||, and ! let you combine multiple conditions cleanly.
  • Boundary detection with if (and constrain()) is the foundation of interactive physics.
  • A state variable is the simplest way to build a multi-mode sketch.
  • Avoid floating-point == comparisons; prefer range checks instead.