We are about to switch to a new forum software. Until then we have removed the registration on this forum.
In my prev comment I was referring to keywords.
Are we going to have a countdown for closing this forum?
Kf
If they're ".java" files, you can simply copy & paste them into the same folder as your ".pde" files. :bz
Take a look at the sketch from these links below. They're for the same sketch btW: O:-)
That sketch is made of 1 ".pde" file: "CountdownClass.pde"
And a ".java" 1: "Countdown.java"
I'd like to write code that will execute when you click the mouse
and I want the action to run for a maximum of four seconds. If the mouse is still pressed for longer than four seconds, the action will stop.
However, I want the action to stop immediately once the mouse is released if the mouse is released after say for example two or three seconds
Also, I'd want this to be repeatable
Then, on mouseReleased, reset all your timer variable(s).
And in order to make easier to spot each version and have them organized in 1 place, I've re-published them all in a new own forum thread of mine: :-bd
https://Forum.Processing.org/two/discussion/27733/countdown-class-library-for-java-js-python
And as GitHub's Gists as well: :bz
"""
Countdown Class II (v1.2.5)
GoToLoop (2017/Aug/30)
Forum.Processing.org/two/discussion/27733/
countdown-class-library-for-java-js-python#Item_3
Forum.Processing.org/two/discussion/23846/
time-delay-in-python-mode#Item_17
Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1
"""
from countdown import Countdown
SECS = 7.5
WAIT_TIME = int(SECS * 1000)
WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK
DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK
countdown = Countdown(SECS)
def setup():
size(300, 180)
smooth(3)
frameRate(60)
colorMode(RGB)
fill(0xffFFFF00)
textSize(0100)
textAlign(CENTER, CENTER)
m = millis(); t = m + WAIT_TIME
countdown.start()
print m, t, t - m, TAB, countdown
def draw(AWAIT='Awaiting ' + `SECS`, END='Finished'):
this.surface.title = countdown.done and END or AWAIT
background(DONE_BG if countdown.done else WAITING_BG)
txt = `millis()` + ENTER + `frameCount`
text(txt, width>>1, height>>1)
"""
Countdown Class II (v1.2.5)
GoToLoop (2017/Aug/30)
https://Forum.Processing.org/two/discussion/27733/
countdown-class-library-for-java-js-python#Item_3
https://Forum.Processing.org/two/discussion/23846/
time-delay-in-python-mode#Item_17
https://Gist.GitHub.com/GoToLoop/893dc18856a7842b76a92d8aea837da1
"""
from threading import Timer
class Countdown:
def __init__(self, waitTime=0.0): # seconds
self.delay = abs(waitTime)
self.done = True
def job(): self.done = True
self._timeout = job
self.task = None
def __str__(self, STR='Delay: %.3f - Done: %s'):
return STR % (self.delay, self.done)
def start(self):
self.task and self.task.cancel()
self.task = Timer(self.delay, self._timeout)
self.done = False
self.task.start()
return self
"""
Countdown Class (v1.2.5)
GoToLoop (2017/Aug/28)
Forum.Processing.org/two/discussion/27733/
countdown-class-library-for-java-js-python#Item_2
Forum.Processing.org/two/discussion/23846/
time-delay-in-python-mode#Item_14
Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57
"""
from countdown import Countdown
SECS = 7.5
WAIT_TIME = int(SECS * 1000)
WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK
DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK
countdown = Countdown(WAIT_TIME)
def setup():
size(300, 180)
smooth(3)
frameRate(60)
colorMode(RGB)
fill(0xffFFFF00)
textSize(0100)
textAlign(CENTER, CENTER)
m = millis(); t = m + WAIT_TIME
countdown.start()
print m, t, t - m, TAB, countdown
def draw(AWAIT='Awaiting ' + `SECS`, END='Finished'):
this.surface.title = countdown.done and END or AWAIT
background(DONE_BG if countdown.done else WAITING_BG)
txt = `millis()` + ENTER + `frameCount`
text(txt, width>>1, height>>1)
"""
Countdown Class (v1.2.5)
GoToLoop (2017/Aug/28)
https://Forum.Processing.org/two/discussion/27733/
countdown-class-library-for-java-js-python#Item_2
https://Forum.Processing.org/two/discussion/23846/
time-delay-in-python-mode#Item_14
https://Gist.GitHub.com/GoToLoop/a476ac6a01d18700240853fed33c0e57
"""
from java.util import Timer, TimerTask
class Countdown:
_t = Timer('Countdown')
def __init__(self, waitTime=0): # milliseconds
self.delay = abs(int(waitTime))
self.done = True
class Job(TimerTask):
def run(_): self.done = True
self._Timeout = Job
self.task = None
def __str__(self, STR='Delay: %d - Done: %s'):
return STR % (self.delay, self.done)
def start(self):
self.task and self.task.cancel()
self.task = self._Timeout()
self.done = False
self._t.schedule(self.task, self.delay)
return self
<script async src=http://CDN.JSDelivr.net/npm/p5></script>
<script defer src=countdown.js></script>
<script defer src=sketch.js></script>
/**
* Countdown Class (v1.2.5)
* GoToLoop (2017/Aug/29)
*
* Forum.Processing.org/two/discussion/27733/
* countdown-class-library-for-java-js-python#Item_1
*
* Forum.Processing.org/two/discussion/23846/
* time-delay-in-python-mode#Item_16
*
* Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60
*/
"use strict";
const SECS = 7.5, WAIT_TIME = SECS * 1000 | 0,
AWAIT = SECS, END = 'Finished', LF = '\n',
countdown = new Countdown(WAIT_TIME);
let waitingBG, doneBG;
function setup() {
createCanvas(300, 180);
frameRate(60);
colorMode(RGB).blendMode(BLEND);
fill('yellow').stroke(0).strokeWeight(1.5);
textSize(0o100).textAlign(CENTER, CENTER);
waitingBG = color('blue');
doneBG = color('red');
const m = ~~millis(), t = m + WAIT_TIME;
countdown.start();
console.log(m, t, t - m, countdown.toString());
status = m + ', ' + t + ', ' + (t - m);
}
function draw() {
top.document.title = countdown.done && END || AWAIT;
background(countdown.done && doneBG || waitingBG);
const txt = ~~millis() + LF + frameCount;
text(txt, width>>1, height>>1);
}
/**
* Countdown Class (v1.2.5)
* GoToLoop (2017/Aug/29)
*
* https://Forum.Processing.org/two/discussion/27733/
* countdown-class-library-for-java-js-python#Item_1
*
* https://Forum.Processing.org/two/discussion/23846/
* time-delay-in-python-mode#Item_16
*
* http://Bl.ocks.org/GoSubRoutine/1a0d21828319cf18fecf44101764bd60
*/
"use strict";
class Countdown {
get delay() {
return this._delay;
}
set delay(waitTime) {
this._delay = ~~Math.abs(waitTime);
}
constructor(waitTime=0) { // milliseconds
this.delay = waitTime;
this.done = true;
this._timeout = () => this.done = true;
this.task = 0;
}
toString() {
return 'Delay: ' + this.delay + ' - Done: ' + this.done;
}
start() {
clearTimeout(this.task);
this.done = false;
this.task = setTimeout(this._timeout, this.delay);
return this;
}
}
/**
* Countdown Class (v1.2.5)
* GoToLoop (2017/Aug/26)
*
* Forum.Processing.org/two/discussion/27733/
* countdown-class-library-for-java-js-python
*
* Forum.Processing.org/two/discussion/23846/
* time-delay-in-python-mode#Item_11
*
* Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21
*/
import gotoloop.countdown.Countdown;
static final float SECS = 7.5;
static final int WAIT_TIME = (int) (SECS * 1000);
static final String AWAIT = "Awaiting " + SECS;
static final String END = "Countdown Finished";
static final color WAITING_BG = PImage.BLUE_MASK | PImage.ALPHA_MASK;
static final color DONE_BG = PImage.RED_MASK | PImage.ALPHA_MASK;
final Countdown countdown = new Countdown(WAIT_TIME);
void setup() {
size(300, 180);
smooth(3);
frameRate(60);
colorMode(RGB);
fill(#FFFF00);
textSize(0100);
textAlign(CENTER, CENTER);
final int m = millis(), t = m + WAIT_TIME;
countdown.start();
println(m, t, t - m, TAB, countdown);
}
void draw() {
getSurface().setTitle(countdown.done? END : AWAIT);
background(countdown.done? DONE_BG : WAITING_BG);
final String txt = millis() + "\n" + frameCount;
text(txt, width>>1, height>>1);
}
/**
* Countdown Class (v1.2.5)
* GoToLoop (2017/Aug/26)
*
* https://Forum.Processing.org/two/discussion/27733/
* countdown-class-library-for-java-js-python
*
* https://Forum.Processing.org/two/discussion/23846/
* time-delay-in-python-mode#Item_11
*
* https://Gist.GitHub.com/GoToLoop/ea4db8a8622e27541213da3c9a43ca21
*/
package gotoloop.countdown;
import java.util.Timer;
import java.util.TimerTask;
public class Countdown {
protected static final Timer t = new Timer("Countdown");
public TimerTask task;
public int delay;
public volatile boolean done = true;
public Countdown() {
}
public Countdown(final int waitTime) { // milliseconds
delay = Math.abs(waitTime);
}
@Override public String toString() {
return "Delay: " + delay + " - Done: " + done;
}
public Countdown start() {
if (task != null) task.cancel();
done = false;
t.schedule(task = new Timeout(), delay);
return this;
}
protected class Timeout extends TimerTask {
@Override public void run() {
done = true;
}
}
}
Be aware that "CountdownClass1.pyde" & "CountdownClass2.pyde" are a silly test drive I've come up w/ in order to confirm that "countdown.py" is indeed working correctly. :(|)
The class
Countdown inside file "countdown.py" is the actual library. $-)
The ".pyde" sketch is merely a very limited example for the library in "countdown.py". 8-X
Looking at the console, I see the FALSE shows up immediately, ...
That console printed info is run from within setup(). Therefore it happens once only!
When I run it, my console displays something like this: 2764 10264 7500 Delay: 7500 - Done: False
2764
is current millis().10264
is the expected millis() when Countdown::done becomes True
.7500
is the Countdown::delay time. That is: 10264 - 2764
.Delay: 7500 - Done: False
is the String returned by Countdown::_ _ str _ _()... , it never gets to TRUE (which is what I thought it was supposed to do).
Have you paid attention to what is displayed at the top of the sketch's window? L-)
In the beginning its title is: Awaiting 7.5
.
Once the expected millis() is reached its title becomes: Finished
Constant SECS is 7.5
, which is the desired Countdown::delay time in seconds.
While constant WAIT_TIME is SECS multiplied by 1000
. Which is its corresponding time in milliseconds.
Yes I have finally spotted them. Trying to understand them now.
Ok, I have the countdown.py (as the second tab) and your pyde copied and pasted in the first tab. I do not get any errors running it so I have named them correctly.
The program seems to run a timer, the bottom number runs slower than the one on top.
The one at the top I assume is regular time (in seconds). The one on the bottom, I am not sure how it works. No matter what I changed the SECS or the (SECS * number), it seems to run at the same speed. My benchmark was 10 second ( at the top) and the bottom always seems to be at about 600.
Looking at the console, I see the FALSE shows up immediately, but even when I set the SECS to something low, it never gets to TRUE (which is what I thought it was supposed to do). I am probably wrong here...what else is new...
Are you going to share yours at some point...
I've written them for you here in this very forum thread! Can't you spot them? :-\"
There are 4 versions btW: :\">
I advise you to read your forum thread from the beginning. #:-S
You seem pretty lost after your almost a year "vacation". B-)
Oh I see what I've done, I mixed up here: you wrote : "However, it's called CountdownTimer, not just Countdown as mine:" I thought the first one was yours...now I see. Are you going to share yours at some point or is it just a personal project?
I did see you Countdown timer in the distribution manager now, ...
That CountdownTimer library isn't mine. I've never published my own Countdown class anywhere else! :-\"
Once installed, if you wanna import that particular 3rd-party library, you may try out this statement: L-)add_library('CountdownTimer')
I am just getting back to this thread. I did see you Countdown timer in the distribution manager now, but I am unsure on how to import or call it!
Demo at http://p5js.sketchpad.cc/sp/pad/view/En0henvcHV/latest
Notice that it seems image()
is not yet (properly) implemented in p5.js when using the WebGJ renderer. See https: //github.com/processing/p5.js/issues/1507
Kf
// Boomerange effect - Proof of concept
// REFERENCE: https:// forum.processing.org/two/discussion/27681/how-to-make-ascending-and-descending-list-of-numbers-based-on-time#latest
//
//NOTICE: WebGL doesn't seem to fully implement Processing functions such as image(). More at https://github.com/processing/p5.js/issues/1507
var PH8 = function ( p ) {
var myCanvas;
var m;
var upFlag;
var currentTimer;
var pg;
var img;
var img2;
var coma, dearlove, icantthink;
p.preload = function() {
img = p.loadImage("/static/uploaded_resources/p.23038/timeline_sw.languages_1995.java.1.0.jpg");
img2 = p.loadImage("/static/uploaded_resources/p.23038/figSmall.jpg");
//comma = p.loadModel('http://people.sc.fsu.edu/~jburkardt/data/obj/airboat.obj');
//dearlove = p.loadModel('https://groups.csail.mit.edu/graphics/classes/6.837/F03/models/cow-nonormals.obj');
//icantthink = p.loadModel('https://groups.csail.mit.edu/graphics/classes/6.837/F03/models/pumpkin_tall_10k.obj');
}
p.setup = function() {
myCanvas = p.createCanvas(600, 400, p.P2D);
pg = p.createGraphics(p.width-100, p.height-200,p.WEBGL);
p.imageMode(p.CENTER,p.CENTER);
m = 0;
upFlag=1;
img.resize(p.width/4,0);
setInterval(function() {
clearInterval(currentTimer);
if (upFlag==0) {
currentTimer = setInterval(p.countUp, 100);
upFlag=1;
} else {
currentTimer = setInterval(p.countDown, 100);
upFlag=0;
}
},1000);
}// Setup
p.draw = function() {
p.background('#c3f2cf');
//console.log("m = " + m);
p.translate(p.width/2,p.height/2);
p.rotate(m/10.0);
if (p.mouseIsPressed) {
p.image(img,0,0);
} else {
//pg.background(190,255,190);
//pg.push();
//pg.translate(p.width/2,p.height/2, 100);
//pg.normalMaterial();
//pg.rotateX(3.14159);
//pg.rotateY(0.78539+ p.frameCount*0.05);
//pg.scale(0.5);
//pg.fill(150);
//pg.stroke(0,150,25);
//var pg2 = p.createGraphics(256,256);
//pg.box(p.witdth/2,50,50);
//pg2.text('hello world!', 50, 50);
//pg.texture(pg2);
//pg.pop();
//p.image(pg,50,0);
p.image(img2,0,0);
}
}
p.countUp = function() {
m += 1;
}
p.countDown = function() {
m -= 1;
}
}
myp5 = new p5(PH8, 'container8');
Thanks for the quick response, I have attempted a solution using what you recommended which looked something like
var PH8 = function ( p ) {
var myCanvas;
var img;
var img2;
p.preload = function() {
img = p.loadImage('Resources/Photos/Painthead/checktex.png');
img2 = p.loadImage('Resources/Photos/Painthead/leopardPrint2.jpg');
}
p.setup = function() {
myCanvas = p.createCanvas(canvasWidth, canvasHeight, p.WEBGL);
comma = p.loadModel('Resources/3DComma.obj');
dearlove = p.loadModel('Resources/dearlove.obj');
icantthink = p.loadModel('Resources/icantthink.obj');
}
p.windowResized = function() {
p.resizeCanvas(canvasWidth, canvasHeight);
}
p.draw = function() {
if (mouseIsPressed) {
p.background('#c3f2cf');
p.push();
p.translate(micLevel*1000+200, micLevel*300+100, 100);
p.normalMaterial();
p.rotateX(3.14159);
p.rotateY(0.78539+ p.frameCount*0.05);
p.scale(0.5);
p.model(comma);
p.pop();
p.push();
p.translate(-60, 50, 35);
var preMap = sin(p.frameCount);
var postMap = p.map(preMap, -1, 1, -3.14, 0);
console.log(postMap);
p.rotateX(postMap);
p.texture(img2);
p.scale(0.9);
p.model(dearlove);
p.pop();
p.push();
p.translate(-55, -80, 25);
p.rotateX(p.frameCount * 0.19);
p.rotateY(0);
p.texture(img2);
p.scale(9);
p.model(icantthink);
p.pop();
// p.fill(r, g, b);
}
else {
p.background(255);
}
}
}
myp5 = new p5(PH8, 'container8');
but the output from the sine function is still very jumpy. I have attempted another solution that looks like the following(I have removed extraneous lines of code)
var PH8 = function ( p ) {
var myCanvas;
var m;
p.countUp = function() {
m += 1;
}
p.countDown = function() {
m -= 1;
}
p.setup = function() {
myCanvas = p.createCanvas(canvasWidth, canvasHeight, p.WEBGL);
m = 0;
setInterval(function() {
if (second() % 2 == 0) {
clearInterval(down);
var up = setInterval(p.countUp, 100);
} else {
clearInterval(up);
var down = setInterval(p.countDown, 100);
}
}, 1000);
}
p.draw = function() {
if (mouseIsPressed) {
p.background('#c3f2cf');
console.log("m = " + m);
}
else {
p.background(255);
}
}
}
`myp5 = new p5(PH8, 'container8');`
and this almost works, as the numbers do oscillate up and down, but the sequence of numbers approaches infinity rather than forever oscillating. Any thoughts? Thanks.
Lots of great timer examples in the forum:
See also Timing Utilities and Countdown Timer under "Utilities" on the libraries page -- looking at examples can be helpful.
I'm having some real trouble getting my two Classes to acknowledge one another and create some sort of collision physics. i'll post my code below, just wondering if there's a way in which this can be achieved. The game is based on table top football, so the ball should be reacting to the 'player' by moving in the opposite direction once they collide, both on the X and Y axis.
Thanks in advance
Ball ball;
Timer startTimer;
Blue blue;
Red red;
void setup () {
size (1200, 800);
frameRate(100);
startTimer = new Timer (0);
ball = new Ball (600, 400,15);
blue = new Blue (400, 230, 50,0,0,255);
red = new Red (800, 230, 50, 200, 255, 0, 0);
}
void draw () {
drawPitch ();
ball.display();
ball.update();
ball.bCollision();
startTimer.countUp();
blue.displayBlue();
blue.moveBlue();
fill(0);
textSize (20);
text (startTimer.getTime(), 575, 20);
println (mouseX, mouseY);
}
void drawPitch () {
background (#4BAF22);
//SIDELINES
strokeWeight (5);
stroke(255);
line (50, 780, 1150, 780);
line (50, 20, 1150, 20);
//GOAL LINES
line (50, 20, 50, 780);
line (1150, 780, 1150, 20);
//CENTER LINE
line (600, 20, 600, 780);
//CENTER ELLIPSE
fill (255);
ellipse (600, 400, 20, 20);
//CENTER BOX (CIRCLE)
noFill();
ellipse (600, 400, 250, 250);
//REDTEAM BOX
line (50, 120, 280, 120);
line (50, 680, 280, 680);
line (280, 120, 280, 680);
//REDTEAM INNER BOX
line (50, 275, 120, 275);
line (50, 525, 120, 525);
line (120, 275, 120, 525);
//REDTEAM PENATLY SPOT
fill(255);
ellipse (200, 400, 20, 20);
//REDTEAM GOAL
noFill();
rect (0, 337, 50, 124);
//REDTEAM SEMICIRCLE
arc (280, 400, 125, 200, -HALF_PI, HALF_PI);
//BLUETEAM BOX
line (1150, 120, 925, 120);
line (1150, 680, 925, 680);
line (925, 120, 925, 680);
//BLUETEAM INNER BOX
line (1080, 275, 1150, 275);
line (1080, 525, 1150, 525);
line (1080, 275, 1080, 525);
//BLUETEAM PENALTY SPOT
fill(255);
//BLUETEAM GOAL
ellipse (1000, 400, 20, 20);
noFill();
rect(1150, 337, 1200, 124);
//BLUETEAM SEMICIRCLE
arc (925, 400, 125, 200, HALF_PI, PI+PI-HALF_PI);
//CORNERS
arc (50, 20, 70, 75, -QUARTER_PI+QUARTER_PI, QUARTER_PI+QUARTER_PI);
arc (50, 780, 70, 75, -HALF_PI, PI-PI);
arc (1150, 780, 70, 75, PI, PI+QUARTER_PI+QUARTER_PI);
arc (1150, 20, 70, 75, HALF_PI, PI);
}
class Ball {
PVector pos1 = new PVector (0, 0);
PVector velo;
float radius;
float m;
Ball (float x, float y, float r_) {
pos1 = new PVector (x, y);
velo = PVector.random2D();
velo.mult(3);
radius = r_;
m = radius * .1;
}
void update () {
pos1.add(velo);
}
void pCollision () {
}
void bCollision () {
if (pos1.x > width-60) { //RIGHT WALL
pos1.x = width-60;
velo.x *= -1;
} else if (pos1.x < 60 ) { //LEFT WALL
pos1.x = 60;
velo.x *= -1;
} else if (pos1.y > height-35) { //BOTTOM WALL
pos1.y = height-35;
velo.y *= -1;
} else if (pos1.y <40) { //TOP WALL
pos1.y = 40;
velo.y *= -1;
}
}
void display () {
noStroke();
fill(0);
ellipse (pos.x, pos.y, radius*2, radius*2);
}
}
class Blue {
PVector pos;
float Size = 50;
float Speed = 0.1;
float radius;
color Colour = color (0, 0, 255);
Blue (float x, float y, float r_, int red, int green, int blue) {
pos = new PVector(x, y);
radius = r_;
Colour = color (red, green, blue);
}
void displayBlue () {
fill (Colour);
strokeWeight (2);
stroke(255);
ellipse(pos.x, pos.y, radius, radius);
}
void moveBlue () {
if ((keyPressed == true) && (key == 'a')) {
pos.x = pos.x -3;
}
if ((keyPressed == true) && (key == 'd')) {
pos.x = pos.x +3;
}
if ((keyPressed == true) && (key == 'w')) {
pos.y = pos.y -3;
}
if ((keyPressed == true) && (key == 's')) {
pos.y = pos.y +3;
}
}
}
class Red {
float xPos;
float yPos;
float Size = 50;
float Speed = 0.1;
color Colour = color (0, 0, 255);
PVector Direction;
Red (float x, float y, float size, float speed, int red, int green, int blue) {
yPos = y;
xPos = x;
Size = size;
Speed = speed;
Colour = color (red, green, blue);
}
void display () {
fill (Colour);
strokeWeight (2);
stroke(255);
ellipse(xPos, yPos, Size, Size);
}
void move () {
if ((keyPressed == true) && (key == 'a')) {
xPos = xPos -2;
}
if ((keyPressed == true) && (key == 'd')) {
xPos = xPos +2;
}
if ((keyPressed == true) && (key == 'w')) {
yPos = yPos -2;
}
if ((keyPressed == true) && (key == 's')) {
yPos = yPos +2;
}
}
}
class Timer {
float Time; //ATTRIBUTES
Timer (float set) { //CONSTRUCTOR
Time = set;
}
float getTime() { //RETURNS CURRENT TIME
return(Time);
}
void setTime (float set) { // SET TIMER
Time = set;
}
void countUp () { //UPDATE TIMER +
Time += 1/frameRate;
}
void countDown () {
Time -=1/frameRate;
}
}
Although my Countdown library can fit in the task of awaiting some amount of time so your sketch knows when it's time to increase the index variable for your PImage[] array, it's kinda awkward to keep invoking its start() method over & over for each single increase.
That's b/c it's an action which needs to repeat itself at some fixed time.
There are many approaches for it btW.
For Processing, most famous is via millis(), as you're attempting it above.
But I'm gonna describe another 1 which relies on frameCount instead:
https://Processing.org/reference/frameCount.html
By default, a Processing sketch callbacks draw() at about 60 FPS:
https://Processing.org/reference/frameRate_.html
It means that each 60 draw() frames, about 1 second (or 1000 milliseconds) had transpired.
Let's say you wanna increase your index variable each 2 seconds interval.
Translating that to frameCount, we've got a 120 frames interval (2 * 60 FPS).
static final int IMAGES = 10, FPS = 60, INTERVAL = 2 * FPS;
final PImage[] pics = new PImage[IMAGES];
int idx;
Easiest shortcut to know that each 120 frames had passed is using the modulo/remaining %
operator:
https://Processing.org/reference/modulo.html
That is, we just need to check whether current frameCount is exactly dividable by 120: *-:)if (frameCount % INTERVAL == 0) idx = (idx + 1) % IMAGES;
As you can above, the same %
operator can also be used to ensure current index never reaches array's length! It loops back to 0 once it reaches its length! \m/