class Player { Particle p; float radius, speed, forceRadius; boolean up, right, down, left, suck, blow; private float aimStart, aimEnd, aimX, aimY; private boolean sucking, blowing; Player (Particle part, float r, float s) { p = part; p.makeFixed(); radius = r; forceRadius = r*6; speed = s; aimStart = 0; aimEnd = TWO_PI; up = right = down = left = false; } 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 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 aim(float x, float y) { aimX = x() + x*radius; aimY = y() - y*radius; if ( screenStats ) { textSize(12); text("(" + aimX + ", " + aimY + ")", x() + radius, y() + radius); } if ( x == 0 && y == 0 ) aimStart = 0; else aimStart = ( x >= 0 ? PI - atan(y/x) : TWO_PI - atan(y/x) ); aimEnd = aimStart + TWO_PI; float aimSize = constrain( sqrt(pow(x, 2) + pow(y, 2)), 0, 1 ); // to increase or decrease the size of the smallest angle // change the value in the parens aimStart += (3*PI/4)*aimSize; aimEnd -= (3*PI/4)*aimSize; if ( screenStats ) { textSize(24); text("aimStart: " + aimStart + ", aimEnd: " + aimEnd + ", aimAngle/2: " + ((aimEnd - aimStart)/2), 10, height - 10); } } void suck(boolean b) { sucking = b; } void keySuck() { suck(suck); } boolean isSucking() { return sucking; } void blow(boolean b) { blowing = b; } void keyBlow() { blow(blow); } boolean isBlowing() { return blowing; } boolean withinRange(Pulser puls) { float sideA = puls.distFrom(this); float sideB = dist(aimX, aimY, puls.x(), puls.y()); float sideC = dist(x(), y(), aimX, aimY); float angleB = ( sideC > 0 ) ? acos( (pow(sideA, 2) + pow(sideC, 2) - pow(sideB, 2)) / ( 2 * sideA * sideC ) ) : 0; float aimAngle = aimEnd - aimStart; if ( screenStats ) { textSize(12); text("angleB: " + angleB, puls.x() + puls.getRadius(), puls.y() + puls.getRadius()); } boolean closeEnough = sideA < forceRadius + puls.getRadius(); boolean inAngle = angleB < aimAngle/2; return closeEnough && inAngle; } void render() { noStroke(); if ( useSmooth ) smooth(); // suck waves if ( sucking ) { fill(255, 255, 0, 64); arc(x(), y(), forceRadius, forceRadius, aimStart, aimEnd); } // blow waves if ( blowing ) { fill(0, 255, 0, 64); arc(x(), y(), forceRadius, forceRadius, aimStart, aimEnd); } // the player fill(0, 0, 255); ellipse(x(), y(), radius, radius); // the aim arc fill(255, 0, 0); arc(x(), y(), radius, radius, aimStart, aimEnd); } void speedUp() { speed = constrain(speed+1, 1, 10); println("Speed increased to " + speed + "."); } void slowDown() { speed = constrain(speed-1, 1, 10); println("Speed decreased to " + speed + "."); } float x() { return p.position().x(); } float y() { return p.position().y(); } }