class Player { Particle p; float radius, speed, forceRadius; boolean up, right, down, left, suck, blow; // for keyboard control private boolean sucking, blowing; private int suckCnt, blowCnt; private int div = 800; // to weaken the blowing/sucking on enemies private Vector blowRings; Player () { p = phys.makeParticle(1, width/2, height/2, 0); p.makeFixed(); radius = playerSize; forceRadius = radius*8; speed = playerSpeed; up = right = down = left = false; suckCnt = blowCnt = 0; blowRings = new Vector(5, 5); } void keyMove() { float moveAmt; if ( up ) { moveAmt = min(y() - 5, speed); p.moveBy(0, -moveAmt, 0); } if ( down ) { moveAmt = min(height - y() - 5, speed); p.moveBy(0, moveAmt, 0); } if ( left ) { moveAmt = min(x() - 5, speed); p.moveBy(-moveAmt, 0, 0); } if ( right ) { moveAmt = min(width - x() - 5, speed); p.moveBy(moveAmt, 0, 0); } } void reset() { p.moveTo(width/2, height/2, 0); sucking = false; blowing = false; } void move(float x, float y) { p.moveBy(x, y, 0); if ( x() < radius ) p.moveTo(radius, y(), 0); else if ( x() > width - radius ) p.moveTo(width - radius, y(), 0); if ( y() < radius ) p.moveTo(x(), radius, 0); else if ( y() > height - radius ) p.moveTo(x(), height - radius, 0); } void interact(Pulser puls) { float d = dist(x(), y(), puls.x(), puls.y()); if ( d > forceRadius + puls.radius() || puls.caught ) return; if ( sucking ) { puls.attach(); if ( puls.attachedFor() > 5 ) puls.setMood(VORACIOUS); else puls.setMood(HAPPY); } else if ( puls.isAttached() ) { puls.detach(); if ( puls.mood() == VORACIOUS ) puls.addVelocity(puls.x() - x(), puls.y() - y()); } if ( blowRings.size() > 0 && d < ((Ring)blowRings.firstElement()).radius() + puls.radius() ) { float cx = puls.x() - x(); float cy = puls.y() - y(); if ( puls.mood() == VORACIOUS ) puls.setVelocity(2*blowStrength*cx, 2*blowStrength*cy); else puls.setVelocity(blowStrength*cx, blowStrength*cy); puls.setMood(HAPPY); } } void interact(Deathskull sk) { float d = dist(x(), y(), sk.x(), sk.y()); if ( d > forceRadius + 30 ) return; if ( sucking ) sk.setVelocity( (x() - sk.x())/div, (y() - sk.y())/div ); if ( isBlowing() && d < ((Ring)blowRings.firstElement()).radius() + 30 ) sk.setVelocity( (sk.x() - x())/div, (sk.y() - y())/div ); if ( d < radius + 35 ) { float cx = sk.x() - x(); float cy = sk.y() - y(); float mult = ((radius + 30 - d)/d); sk.moveTo(sk.x() + (cx*mult*0.05f), sk.y() + (cy*mult*0.05)); p.moveTo(x() - (cx*mult), y() - (cx*mult), 0); } } void interact(SuckBlow sb) { float d = dist(x(), y(), sb.x(), sb.y()); if ( d > forceRadius + 30 ) return; if ( sucking ) sb.setVelocity( (x() - sb.x())/div, (y() - sb.y())/div ); if ( isBlowing() && d < ((Ring)blowRings.firstElement()).radius() + 30 ) sb.setVelocity( (sb.x() - x())/div, (sb.y() - y())/div ); if ( d < radius + 35 ) { float cx = sb.x() - x(); float cy = sb.y() - y(); float mult = ((radius + 30 - d)/d); sb.moveTo(sb.x() + (cx*mult*0.05f), sb.y() + (cy*mult*0.05f)); p.moveTo(x() - (cx*mult), y() - (cx*mult), 0); } } void suck(boolean b) { if ( !blowing && b ) sucking = true; else sucking = false; } void keySuck() { suck(suck); } boolean isSucking() { return sucking; } void blow(boolean b) { if ( !blowing && b ) { blowRings.add(new Ring()); } blowing = b; } void keyBlow() { blow(blow); } boolean isBlowing() { return blowRings.size() > 0; } void render() { noFill(); stroke(255, 255, 0); // suck waves if ( sucking ) { float rad = forceRadius * cos((suckCnt%30)*PI/60); ellipse(x(), y(), rad, rad); suckCnt++; } else suckCnt = 0; // blow waves 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(); } } } // the player ellipse(x(), y(), radius, radius); } float x() { return p.position().x(); } float y() { return p.position().y(); } class Ring { boolean finished; private float radius, endRadius, step; Ring() { radius = playerSize; endRadius = forceRadius; step = 10; } float radius() { return radius; } void update() { radius += step; } void render() { ellipse(x(), y(), radius, radius); if ( radius >= endRadius ) finished = true; } } }