simple starfield simulation combined with spritesheet animation
This sketch refers to a custom creates spritesheet animation system for Processing – check more details here: https://turboflip.de/advanced-animation-with-spritesheets-in-processing/
It combines a simple starfield simulation with a 2D mouse click behaviour and spritesheet animation. all wrapped with object and class logic 🙂
// NOTE!!! this script needs to have a explosion.png spritesheet in the data folder!!! int how_many_stars = 800; float displace_amount = 0; float targetSpeed = 0; float main_speed = 0; aSTAR[] allSTARS; void setup() { size(640, 480); init_spritesheet(); imageMode(CENTER); noSmooth(); // create a new list/array of explosion objects allSTARS = new aSTAR[how_many_stars]; // run through the empty list an create a new star object at a random position and random phase for (int i=0; i<allSTARS.length; i++) { allSTARS[i] = new aSTAR( random(-width/2, width/2), random(-height/2, height/2) ); } } void draw() { displace_amount = map(mouseY, 0, height, 0, 4); targetSpeed = map(mouseX, 0, width, 0, 2); // update Speed main_speed = lerp(targetSpeed, main_speed, 0.1); noStroke(); fill(0, 44); rect(0, 0, width, height); translate(width/2, height/2); // run through the star list and update each star object for (int i=0; i<allSTARS.length; i++) { if(allSTARS[i].do_explode){ allSTARS[i].explodeMe(); }else{ allSTARS[i].updateMe(); } } } void mousePressed() { // by pressing any mouse button, a random star needs to explode! int nid = return_ID_of_the_nearest_star_2D(); allSTARS[nid].do_explode = true; } int return_ID_of_the_nearest_star_2D() { float def_dist = 100000; int rid = -1; float cdist = 0; for (int i=0; i<allSTARS.length; i++) { cdist = dist( mouseX-width/2, mouseY-height/2, allSTARS[i].sx, allSTARS[i].sy); if (cdist < def_dist) { rid = i; def_dist = cdist; } } return rid; } // --------------------------------------------- // --------------------------------------------- // ----- 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 aSTAR { // basic var we need for each star object float x = 0; float y = 0; float z = 0; float sx=0; float sy=0; int my_anim_tick = 0; float myspeed = .1; boolean do_explode = false; aSTAR(float _x, float _y) { // set an inital position x = _x; y= _y; z = random(width/2); } void resetMe() { x = random(-width/2, width/2); y = random(-height/2, height/2); z = random(width/2); do_explode = false; } void updateMe() { z -= myspeed + main_speed; x += ( noise(z*.01, y*.01, millis()*.0001 )-.5 ) * displace_amount; y += ( noise(x*.01, z*.01, millis()*.0001 )-.5 ) * displace_amount; sx = map(x / z, 0, 1, 0, width/2); sy = map(y / z, 0, 1, 0, height/2); // I use the z value to increase the star size between a range from 0 to 16. float r = map(z, 0, width/2, 10, 0); fill(255, 255-1*z); noStroke(); ellipse(sx, sy, r, r); if (z<4) { resetMe(); } } void explodeMe() { // update routine for each explosion object my_anim_tick = animate( sx, sy, int(z*1.2), int(z*1.2), explo_anim, my_anim_tick, 5, false, true ); if (my_anim_tick>explo_anim.length-2) { resetMe(); } } }
is this fireflies or stars?
This sketch is a simple redesign of Daniel Shiffmans starfield simulation. It adds up with a displacement that can be contolled by the mouse
int how_many_stars = 800; float displace_amount = 0; float targetSpeed = 0; float main_speed = 0; aSTAR[] allSTARS; void setup(){ size(640,480); init_spritesheet(); imageMode(CENTER); noSmooth(); // create a new list/array of explosion objects allSTARS = new aSTAR[how_many_stars]; // run through the empty list an create a new star object at a random position and random phase for(int i=0;i<allSTARS.length;i++){ allSTARS[i] = new aSTAR( random(-width/2, width/2), random(-height/2, height/2) ); } } void draw(){ displace_amount = map(mouseY, 0, height, 0, 4); targetSpeed = map(mouseX, 0, width, 0, 2); // update Speed main_speed = lerp(targetSpeed, main_speed, 0.1); noStroke(); fill(0,44); rect(0,0,width,height); translate(width/2, height/2); // run through the star list and update each star object for(int i=0;i<allSTARS.length;i++){ allSTARS[i].updateMe(); } } class aSTAR{ // basic var we need for each star object float x = 0; float y = 0; float z = 0; // int my_anim_tick = 0; float myspeed = .1; aSTAR(float _x,float _y){ // set an inital position x = _x; y= _y; z = random(width/2); } void resetMe(){ x = random(-width/2, width/2); y = random(-height/2, height/2); z = random(width/2); } void updateMe(){ z -= myspeed + main_speed; x += ( noise(z*.01,y*.01, millis()*.0001 )-.5 ) * displace_amount; y += ( noise(x*.01,z*.01, millis()*.0001 )-.5 ) * displace_amount; float sx = map(x / z, 0, 1, 0, width/2); float sy = map(y / z, 0, 1, 0, height/2); // I use the z value to increase the star size between a range from 0 to 16. float r = map(z, 0, width/2, 10, 0); fill(255,255-1*z); noStroke(); ellipse(sx, sy, r, r); if(z<4){ resetMe(); } /* // update routine for each explosion object my_anim_tick = animate( x, y, 300,300, explo_anim, my_anim_tick, 5, false, true ); */ } }