Conditionals & Logic
Control your sketch's behaviour with if/else, boolean operators, and a simple state machine.
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 / elseroutes execution based on runtime conditions.&&,||, and!let you combine multiple conditions cleanly.- Boundary detection with
if(andconstrain()) 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.