# How to run a function every n frames in Processing? A mini callback tutorial

**URL:** <https://discourse.processing.org/t/how-to-run-a-function-every-n-frames-in-processing-a-mini-callback-tutorial/48812>\
**Category:** Gallery\
**Created:** [June 15, 2026, 10:37am UTC](https://discourse.processing.org/t/how-to-run-a-function-every-n-frames-in-processing-a-mini-callback-tutorial/48812 "2026-06-15T10:37:34Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![sableraph](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sableraph/32/251_2.png) [@sableraph](https://discourse.processing.org/u/sableraph)\
**Post date:** [June 15, 2026, 10:37am UTC](https://discourse.processing.org/t/how-to-run-a-function-every-n-frames-in-processing-a-mini-callback-tutorial/48812/1 "2026-06-15T10:37:34Z")

</div>

The `draw()` loop runs 60 times per second. That’s great for animation, but what if you want something to happen only every `n` frames?

A quick way to do it is to use `frameCount` and the modulo operator, like so:

```Processing
if(frameCount % 60 == 0) {
  // something to do once every 60 frames
}

```

That works well, and is all you need for a one-off. But if you find yourself reaching for that pattern often, it’s worth wrapping it into a helper function.

Besides, this will be a good excuse to learn about a Java feature that I haven’t really seen in Processing tutorials before: **passing a function as an argument** (also known as a “callback function”) 😃

In Java we do this with a `Runnable`, a small wrapper that represents a function as a value.

Say we have a function `changeScene()` that we want to call every 60 frames.

We start by storing it in a `Runnable` variable using a **method reference** :

```Processing
Runnable onNextScene = this::changeScene;

```

_Note: `this` refers to your sketch, which extends `PApplet` under the hood._

If you prefer, you can write the same thing as a **lambda** (both are equivalent):

```Processing
Runnable onNextScene = () -> changeScene();

```

Now that `changeScene` is stored as a value, we can call it with `.run()`:

```Processing
onNextScene.run(); // calls changeScene()

```

And since it’s just a variable, we can pass it to another function as an argument:

```Processing
doEvery(60, onNextScene);

```

That’s all `doEvery` needs to do its job. It receives a `Runnable` and calls `.run()` at the right moment:

```Processing
void doEvery(int frameInterval, Runnable callback) {
  if (frameCount % frameInterval == 0) {
    callback.run();
  }
}

```

Here’s the full sketch putting it all together:

```Processing
Runnable onNextScene;

color bg = color(175);
int shapeType = 0;

void setup() {
  size(400, 400);
  colorMode(HSB);
  
  // Equivalent to onNextScene = () -> changeScene();
  onNextScene = this::changeScene;
}

void draw() {
  background(bg);

  doEvery(60, onNextScene);
  
  stroke(255);
  strokeWeight(2);
  
  switch(shapeType) {
    case 0: ellipse(200, 200, 150, 150); break;
    case 1: rect(125, 125, 150, 150); break;
    case 2: triangle(200, 125, 275, 275, 125, 275); break;
  }
}

void changeScene() {
  bg = color(random(255), random(240, 255), random(200, 255));
  shapeType = (shapeType + 1) % 3;
}

// Run the given callback function every frameInterval frames
void doEvery(int frameInterval, Runnable callback) {
  if (frameCount % frameInterval == 0) {
    callback.run();
  }
}

```

Credit to @neill for [the p5.js-based inspiration](https://editor.p5js.org/neill0/sketches/IgSoLB8Pp) 💙🌸

---

<div class="post-metadata">

**Author:** ![sableraph](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sableraph/32/251_2.png) [@sableraph](https://discourse.processing.org/u/sableraph)\
**Post date:** [June 15, 2026, 10:43am UTC](https://discourse.processing.org/t/how-to-run-a-function-every-n-frames-in-processing-a-mini-callback-tutorial/48812/2 "2026-06-15T10:43:26Z")

</div>

Here are some other examples of probability functions taking inspiration from [this p5.js sketch](https://editor.p5js.org/neill0/sketches/IgSoLB8Pp) by @neill:

```Processing
Runnable onColorChange;

color bg = color(175);
int shapeType = 0;
int lineWeight = 1;

void setup() {
  size(400, 400);
  colorMode(HSB);
  onColorChange = this::randomizeBackground;
}

void draw() {
  background(bg);
  
  // 5% chance of changing background each frame. Try tweaking this!
  sometimes(0.05, onColorChange);
  
  // 10% chance of changing shape each frame
  occasionally(() -> {
    shapeType = (shapeType + 1) % 3;
  });
  
  // Coin flip each frame: nudge position and randomize stroke weight
  fiftyFifty(() -> {
    translate(random(-4,4), 0);
    lineWeight = (int)random(1, 10);
  });
  
  stroke(255);
  strokeWeight(lineWeight);
  noFill();
  
  switch(shapeType) {
    case 0: ellipse(200, 200, 150, 150); break;
    case 1: rect(125, 125, 150, 150); break;
    case 2: triangle(200, 125, 275, 275, 125, 275); break;
  }
}

void randomizeBackground() {
  bg = color(random(255), random(180, 200), random(200, 210));
}

// Call the callback with the given probability (0.0–1.0)
void sometimes(float probability, Runnable callback) {
  if (random(1) < probability) {
    callback.run();
  }
}

// Call the callback 50% of the time
void fiftyFifty(Runnable callback) {
  sometimes(0.5, callback);
}

// Call the callback 10% of the time
void occasionally(Runnable callback) {
  sometimes(0.1, callback);
}

```
