class Pulser { private PImage sprite; private Particle p; private Spring s; private float baseRadius, currRadius, pulseAmt; private float faceOffX, faceOffY; boolean pulsing, rendered; color c; int type; Pulser(int t, float rad, color col, float pulamt) { sprite = loadImage("pulser.png"); type = t; p = phys.makeParticle(1, random(width), random(height), 0); s = phys.makeSpring(pl.p, p, suckStrength, 1, pl.radius + rad*pulamt + 5); s.turnOff(); baseRadius = currRadius = rad; faceOffX = faceOffY = 0; pulseAmt = pulamt; c = col; pulsing = false; rendered = false; } Pulser(int t, float rad, color col) { sprite = loadImage("pulser.png"); type = t; p = phys.makeParticle(1, random(width), random(height), 0); s = phys.makeSpring(pl.p, p, 1, 1, pl.radius + rad*1.5 + 5); s.turnOff(); baseRadius = currRadius = rad; faceOffX = faceOffY = 0; pulseAmt = 1.5; c = col; pulsing = false; rendered = false; } // update methods void look() { if ( distFrom(pl) < 200 ) lookAt(pl.x(), pl.y()); else lookAt(x(), y()); } void lookAt(float mx, float my) { float x = x(); float y = y(); float hypo = dist(x, y, mx, my); float high = dist(x, y, x, my); float wide = dist(x, my, mx, my); if ( hypo == 0 ) faceOffX = faceOffY = 0; else { faceOffX = ( mx > x ? (baseRadius*0.3)*wide/hypo : -(baseRadius*0.3)*wide/hypo); faceOffY = ( my > y ? (baseRadius*0.3)*high/hypo : -(baseRadius*0.4)*high/hypo); } } void pulse() { if ( !pulsing ) { pulsing = true; currRadius = baseRadius * pulseAmt; } } void attach() { s.turnOn(); } void detach() { s.turnOff(); } void wallBounce() { int force = pulsing ? 8 : 2; if ( x() < currRadius ) setVelocity(force, vy()); if ( x() > width - currRadius ) setVelocity(-force, vy()); if ( y() < currRadius ) setVelocity(vx(), force); if ( y() > height - currRadius ) setVelocity(vx(), -force); } void pulseBounce(Pulser puls) { if ( puls == this ) return; if ( distFrom(puls) < currRadius + puls.currRadius + 5) { int force = pulsing ? 2 : 3; float cx = puls.x() - x(); float cy = puls.y() - y(); puls.setVelocity(cx/force, cy/force); } } void playerCollide() { float actualDist = distFrom(pl); float allowDist = pl.radius + currRadius + 5; if ( actualDist < allowDist ) { float cx = x() - pl.x(); float cy = y() - pl.y(); float diffDist = allowDist - actualDist; p.moveTo(x() + (cx*diffDist/actualDist), y() + (cy*diffDist/actualDist), 0); p.setVelocity(0, 0, 0); } } void setVelocity(float x, float y) { p.setVelocity(x, y, 0); dampVelocity(); } void dampVelocity() { if ( abs(vx()) > 10 ) p.setVelocity(vx()/2, vy(), 0); if ( abs(vy()) > 10 ) p.setVelocity(vx(), vy()/2, 0); } // state/relationship methods boolean isAttached() { return s.isOn(); } boolean isOffScreen() { if ( x() < -currRadius ) return true; if ( x() > width + currRadius ) return true; if ( y() < -currRadius ) return true; if ( y() > height + currRadius ) return true; return false; } boolean isDead() { return p.isDead(); } float distFrom(Pulser puls) { return dist(puls.x(), puls.y(), x(), y()); } float distFrom(Player pl) { return dist(pl.x(), pl.y(), x(), y()); } float getRadius() { return currRadius; } float x() { return p.position().x(); } float y() { return p.position().y(); } float vx() { return p.velocity().x(); } float vy() { return p.velocity().y(); } float age() { return p.age(); } void kill() { p.kill(); } // render section void renderSprite() { image(sprite, x() - (currRadius - baseRadius)/2, y() - (currRadius - baseRadius)/2, currRadius, currRadius); // update the current radius // update the current radius if ( pulsing ) currRadius *= 0.96; if ( currRadius < baseRadius ) { currRadius = baseRadius; pulsing = false; } rendered = true; } void render() { if ( useSmooth ) smooth(); float x = x(); float y = y(); float glow = currRadius * glowIntensity; // draw the avatar drawSept(255, 1, x, y, currRadius); pushMatrix(); translate(faceOffX, faceOffY, 0); drawEye(255, 1, x - baseRadius*0.55f, y, baseRadius/4); drawEye(255, 1, x + baseRadius*0.55f, y, baseRadius/4); drawMouth(255, 1, x, y, baseRadius); popMatrix(); if ( drawGlow ) { for (int i = 1; i < 5; i++) { drawSept(glow/i, 8, x, y, currRadius + i); drawSept(glow/i, 8, x, y, currRadius - i); pushMatrix(); translate(faceOffX, faceOffY, 0); drawEye(glow/i, 6, x - baseRadius*0.55f, y, baseRadius/4 + i); drawEye(glow/i, 6, x - baseRadius*0.55f, y, baseRadius/4 - i); drawEye(glow/i, 6, x + baseRadius*0.55f, y, baseRadius/4 + i); drawEye(glow/i, 6, x + baseRadius*0.55f, y, baseRadius/4 - i); drawMouth(glow/i, 6, x, y, baseRadius + i); drawMouth(glow/i, 6, x, y, baseRadius - i); popMatrix(); } } // update the current radius if ( pulsing ) currRadius *= 0.96; if ( currRadius < baseRadius ) { currRadius = baseRadius; pulsing = false; } rendered = true; } private void drawSept(float opacity, int weight, float x, float y, float r) { stroke(red(c), green(c), blue(c), opacity); strokeWeight(weight); beginShape(LINE_LOOP); vertex(x - r*0.98, y - yCoor(r, r*0.98f)); vertex(x - r*0.45f, y - yCoor(r, r*0.45f)); vertex(x + r*0.45f, y - yCoor(r, r*0.45f)); vertex(x + r*0.98f, y - yCoor(r, r*0.98f)); vertex(x + r*0.8f, y + yCoor(r, r*0.8f)); vertex(x, y + r); vertex(x - r*0.8f, y + yCoor(r, r*0.8f)); endShape(); } private void drawEye(float opacity, int weight, float x, float y, float r) { stroke(red(c), green(c), blue(c), opacity); strokeWeight(weight); beginShape(LINE_LOOP); vertex(x - r*0.95f, y - yCoor(r, r*0.95f)); vertex(x, y - r); vertex(x + r*0.95f, y - yCoor(r, r*0.95f)); vertex(x + r*0.6f, y + yCoor(r, r*0.6f)); vertex(x - r*0.6f, y + yCoor(r, r*0.6f)); endShape(); float eyeY = faceOffX/3 > 0 ? ( (yCoor(r, r*0.95f) - r) / r*0.95 ) * faceOffX/3 + r : ( -(yCoor(r, r*0.95f) - r) / r*0.95 ) * faceOffX/2 + r; line(x + faceOffX/3, y - eyeY, x + faceOffX/3, y + yCoor(r, r*0.6f)); } private void drawMouth(float opacity, int weight, float x, float y, float r) { stroke(red(c), green(c), blue(c), opacity); strokeWeight(weight); beginShape(LINE_LOOP); vertex(x - r*0.65f, y + r*0.35f); vertex(x + r*0.65f, y + r*0.35f); vertex(x + r*0.5625f, y + r*0.55f); vertex(x, y + r*0.8f); vertex(x - r*0.5625f, y + r*0.55f); endShape(); } private float yCoor(float r, float x) { return sqrt(pow(r, 2) - pow(x, 2)); } }