🔍

advanced animation with spritesheets in Processing

multiple animations with random placement and phases

This sketch demonstrates how to use simple object classes to animate multiple explosions with each a different animation phase independently in a loop


// This script needs to have the explosions.png spreadsheet in the data folder!!!
// the explosion animation is drawn to the last clicked position not looping

int explo_pos_x = 0;
int explo_pos_y = 0;
int how_many_explosions = 33;

aEXPLO[] allEXPLOSIONS;

void setup(){

  size(640,480);
  init_spritesheet();
  imageMode(CENTER);
  noSmooth();
  
  // create a new list/array of explosion objects
  allEXPLOSIONS = new aEXPLO[how_many_explosions];
  
  // run through the empty list an create a new explosion object at a random position and random phase
  for(int i=0;i<allEXPLOSIONS.length;i++){
  
    allEXPLOSIONS[i] = new aEXPLO(random(width),random(height));
    allEXPLOSIONS[i].my_anim_tick = int(random(11));
  
  }
 
}

void draw(){

  background(22);
  
  // run through the explosion list and update each explosion object 
     for(int i=0;i<allEXPLOSIONS.length;i++){
  
       allEXPLOSIONS[i].updateMe();
  }
   
}
 

// ---------------------------------------------
// ---------------------------------------------
// ----- SPRITESHEET OPERATIONS ---------------- 
// ---------------------------------------------
// ---------------------------------------------
 
// this spritesheet has only one row of 12 x 96x96px graphics
 
int[] explo_anim = {0,1,2,3,4,5,6,7,8,9,10,11 };
int DIM_X = 12; // horizontal dimension of spritesheet
int DIM_Y = 1; // vertical dimension of spritesheet
  
PImage main_sheet;
PImage[] sprites = new PImage[DIM_X*DIM_Y];
int animtick = 0;


 // ---------------------------------------------
void init_spritesheet() {
 imageMode(CENTER);
  main_sheet = loadImage("explosion.png");
  int W = main_sheet.width/DIM_X;
  int H = main_sheet.height/DIM_Y;
   
  for (int i=0; i<sprites.length; i++) {
    
    int x = i%DIM_X*W;
    int y = 0; // this is a hakc here! needs to be improved!!!
    sprites[i] = main_sheet.get(x, y, W, H);

}
  println("extracted " + sprites.length + "frames with each" + W + "x" + H  + "px from spritesheet");
}

// ---------------------------------------------
  
int animate(float _x, float _y, int _w, int _h, int[] _arr, int _anim_tick, int _anim_speed, boolean _hor_flipped, boolean looped) {
    
  pushMatrix();
    translate(_x, _y);
    if(_hor_flipped){
      scale(1,1);
    }else{
      scale(-1,1);
    }
    image(sprites[_arr[_anim_tick]],0,0 , _w, _h);
   popMatrix();
   
  if (frameCount % _anim_speed == 0) {
    if (_anim_tick<_arr.length-1) {
     _anim_tick++;
    } else {
      
      if( looped ){
       _anim_tick = 0;
      }
    }
  }
  return _anim_tick;
}



class aEXPLO{

   // basic var we need for each explosion object
   float x = 0;
   float y = 0;
   int my_anim_tick = 0;
   
   aEXPLO(float _x,float _y){
     // set an inital position
      x =  _x;
      y=   _y;
   
   }
   
   void updateMe(){
   
     // update routine for each explosion object
     my_anim_tick = animate(
      x,
      y,
      300,300,
      explo_anim,
      my_anim_tick,
      5,
       false,
       true
    );
      
   }

}

simple singular animation placement

the explosion animation is drawn to the last clicked position not looping


// This script needs to have the explosions.png spreadsheet in the data folder!!!
// the explosion animation is drawn to the last clicked position not looping

int explo_pos_x = 0;
int explo_pos_y = 0;

void setup(){

  size(640,480);
  init_spritesheet();
  imageMode(CENTER);
  noSmooth();

}

void draw(){

  background(22);
  animtick= animate(
      explo_pos_x,
      explo_pos_y,
      300,300,
      explo_anim,
      animtick,
      5,
     false,
     false
    );
   
}

void mousePressed(){
  
  explo_pos_x = mouseX;
  explo_pos_y = mouseY;
  animtick = 0;

}

// ---------------------------------------------
// ---------------------------------------------
// ----- SPRITESHEET OPERATIONS ---------------- 
// ---------------------------------------------
// ---------------------------------------------
 
// this spritesheet has only one row of 12 x 96x96px graphics
 
int[] explo_anim = {0,1,2,3,4,5,6,7,8,9,10,11 };
int DIM_X = 12; // horizontal dimension of spritesheet
int DIM_Y = 1; // vertical dimension of spritesheet
  
PImage main_sheet;
PImage[] sprites = new PImage[DIM_X*DIM_Y];
int animtick = 0;


 // ---------------------------------------------
void init_spritesheet() {
 imageMode(CENTER);
  main_sheet = loadImage("explosion.png");
  int W = main_sheet.width/DIM_X;
  int H = main_sheet.height/DIM_Y;
   
  for (int i=0; i<sprites.length; i++) {
    
    int x = i%DIM_X*W;
    int y = 0; // this is a hakc here! needs to be improved!!!
    sprites[i] = main_sheet.get(x, y, W, H);

}
  println("extracted " + sprites.length + "frames with each" + W + "x" + H  + "px from spritesheet");
}

// ---------------------------------------------
  
int animate(int _x, int _y, int _w, int _h, int[] _arr, int _anim_tick, int _anim_speed, boolean _hor_flipped, boolean looped) {
    
  pushMatrix();
    translate(_x, _y);
    if(_hor_flipped){
      scale(1,1);
    }else{
      scale(-1,1);
    }
    image(sprites[_arr[_anim_tick]],0,0 , _w, _h);
   popMatrix();
   
  if (frameCount % _anim_speed == 0) {
    if (_anim_tick<_arr.length-1) {
     _anim_tick++;
    } else {
      
      if( looped ){
       _anim_tick = 0;
      }
    }
  }
  return _anim_tick;
}