Slow down an animation

Hi, i found the sequential example to make an animation and i wonder how can i slow down the animation without change the framerate. Is that possible ?

here is the example: (https://processing.org/examples/sequential.html)

int numFrames = 12;  // The number of frames in the animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];
    
void setup() {
  size(640, 360);
  frameRate(24);
  
  images[0]  = loadImage("PT_anim0000.gif");
  images[1]  = loadImage("PT_anim0001.gif"); 
  images[2]  = loadImage("PT_anim0002.gif");
  images[3]  = loadImage("PT_anim0003.gif"); 
  images[4]  = loadImage("PT_anim0004.gif");
  images[5]  = loadImage("PT_anim0005.gif"); 
  images[6]  = loadImage("PT_anim0006.gif");
  images[7]  = loadImage("PT_anim0007.gif"); 
  images[8]  = loadImage("PT_anim0008.gif");
  images[9]  = loadImage("PT_anim0009.gif"); 
  images[10] = loadImage("PT_anim0010.gif");
  images[11] = loadImage("PT_anim0011.gif"); 
  
  // If you don't want to load each image separately
  // and you know how many frames you have, you
  // can create the filenames as the program runs.
  // The nf() command does number formatting, which will
  // ensure that the number is (in this case) 4 digits.
  //for (int i = 0; i < numFrames; i++) {
  //  String imageName = "PT_anim" + nf(i, 4) + ".gif";
  //  images[i] = loadImage(imageName);
  //}
} 
 
void draw() { 
  background(0);
  currentFrame = (currentFrame+1) % numFrames;  // Use % to cycle through frames
  int offset = 0;
  for (int x = -100; x < width; x += images[0].width) { 
    image(images[(currentFrame+offset) % numFrames], x, -20);
    offset+=2;
    image(images[(currentFrame+offset) % numFrames], x, height/2);
    offset+=2;
  }
}

yes you can.

delay = 30;
if(frameCount % delay == 0) {
   //nextFrame Codes goes here
}

if frameRate is at 60 fps then the speed is 60/30 = 2 fps

Instead of

x += images[0].width) {

In the for loop say x+=2 )

Delay is not recommended

You can also use the millis() function to keep track of the elapsed time between each frame to draw.

Something like this:

int previousDisplayTime;  // Keep track of the last time a frame of the animation was displayed
int deltaTime;            // The time between each frame

void setup() {
  deltaTime = 2000; // Display every 2 seconds
  previousDisplayTime = 0;
}


void draw() {
  if (millis() > previousDisplayTime + deltaTime) {
    println("Draw you image");
    previousDisplayTime = millis();
  }
}
2 Likes

did you mean delay() function? nope, that just a variable that determines the speed of the frame cycles through

1 Like

My apologies

My badā€¦

1 Like

thanks guys, i gonna try and yes i just wanted a way to determines the speed of the frame cycles

Chrisir what do you mean by ā€œ(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)ā€ ?

I made a bad reply and had to delete it .

This is just the automatically text by the forum

i pefer the solution by @jb4x. the speed relatives to the real timing, not the frame rate.

2 Likes

Hi, i have tried what you propose, and its work :slight_smile: .
But its not what i need (my bad)
what i looking for is :
1: a way to slow down the cycle of each picture
2: keep each picture long enough to see it

the problem is that it goes too fast

i dont know if you know what i mean but here the code:

int numFrames = 3;  // The number of frames in the animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];

int previousDisplayTime;  // Keep track of the last time a frame of the animation was displayed
int deltaTime;   

void setup() {
  size(600, 600);
   
  deltaTime = 2000; // Display every 2 seconds
  previousDisplayTime = 0;
  
  images[0]  = loadImage("papillonD0.png");
  images[1]  = loadImage("papillonD1.png"); 
  images[2]  = loadImage("papillonD2.png");
  
}

void draw() { 
  background(0);
  currentFrame = (currentFrame+1) % numFrames;  // Use % to cycle through frames
  int offset = 0;
  ////what you said
  if (millis() > previousDisplayTime + deltaTime) {
    image(images[(currentFrame+offset) % numFrames], width/2, height/2);
    offset+=2;
    println("Draw you image");
    previousDisplayTime = millis();
  } 
  
  /////the base i have
  image(images[(currentFrame+offset) % numFrames], width/2, height/3);
  offset+=2;
  
}

