simple player created from npc class
This example shows how to use a general NPC class to create a key controlled player character to move over the stage.
// ------------------------------------------------------------ // ----- CUSTOM PLAYER OBJECT DERIVATED BY NPC ---------------- // ------------------------------------------------------------ aNPC playerOBJ; float medge = .1; // motion edge void createPlayer(){ playerOBJ = new aNPC(-1); playerOBJ.acc.x = 0; playerOBJ.acc.y = 0; } // --------------------------------------------- // --------------------------------------------- // ----- CUSTOM NPC CLASS ---------------- // --------------------------------------------- // --------------------------------------------- class aNPC{ int id = -1; PVector pos = new PVector(256,128); PVector acc = new PVector(); int animtick = 0; int anim_speed = int(random(3,7)); // animation speed // lower = faster int[] curr_animation = new int[1]; boolean hor_flipped = false; aNPC(int _id){ id=_id; acc.x = random(-1,1); acc.y = random(-1,1); } void updateAndDrawMe(){ if(abs(acc.x)>medge){ curr_animation = side_anim; hor_flipped = false; if(acc.x>medge){ hor_flipped = true; } } if(abs(acc.y) > abs(acc.x)){ if(acc.y>medge){ curr_animation = front_anim; } if(acc.y<-medge){ curr_animation = back_anim; } } animtick = animate( int(pos.x), int(pos.y), 64,64, curr_animation, animtick, int(anim_speed/acc.mag())+1, hor_flipped ); if(pos.x > width || pos.x < 0){ acc.x *= -random(.9,1.1); } if(pos.y > height ||pos.y < 0){ acc.y *= -random(.9,1.1);} pos.x += acc.x; pos.y += acc.y; } } aNPC[] allNPCS; void createNPCS(){ allNPCS = new aNPC[55]; for(int i=0;i<55;i++){ allNPCS[i] = new aNPC(i); } } // --------------------------------------------- // --------------------------------------------- // ----- SPRITESHEET OPERATIONS ---------------- // --------------------------------------------- // --------------------------------------------- // the default sheet has 9 sprites in it in a 3x3 matrix // 0 - 1 - 2 // 3 - 4 - 5 // 6 - 7 - 8 int[] front_anim = {6,7,8,7}; int[] back_anim = {0,1,2,1}; int[] side_anim = {3,4,5,4}; int DIM_X = 3; // horizontal dimension of spritesheet int DIM_Y = 3; // vertical dimension of spritesheet // --------------------------------------------- // --------------------------------------------- // --------------------------------------------- PImage main_sheet; PImage[] sprites = new PImage[DIM_X*DIM_Y]; // --------------------------------------------- void init_spritesheet() { imageMode(CENTER); main_sheet = loadImage("slime_monster_spritesheet.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 = i/DIM_Y*H; sprites[i] = main_sheet.get(x, y, W, H); } } // --------------------------------------------- int animate(int _x, int _y, int _w, int _h, int[] _arr, int _anim_tick, int _anim_speed, boolean _hor_flipped) { 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 { _anim_tick = 0; } } return _anim_tick; } // --------------------------------------------- // --------------------------------------------- // ----- MAIN PART OF THE SCRIPT ---------------- // --------------------------------------------- // --------------------------------------------- // some variables to move an NPC float xpos = 128; float ypos = 128; float accx = 1; float accy = 1; // -------------------------------- void setup() { size(512,256); // set stage size init_spritesheet(); // initally setup the spritesheet noSmooth(); createNPCS(); createPlayer(); frameRate(60); } // -------------------------------- void draw() { background( 22,255,22 ); for(int i=0;i<allNPCS.length;i++){ allNPCS[i].updateAndDrawMe(); } if(keyPressed){ keyAction(); } playerOBJ.updateAndDrawMe(); playerOBJ.acc.x *= .8; playerOBJ.acc.y *= .8; } // -------------------------------- void keyAction(){ //println(keyCode); if(keyCode == 37){ playerOBJ.acc.x = -2; } // left if(keyCode == 39){ playerOBJ.acc.x = 2; } // right if(keyCode == 38){ playerOBJ.acc.y = -2; } // up if(keyCode == 40){ playerOBJ.acc.y = 2; } // down }
class implementation to create multiple npc’s with individual animation
The second example comes with an implementation of a more advanced, but necessary class logic. Each NPC is handled with a custom object, created in the background to store position, acceleration, animation tick and speed.
// --------------------------------------------- // --------------------------------------------- // ----- CUSTOM NPC CLASS ---------------- // --------------------------------------------- // --------------------------------------------- class aNPC{ int id = -1; PVector pos = new PVector(256,128); PVector acc = new PVector(); int animtick = 0; int anim_speed = int(random(3,7)); // animation speed // lower = faster aNPC(int _id){ id=_id; acc.x = random(-1,1); acc.y = random(-1,1); } void updateAndDrawMe(){ animtick = animate(int(pos.x),int(pos.y), 64,64, front_anim, animtick,anim_speed); if(pos.x > width || pos.x < 0){ acc.x *= -random(.9,1.1); } if(pos.y > height ||pos.y < 0){ acc.y *= -random(.9,1.1);} pos.x += acc.x; pos.y += acc.y; } } aNPC[] allNPCS; void createNPCS(){ allNPCS = new aNPC[55]; for(int i=0;i<55;i++){ allNPCS[i] = new aNPC(i); } } // --------------------------------------------- // --------------------------------------------- // ----- SPRITESHEET OPERATIONS ---------------- // --------------------------------------------- // --------------------------------------------- // the default sheet has 9 sprites in it in a 3x3 matrix // 0 - 1 - 2 // 3 - 4 - 5 // 6 - 7 - 8 int[] front_anim = {6,7,8,7}; int[] back_anim = {0,1,2,1}; int DIM_X = 3; // horizontal dimension of spritesheet int DIM_Y = 3; // vertical dimension of spritesheet // --------------------------------------------- // --------------------------------------------- // --------------------------------------------- PImage main_sheet; PImage[] sprites = new PImage[DIM_X*DIM_Y]; // --------------------------------------------- void init_spritesheet() { imageMode(CENTER); main_sheet = loadImage("slime_monster_spritesheet.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 = i/DIM_Y*H; sprites[i] = main_sheet.get(x, y, W, H); } } // --------------------------------------------- int animate(int _x, int _y, int _w, int _h, int[] _arr, int _anim_tick, int _anim_speed) { image(sprites[_arr[_anim_tick]], _x, _y, _w, _h); if (frameCount % _anim_speed == 0) { if (_anim_tick<_arr.length-1) { _anim_tick++; } else { _anim_tick = 0; } } return _anim_tick; } // --------------------------------------------- // --------------------------------------------- // ----- MAIN PART OF THE SCRIPT ---------------- // --------------------------------------------- // --------------------------------------------- // some variables to move an NPC float xpos = 128; float ypos = 128; float accx = 1; float accy = 1; // -------------------------------- void setup() { size(512,256); // set stage size init_spritesheet(); // initally setup the spritesheet noSmooth(); createNPCS(); frameRate(60); } // -------------------------------- void draw() { background( 22,255,22 ); for(int i=0;i<allNPCS.length;i++){ allNPCS[i].updateAndDrawMe(); } }
basic animation example with one npc
This example shows a simple application of animating through a spritesheet with a custom sheet order. The animation is then move across the stage with a simple bouncing algorithm.
DOWNLOAD THE SHEET HERE
// --------------------------------------------- // ---------SPRITESHEET SETUP ---------------------- // --------------------------------------------- // the default sheet has 9 sprites in it in a 3x3 matrix // 0 - 1 - 2 // 3 - 4 - 5 // 6 - 7 - 8 int[] front_anim = {6,7,8,7}; int[] back_anim = {0,1,2,1}; int anim_speed = 5; // animation speed // lower = faster int DIM_X = 3; // horizontal dimension of spritesheet int DIM_Y = 3; // vertical dimension of spritesheet // --------------------------------------------- // --------------------------------------------- // --------------------------------------------- PImage main_sheet; PImage[] sprites = new PImage[DIM_X*DIM_Y]; int anim_tick = 0; // --------------------------------------------- void init_spritesheet() { imageMode(CENTER); main_sheet = loadImage("slime_monster_spritesheet.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 = i/DIM_Y*H; sprites[i] = main_sheet.get(x, y, W, H); } } // --------------------------------------------- void animate(int _x, int _y, int _w, int _h, int[] _arr ) { image(sprites[_arr[anim_tick]], _x, _y, _w, _h); if (frameCount % anim_speed == 0) { if (anim_tick<_arr.length-1) { anim_tick++; } else { anim_tick = 0; } } } // --------------------------------------------- // --------------------------------------------- // --------------------------------------------- // some variables to move an NPC float xpos = 128; float ypos = 128; float accx = 1; float accy = 1; // -------------------------------- void setup() { size(256,256); // set stage size init_spritesheet(); // initally setup the spritesheet noSmooth(); frameRate(60); } // -------------------------------- void draw() { background( 22,255,22 ); animate(int(xpos),int(ypos), 64,64, front_anim); xpos += accx; ypos += accy; if(xpos > width || xpos < 0){ accx *= -random(.9,1.1); } if(ypos > height || ypos < 0){ accy *= -random(.9,1.1);} }