class Sucker { private Particle p; private boolean sucking; private int suckCnt, restCnt, forceRadius; private float cfr; private float hitPoints; private color c, g; Sucker() { p = phys.makeParticle(1, random(40, width-40), random(40, height-40), 0); sucking = false; suckCnt = restCnt = 0; cfr = forceRadius = 180; hitPoints = 200; c = sbColor; g = sbGlow; } void update() { if ( suckCnt == 0 && restCnt/frameRate > 3 ) { sucking = true; restCnt = 0; } if ( suckCnt/frameRate > 5 ) { sucking = false; suckCnt = 0; } } void interact(Pulser puls) { float d = dist(puls.x(), puls.y(), x(), y()); float vx = (x() - puls.x())/d; float vy = (y() - puls.y())/d; puls.detach(); puls.addVelocity(vx, vy); if ( d < puls.radius() + radius() + 10 && puls.mood() != VORACIOUS ) { switch( puls.type ) { case KICK: puls.score(-50); break; case SNARE: puls.score(-75); break; case HAT: puls.score(-100); break; } puls.kill(); } } void damage(float amt) { if ( amt > 0 ) { hitPoints -= amt; println("SuckBlow took " + amt + " points of damage."); } if ( hitPoints < 0 ) p.kill(); } void kill() { p.kill(); } void setVelocity(float x, float y) { p.setVelocity(x, y, 0); } void addVelocity(float x, float y) { p.addVelocity(x, y, 0); } void moveTo(float x, float y) { p.moveTo(x, y, 0); } boolean isOffScreen() { if ( x() < -30 ) return true; if ( x() > width + 30 ) return true; if ( y() < -30 ) return true; if ( y() > height + 30 ) return true; return false; } boolean awareOf(Pulser puls) { return dist(x(), y(), puls.x(), puls.y()) < (forceRadius() + puls.radius()) && puls.isFree(); } boolean isSucking() { return sucking; } boolean isDead() { return p.isDead(); } int radius() { return sucking ? 50 : 30; } float forceRadius() { return cfr; } float x() { return p.position().x(); } float y() { return p.position().y(); } void render() { float glow = glowIntensity; noFill(); pushMatrix(); translate(x(), y()); if ( drawGlow ) { pushMatrix(); for (int i = 1; i < 10; i++) { stroke(red(g), green(g), blue(g), glow/i); scale(0.97f); if ( sucking ) suckFace(); else restFace(); } popMatrix(); pushMatrix(); for (int i = 1; i < 10; i++) { stroke(red(g), green(g), blue(g), glow/i); scale(1.03f); if ( sucking ) suckFace(); else restFace(); } popMatrix(); } stroke(c); if ( sucking ) { // suck waves cfr = constrain(forceRadius * cos((suckCnt%30)*PI/60), 50, forceRadius); body(cfr); suckFace(); suckCnt++; } else { restFace(); restCnt++; } popMatrix(); } private void suckFace() { // outline body(50); //left eye pushMatrix(); translate(-17, 0); pent(6); line(-4.5, -1.5, 5, 1.5); line(4, -5, 6, -7); popMatrix(); //right eye pushMatrix(); translate(17, 0); pent(6); line(-5, 1.5, 4.5, -1.5); line(-4, -5, -6, -7); //mouth popMatrix(); pushMatrix(); translate(0, 14); rotate(PI); pent(12); line(-17, 4, -11, 4); line(11, 4, 17, 4); line(-6, 8, 6, 8); line(-8, -7, 8, -7); popMatrix(); } private void restFace() { // outline body(30); //left eye pushMatrix(); translate(-17, 0); rotate(PI); pent(6); line(0, 6, 0, -5); popMatrix(); //right eye pushMatrix(); translate(17, 0); rotate(PI); pent(6); line(0, 6, 0, -5); popMatrix(); // mouth line(-10, 15, 10, 15); } private void body(float r) { if ( sucking ) { float a = 0.5; float b = 0.866025404; float c = 0.183012702; float d = 0.683012702; beginShape(); vertex(-r, 0); vertex(r*-d , r*-c); vertex(r*-b, r*-a); vertex(r*-a, r*-a); vertex(r*-a, r*-b); vertex(r*-c, r*-d); vertex(0, -r); vertex(r*c, r*-d); vertex(r*a, r*-b); vertex(r*a, r*-a); vertex(r*b, r*-a); vertex(r*d, r*-c); vertex(r, 0); vertex(r*d, r*c); vertex(r*b, r*a); vertex(r*a, r*a); vertex(r*a, r*b); vertex(r*c, r*d); vertex(0, r); vertex(r*-c, r*d); vertex(r*-a, r*b); vertex(r*-a, r*a); vertex(r*-b, r*a); vertex(r*-d, r*c); endShape(CLOSE); } else { beginShape(); vertex(0, r); vertex(r*-0.6666f, r*0.7453f); vertex(-r, r*0.2f); vertex(r*-0.9f, r*-0.4333f); vertex(r*-0.4333f, r*-0.9163f); vertex(r*0.4333f, r*-0.9163f); vertex(r*0.9f, r*-0.4333f); vertex(r, r*0.2f); vertex(r*0.6666f, r*0.7453f); endShape(CLOSE); } } }