i put the three picture so you can see the issue.

papillonD0 papillonD1 papillonD2

Thanks for yours times.

Have a variable called ā€œframeNbā€ that will keep track of wich frame of the animation you are in.

Then change this value inside the time check condition.

After that you can always display your animation frame outside that check based on the value of that variable.

Iā€™m currently on my phone but Iā€™ll write an example later on if you want.

ok i think i understand what you said, i gonna try but an example is always welcome :slight_smile:

Here you go =):

int numFrames = 3;  // The number of frames in the animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];
int posX, posY;

int previousDisplayTime;  // Keep track of the last time a frame of the animation was displayed
int deltaTime;            // The time between each frame

void setup() {
  size(600, 600);
  background(20);

  deltaTime = 150;
  previousDisplayTime = 0;
  
  posX = 10;
  posY = 10;
  
  images[0]  = loadImage("IMG_01.png");
  images[1]  = loadImage("IMG_02.png"); 
  images[2]  = loadImage("IMG_03.png");
}

void draw() {
  if (millis() > previousDisplayTime + deltaTime) {
    currentFrame++;
    if (currentFrame > 2) { 
      currentFrame = 0;
      posX += 8;
      posY += 5;
    }
    previousDisplayTime = millis();
  }
  
  background(20);
  image(images[currentFrame], posX, posY);
}
1 Like

Thanks a lot its work perfectly !!! and i can change the speed !!

1 Like

If you want an industrial-strength solution for dealing with many different sprites at different speeds, I suggest the Sprites for Processing (S4P) library.

http://www.lagers.org.uk/s4p/

The Sprite class has built-in featuresw like an animation interval.

http://www.lagers.org.uk/s4p/ref/classsprites_1_1_sprite.html

2 Likes

I have a similar challenge: How to pause between each drawn frame, so that each frame can be viewed. The program is supposed to draw 4 frames and hold the display of each frame for say 0.5 seconds before displaying the next frame. I tried adjusting frameRate() but it doesnā€™t have an effect.

This is a simple ā€˜walking manā€™ animation whereby the stick figure walks ā€˜on the spotā€™. Below are the first 2 frames of the animation. How to display and pause, display and pause, then repeat?

PImage bkg;

void setup() {
  size (800, 600);
  bkg = loadImage("bkg+clouds.jpg");
}

void draw() {
 background (bkg); // first walking position
 fill(255);
 ellipse (250,150, 100,100);
 fill(0);
 ellipse (270,130, 10,10);
 noFill();
 curve(250, 100, 260, 175, 290, 175, 325, 100);
 stroke(0);
 strokeWeight(3);
 line(250, 200, 250, 350); //body
 line(250, 225, 215, 250); //left arm
 line(215, 250, 200, 300);
 line(250, 225, 300, 275); //right arm
 line(300, 275, 325, 225);
 line(250, 350, 225, 415); //left leg
 line(225, 415, 170, 500);
 line(250, 350, 300, 415); //right leg
 line(300, 415, 325, 500);
 
 background (bkg); // second walking position
 fill(255);
 ellipse (250,150, 100,100);
 fill(0);
 ellipse (270,130, 10,10);
 noFill();
 curve(250, 100, 260, 175, 290, 175, 325, 100);
 stroke(0);
 strokeWeight(3);
 line(250, 200, 250, 350); //body
 line(250, 225, 200, 240); //left arm
 line(200, 240, 190, 290);
 line(250, 225, 285, 285); //right arm
 line(285, 285, 325, 250);
 line(250, 350, 240, 415); //left leg
 line(240, 415, 150, 425);
 line(250, 350, 280, 415); //right leg
 line(280, 415, 270, 500);
}

Problem solved! I applied the following delay display code presented by user jb4x above, and it worked successfully. Thanks @jb4x!

  if (millis() > previousDisplayTime + deltaTime) {
    currentFrame++;
    if (currentFrame > 2) { 
      currentFrame = 0;
      posX += 8;
      posY += 5;
    }
    previousDisplayTime = millis();
  }
1 Like