class SuckBlow { private Particle p; private boolean sucking, blowing; private int suckCnt, blowCnt, restCnt, forceRadius; private float hitPoints; private Vector blowRings; private Iterator rIter; SuckBlow() { p = phys.makeParticle(1, random(40, width-40), random(40, height-40), 0); sucking = blowing = false; suckCnt = blowCnt = restCnt = 0; forceRadius = 180; hitPoints = 200; blowRings = new Vector(5, 5); } void update() { if ( suckCnt == 0 && !blowing && restCnt/frameRate > 5 ) { sucking = random(1) > 0.99 ? true : false; if ( sucking ) restCnt = 0; } if ( blowCnt == 0 && !sucking && restCnt/frameRate > 5 ) { blowing = random(1) > 0.98 ? true : false; if ( blowing ) restCnt = 0; } if ( suckCnt/frameRate > 3 ) { sucking = false; suckCnt = 0; } if ( blowCnt/frameRate > 3 ) { blowing = false; blowCnt = 0; } if ( blowing && beat.isKick() ) { blowRings.add(new Ring()); } } void interact(Pulser puls) { float d = dist(puls.x(), puls.y(), x(), y()); if ( sucking ) { float cx = x() - puls.x(); float cy = y() - puls.y(); puls.detach(); puls.addVelocity(cx/200, cy/200); if ( d < puls.radius() + 30 && puls.mood() != VORACIOUS ) { puls.points = -50; score -= 50; puls.kill(); } } else if ( blowRings.size() > 0 && d < ((Ring)blowRings.firstElement()).radius() + puls.radius() ) { float cx = puls.x() - x(); float cy = puls.y() - y(); puls.detach(); puls.setVelocity(cx/3, cy/3); } } 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.caught; } boolean isSucking() { return sucking; } boolean isBlowing() { return blowRings.size() > 0 || blowing; } boolean isDead() { return p.isDead(); } float x() { return p.position().x(); } float y() { return p.position().y(); } void render() { float glow = glowIntensity; noFill(); stroke(255, 0, 255); pushMatrix(); translate(x(), y()); if ( sucking ) { // suck waves float rad = constrain(forceRadius * cos((suckCnt%30)*PI/60), 30, forceRadius); body(rad); suckFace(); suckCnt++; } else if ( isBlowing() ) { for (int i = 0; i < blowRings.size(); i++) { Ring tmp = (Ring)blowRings.get(i); if ( tmp.finished ) { blowRings.remove(i); i--; } else { tmp.update(); tmp.render(); } } blowFace(); blowCnt++; } else { restFace(); restCnt++; } if ( drawGlow ) { pushMatrix(); for (int i = 1; i < 7; i++) { stroke(255, 0, 255, glow/i); scale(0.98f); if ( sucking ) suckFace(); else if ( blowing ) blowFace(); else restFace(); } popMatrix(); pushMatrix(); for (int i = 1; i < 7; i++) { stroke(255, 0, 255, glow/i); scale(1.02f); if ( sucking ) suckFace(); else if ( blowing ) blowFace(); else restFace(); } popMatrix(); } popMatrix(); } private void suckFace() { // outline body(30); //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 blowFace() { // outline body(30); //left eye pushMatrix(); translate(-17, 0); rotate(PI/5); pent(6); line(4, -5, 7, -4.5); rotate(-PI/5); line(-4.5, -1.5, 5, 1.5); popMatrix(); //right eye pushMatrix(); translate(17, 0); rotate(-PI/5); pent(6); line(-4, -5, -7, -4.5); rotate(PI/5); line(-5, 1.5, 4.5, -1.5); popMatrix(); //mouth pushMatrix(); translate(0, 14); pent(6); line(-5, 2, -10, 2); line(5, 2, 10, 2); 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) { 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); } class Ring { boolean finished; private float radius, endRadius, step; Ring() { radius = 30; endRadius = forceRadius; step = 10; } float radius() { return radius; } void update() { radius += step; } void render() { body(radius); if ( radius >= endRadius ) finished = true; } } }