//by: Nolan Grant, ID: 991412483, date: 04, October, 2017 //use arrow keys to control the shark, up to accelerate, left or right to rotate //the shark is chill, it won't eat the other fish. //shark float sharkVectorPivotX = 200; float sharkVectorPivotY = 190; float sharkVectorHandleX = 200; float sharkVectorHandleY = 215; float rotation = 0; float sharkThrustValue = 0.0; float thrustBoundary = 1.0; float thrustComponentX = (sharkVectorHandleX-sharkVectorPivotX)/25.0; float thrustComponentY = (sharkVectorHandleY-sharkVectorPivotY)/25.0; boolean isUpPressed = false; boolean isLeftPressed = false; boolean isRightPressed = false; int sharkBaseColour = 127; float tailSpeed = 0.002; float leftRotationMomentum=0.0; float RightRotationMomentum=0.0; float heading= (atan((sharkVectorPivotY-sharkVectorHandleY)/(sharkVectorPivotX-sharkVectorHandleX))); //fish 1/A float fishAVectorPivotX = random(20, 380); float fishAVectorPivotY = random(20, 380); float fishARotation = random(0, PI*2.0); float fishANoiseTime = random(0, 1000000); //fish 2/B float fishBVectorPivotX = random(20, 380); float fishBVectorPivotY = random(20, 380); float fishBRotation = random(0, PI*2.0); float fishBNoiseTime = random(0, 1000000); //fish 3/C float fishCVectorPivotX = random(20, 380); float fishCVectorPivotY = random(20, 380); float fishCRotation = random(0, PI*2.0); float fishCNoiseTime = random(0, 1000000); //fish 4/D float fishDVectorPivotX = random(20, 380); float fishDVectorPivotY = random(20, 380); float fishDRotation = random(0, PI*2.0); float fishDNoiseTime = random(0, 1000000); //fish 5/E float fishEVectorPivotX = random(20, 380); float fishEVectorPivotY = random(20, 380); float fishERotation = random(0, PI*2.0); float fishENoiseTime = random(0, 1000000); //fish 6/F float fishFVectorPivotX = random(20, 380); float fishFVectorPivotY = random(20, 380); float fishFRotation = random(0, PI*2.0); float fishFNoiseTime = random(0, 1000000); //fish 7/G float fishGVectorPivotX = random(20, 380); float fishGVectorPivotY = random(20, 380); float fishGRotation = random(0, PI*2.0); float fishGNoiseTime = random(0, 1000000); //fish 8/H float fishHVectorPivotX = random(20, 380); float fishHVectorPivotY = random(20, 380); float fishHRotation = random(0, PI*2.0); float fishHNoiseTime = random(0, 1000000); //fish 9/I float fishIVectorPivotX = random(20, 380); float fishIVectorPivotY = random(20, 380); float fishIRotation = random(0, PI*2.0); float fishINoiseTime = random(0, 1000000); //fish 10/J float fishJVectorPivotX = random(20, 380); float fishJVectorPivotY = random(20, 380); float fishJRotation = random(0, PI*2.0); float fishJNoiseTime = random(0, 1000000); //fish 11/K float fishKVectorPivotX = random(20, 380); float fishKVectorPivotY = random(20, 380); float fishKRotation = random(0, PI*2.0); float fishKNoiseTime = random(0, 1000000); //fish 12/L float fishLVectorPivotX = random(20, 380); float fishLVectorPivotY = random(20, 380); float fishLRotation = random(0, PI*2.0); float fishLNoiseTime = random(0, 1000000); //fish 13/M float fishMVectorPivotX = random(20, 380); float fishMVectorPivotY = random(20, 380); float fishMRotation = random(0, PI*2.0); float fishMNoiseTime = random(0, 1000000); //fish 14/N float fishNVectorPivotX = random(20, 380); float fishNVectorPivotY = random(20, 380); float fishNRotation = random(0, PI*2.0); float fishNNoiseTime = random(0, 1000000); void setup() { size(400, 400); frameRate(60); } void draw() { background(0, 0, 200); drawBackDrop(); drawBottomFishGroup(); drawShark(); drawTopFishGroup(); sharkRotationControl(); } void sharkRotationControl() { //determines how the shark will rotate each frame //rotation speed has a minimum value of (rotationValue), but will increase for up to 30 frames if the key is not released or the opposite key pressed float rotationValue=(PI/128.0); float maxRotationMomentum=(PI/256.0); if (isLeftPressed==true) { rotation=rotation+(rotationValue)+leftRotationMomentum; leftRotationMomentum=leftRotationMomentum+(PI/(64.0*120.0)); if (leftRotationMomentum>maxRotationMomentum) { leftRotationMomentum=maxRotationMomentum; } } if (isLeftPressed==false) { leftRotationMomentum=0.0; } if (isRightPressed==true) { rotation=rotation-(rotationValue)-RightRotationMomentum; RightRotationMomentum=RightRotationMomentum+(PI/(64.0*120.0)); if (RightRotationMomentum>maxRotationMomentum) { RightRotationMomentum=maxRotationMomentum; } } if (isRightPressed==false) { RightRotationMomentum=0.0; } } void drawBackDrop() { //creates a backdrop of concentric circles with pulsing size for (int i = 0; i < 20; i++) { int fillColour = 45+(i*9); stroke(0, 0, fillColour-8, 255); float radius = sin(millis()*.001)*10+600-(i*30.0); fill(0, 0, fillColour, 255); ellipse(width/2.0, height/2.0, radius, radius); } } void keyPressed() { //determines if left arrow key has been pressed if (key == CODED) { if (keyCode == LEFT) { isLeftPressed=true; isRightPressed=false; } else { } //determines if right arrow key has been pressed if (key == CODED) { if (keyCode == RIGHT) { isRightPressed=true; isLeftPressed=false; } else { } //increases shark's forward thrust if up arrow key is pressed if (key == CODED) { if (keyCode == UP) { isUpPressed=true; } if (isUpPressed==true) { sharkThrustValue=3.0; } else { } } } } } void keyReleased() { if (key == CODED) { if (keyCode == UP) { isUpPressed=false; sharkThrustValue=1.0; } } if (key == CODED) { if (keyCode == LEFT) { isLeftPressed=false; } } if (key == CODED) { if (keyCode == RIGHT) { isRightPressed=false; } } } void drawShark() { //right eye ellipseMode(CENTER); stroke(255); strokeWeight(.5); fill(0); float eyesRX = sin(rotation-0.155)*-85.34+sharkVectorPivotX; float eyesRY = cos(rotation-0.155)*-85.34+sharkVectorPivotY; ellipse(eyesRX, eyesRY, 8, 8 ); //left eye float eyesLX = sin(rotation+0.155)*-85.34+sharkVectorPivotX; float eyesLY = cos(rotation+0.155)*-85.34+sharkVectorPivotY; ellipse(eyesLX, eyesLY, 8, 8 ); //nose stroke(sharkBaseColour); fill(sharkBaseColour); strokeWeight(2); float noseAX = sin(rotation-0.0261799)*-111.04+sharkVectorPivotX; float noseAY = cos(rotation-0.0261799)*-111.04+sharkVectorPivotY; float noseDX = sin(rotation+0.0261799)*-111.04+sharkVectorPivotX; float noseDY = cos(rotation+0.0261799)*-111.04+sharkVectorPivotY; float noseBX = sin(rotation-0.139626)*-93.9+sharkVectorPivotX; float noseBY = cos(rotation-0.139626)*-93.9+sharkVectorPivotY; float noseCX = sin(rotation+0.139626)*-93.9+sharkVectorPivotX; float noseCY = cos(rotation+0.139626)*-93.9+sharkVectorPivotY; quad(noseAX, noseAY, noseBX, noseBY, noseCX, noseCY, noseDX, noseDY); //head stroke(sharkBaseColour); fill(sharkBaseColour); float headAX = noseCX; float headAY = noseCY; float headBX = noseBX; float headBY = noseBY; float headCX = sin(rotation-0.349066)*-58.52+sharkVectorPivotX; float headCY = cos(rotation-0.349066)*-58.52+sharkVectorPivotY; float headDX = sin(rotation+0.349066)*-58.52+sharkVectorPivotX; float headDY = cos(rotation+0.349066)*-58.52+sharkVectorPivotY; quad(headAX, headAY, headBX, headBY, headCX, headCY, headDX, headDY); //torso stroke(sharkBaseColour); fill(sharkBaseColour); float torsoAX = headDX; float torsoAY = headDY; float torsoBX = headCX; float torsoBY = headCY; float torsoCX = sin(rotation-0.6038839)*-35.23+sharkVectorPivotX; float torsoCY = cos(rotation-0.6038839)*-35.23+sharkVectorPivotY; float torsoDX = sin(rotation+0.6038839)*-35.23+sharkVectorPivotX; float torsoDY = cos(rotation+0.6038839)*-35.23+sharkVectorPivotY; quad(torsoAX, torsoAY, torsoBX, torsoBY, torsoCX, torsoCY, torsoDX, torsoDY); //right fin stroke(sharkBaseColour); fill(sharkBaseColour); float rfinAX = torsoBX; float rfinAY = torsoBY; float rfinBX = sin(rotation-1.199041)*-55.54+sharkVectorPivotX; float rfinBY = cos(rotation-1.199041)*-55.54+sharkVectorPivotY; float rfinCX = sin(rotation-1.35263)*-55.32+sharkVectorPivotX; float rfinCY = cos(rotation-1.35263)*-55.32+sharkVectorPivotY; float rfinDX = torsoCX; float rfinDY = torsoCY; //right fin shadow stroke(94); line(rfinAX, rfinAY, rfinDX, rfinDY); //left fin stroke(sharkBaseColour); fill(sharkBaseColour); float lfinAX = torsoAX; float lfinAY = torsoAY; float lfinBX = sin(rotation+1.199041)*-55.54+sharkVectorPivotX; float lfinBY = cos(rotation+1.199041)*-55.54+sharkVectorPivotY; float lfinCX = sin(rotation+1.35263)*-55.32+sharkVectorPivotX; float lfinCY = cos(rotation+1.35263)*-55.32+sharkVectorPivotY; float lfinDX = torsoDX; float lfinDY = torsoDY; //left fin shadow stroke(94); line(lfinAX, lfinAY, lfinDX, lfinDY); //changes location of vertices at the fin tips to make the fin appear to dip when the shark turns in that direction //left turn if (isLeftPressed==true) { isRightPressed=false; lfinBX = sin(rotation+1.199041)*-46.54+sharkVectorPivotX; lfinBY = cos(rotation+1.199041)*-46.54+sharkVectorPivotY; lfinCX = sin(rotation+1.35263)*-46.32+sharkVectorPivotX; lfinCY = cos(rotation+1.35263)*-46.32+sharkVectorPivotY; noStroke(); quad(lfinAX, lfinAY, lfinBX, lfinBY, lfinCX, lfinCY, lfinDX, lfinDY); } else { noStroke(); quad(lfinAX, lfinAY, lfinBX, lfinBY, lfinCX, lfinCY, lfinDX, lfinDY); } //right turn if (isRightPressed==true) { isLeftPressed=false; rfinBX = sin(rotation-1.199041)*-46.54+sharkVectorPivotX; rfinBY = cos(rotation-1.199041)*-46.54+sharkVectorPivotY; rfinCX = sin(rotation-1.35263)*-46.32+sharkVectorPivotX; rfinCY = cos(rotation-1.35263)*-46.32+sharkVectorPivotY; noStroke(); quad(rfinAX, rfinAY, rfinBX, rfinBY, rfinCX, rfinCY, rfinDX, rfinDY); } else { noStroke(); quad(rfinAX, rfinAY, rfinBX, rfinBY, rfinCX, rfinCY, rfinDX, rfinDY); } //small fins near base of tail float tinyFinAX = sin(rotation)*4.54+sharkVectorPivotX; float tinyFinAY = cos(rotation)*4.54+sharkVectorPivotY; float tinyFinBX = sin(rotation+2.64346)*-34.54+sharkVectorPivotX; float tinyFinBY = cos(rotation+2.64346)*-34.54+sharkVectorPivotY; float tinyFinCX = sin(rotation-2.64346)*-34.54+sharkVectorPivotX; float tinyFinCY = cos(rotation-2.64346)*-34.54+sharkVectorPivotY; fill(sharkBaseColour); noStroke(); triangle (tinyFinAX, tinyFinAY, tinyFinBX, tinyFinBY, tinyFinCX, tinyFinCY); //tail: Is made of 100 overlapping circles that whip at a rate linked to its speed as the shark moves for (int i = 0; i < 100; i++) { float tailSpeed = .002 * sharkThrustValue; float whipCoefficient = 111.0-i; float segmentRadius = 1.0+i; float tailSegmentX = (sin(rotation+(sin(millis()*tailSpeed)*(PI/whipCoefficient)))*segmentRadius+sharkVectorPivotX); float tailSegmentY = (cos(rotation+(sin(millis()*tailSpeed)*(PI/whipCoefficient)))*segmentRadius+sharkVectorPivotY); float sizeX = 30-i/3.5; float sizeY = 30-i/3.5; fill(sharkBaseColour); noStroke(); ellipse(tailSegmentX, tailSegmentY, sizeX, sizeY); } //finds the pivot/root segment center of the fourth from last ellipse that makes up the tail //i=100-4 or 96, substitute in 96 for i as it would appear in the for loop float tailSpeed = .002 * sharkThrustValue; float whipCoefficient = 111.0-96; float rootSegmentRadius = 1.0+96; float rootTailSegmentX = (sin(rotation+(sin(millis()*tailSpeed)*(PI/whipCoefficient)))*rootSegmentRadius+sharkVectorPivotX); float rootTailSegmentY = (cos(rotation+(sin(millis()*tailSpeed)*(PI/whipCoefficient)))*rootSegmentRadius+sharkVectorPivotY); //finds the terminal/handle segment center of the last ellipse that makes up the tail //i=100-0 or 100, substitute in 0 for i as it would appear in the for loop float terminalWhipCoefficient = 111.0-100; float terminalSegmentRadius = 1.0+100; float terminalTailSegmentX = (sin(rotation+(sin(millis()*tailSpeed)*(PI/terminalWhipCoefficient)))*terminalSegmentRadius+sharkVectorPivotX); float terminalTailSegmentY = (cos(rotation+(sin(millis()*tailSpeed)*(PI/terminalWhipCoefficient)))*terminalSegmentRadius+sharkVectorPivotY); //shark tail fins: creates triangles with 2 points parented to the root/pivot and terminal/handle points and 1 point that rotates around the terminal point with the tail whip //bottom fin stroke(sharkBaseColour); strokeWeight(.5); fill(sharkBaseColour); triangle(terminalTailSegmentX, terminalTailSegmentY, rootTailSegmentX, rootTailSegmentY, (sin(rotation+(sin((millis())*tailSpeed)))*25.0)+terminalTailSegmentX, (cos(rotation+(sin((millis())*tailSpeed)))*25.0)+terminalTailSegmentY); //top fin fill(sharkBaseColour); triangle(terminalTailSegmentX, terminalTailSegmentY, rootTailSegmentX, rootTailSegmentY, (sin(rotation+((sin((millis())*tailSpeed)))+(sin((millis())*tailSpeed)))*35.0)+terminalTailSegmentX, (cos(rotation+((sin((millis())*tailSpeed)))+(sin((millis())*tailSpeed)))*35.0)+terminalTailSegmentY); //lower body noStroke(); fill(sharkBaseColour); float tailX=sin(rotation+0.25)*39.0+sharkVectorPivotX; float tailY=cos(rotation+0.25)*39.0+sharkVectorPivotY; float tailBX=sin(rotation-0.25)*39.0+sharkVectorPivotX; float tailBY=cos(rotation-0.25)*39.0+sharkVectorPivotY; quad(torsoDX, torsoDY, torsoCX, torsoCY, tailX, tailY, tailBX, tailBY); //dorsal fin stroke(94); strokeWeight(1); fill(sharkBaseColour); float dFinAX=sin(rotation)*-35.0+sharkVectorPivotX; float dFinAY=cos(rotation)*-35.0+sharkVectorPivotY; float dFinBX=sin(rotation-0.3036873)*-16.76+sharkVectorPivotX; float dFinBY=cos(rotation-0.3036873)*-16.76+sharkVectorPivotY; float dFinCX=sin(rotation)*5.0+sharkVectorPivotX; float dFinCY=cos(rotation)*5.0+sharkVectorPivotY; float dFinDX=sin(rotation+0.3036873)*-16.76+sharkVectorPivotX; float dFinDY=cos(rotation+0.3036873)*-16.76+sharkVectorPivotY; quad(dFinAX, dFinAY, dFinBX, dFinBY, dFinCX, dFinCY, dFinDX, dFinDY); //front gills stroke(64); strokeWeight(1); float gillAX = sin(rotation-0.143117)*-73.72+sharkVectorPivotX; float gillAY = cos(rotation-0.143117)*-73.72+sharkVectorPivotY; float gillBX = sin(rotation-0.2408554)*-76.2+sharkVectorPivotX; float gillBY = cos(rotation-0.2408554)*-76.2+sharkVectorPivotY; line(gillAX, gillAY, gillBX, gillBY); float gillCX = sin(rotation+0.143117)*-73.72+sharkVectorPivotX; float gillCY = cos(rotation+0.143117)*-73.72+sharkVectorPivotY; float gillDX = sin(rotation+0.2408554)*-76.2+sharkVectorPivotX; float gillDY = cos(rotation+0.2408554)*-76.2+sharkVectorPivotY; line(gillCX, gillCY, gillDX, gillDY); //middle gills float gillIX = sin(rotation-0.1780236)*-68.07+sharkVectorPivotX; float gillIY = cos(rotation-0.1780236)*-68.07+sharkVectorPivotY; float gillJX = sin(rotation-0.26229)*-71.40+sharkVectorPivotX; float gillJY = cos(rotation-0.26229)*-71.40+sharkVectorPivotY; line(gillIX, gillIY, gillJX, gillJY); float gillKX = sin(rotation+0.1780236)*-68.07+sharkVectorPivotX; float gillKY = cos(rotation+0.1780236)*-68.07+sharkVectorPivotY; float gillLX = sin(rotation+0.26229)*-71.40+sharkVectorPivotX; float gillLY = cos(rotation+0.26229)*-71.40+sharkVectorPivotY; line(gillKX, gillKY, gillLX, gillLY); //back gills stroke(64); strokeWeight(1); float gillEX = sin(rotation-0.2181662)*-63.31+sharkVectorPivotX; float gillEY = cos(rotation-0.2181662)*-63.31+sharkVectorPivotY; float gillFX = sin(rotation-0.29147)*-66.48+sharkVectorPivotX; float gillFY = cos(rotation-0.29147)*-66.48+sharkVectorPivotY; line(gillEX, gillEY, gillFX, gillFY); float gillGX = sin(rotation+0.2181662)*-63.31+sharkVectorPivotX; float gillGY = cos(rotation+0.2181662)*-63.31+sharkVectorPivotY; float gillHX = sin(rotation+0.29147)*-66.48+sharkVectorPivotX; float gillHY = cos(rotation+0.29147)*-66.48+sharkVectorPivotY; line(gillGX, gillGY, gillHX, gillHY); //shark rotation system sharkVectorPivotX=sin(rotation)*25.0+sharkVectorHandleX; sharkVectorPivotY=cos(rotation)*25.0+sharkVectorHandleY; //shark movement system, calculates directional speed by using vector math, sharkThrustValue is magnitude and X and Y components are calculated. thrustComponentX=(sharkVectorHandleX-sharkVectorPivotX)/25.0*sharkThrustValue*thrustBoundary; thrustComponentY=(sharkVectorHandleY-sharkVectorPivotY)/25.0*sharkThrustValue*thrustBoundary; sharkVectorHandleX=sharkVectorHandleX+thrustComponentX; sharkVectorHandleY=sharkVectorHandleY+thrustComponentY; //causes shark to move to opposite side of screen if it goes offscreen int sharkBoundary = 165; if (sharkVectorHandleY <-sharkBoundary) { sharkVectorHandleY=515; } if (sharkVectorHandleY >height + sharkBoundary) { sharkVectorHandleY=-15; } if (sharkVectorHandleX <-sharkBoundary) { sharkVectorHandleX=515; } if (sharkVectorHandleX >width+sharkBoundary) { sharkVectorHandleX=-15; } //hard resets shark to center if it somehow escapes the play area if ((sharkVectorPivotX >600) || (sharkVectorPivotX<(-200)) ||(sharkVectorPivotY<(-200))||(sharkVectorPivotY>600)) { sharkVectorPivotX=200; sharkVectorPivotY=200; rotation=0; } else { } } //unique fish functions, arguments are the (fish number, x pivot vector, y pivot vector, thrust, noisetime) for that unique fish //groups half the fish (A/1 to G/7) into a function. These will swim below the shark to add a sense of depth. void drawTopFishGroup() { drawFishA(); drawFishB(); drawFishC(); drawFishD(); drawFishE(); drawFishF(); drawFishG(); } //groups half the fish (H/8 to N/14) into a function. These will swim above the shark to add a sense of depth. void drawBottomFishGroup() { drawFishH(); drawFishI(); drawFishJ(); drawFishK(); drawFishL(); drawFishM(); drawFishN(); } void drawFishA() { drawAnyFish(1, fishAVectorPivotX, fishAVectorPivotY, 1.0, fishARotation, fishANoiseTime); } void drawFishB() { drawAnyFish(2, fishBVectorPivotX, fishBVectorPivotY, 1.0, fishBRotation, fishBNoiseTime); } void drawFishC() { drawAnyFish(3, fishCVectorPivotX, fishCVectorPivotY, 1.0, fishCRotation, fishDNoiseTime); } void drawFishD() { drawAnyFish(4, fishDVectorPivotX, fishDVectorPivotY, 1.0, fishDRotation, fishDNoiseTime); } void drawFishE() { drawAnyFish(5, fishEVectorPivotX, fishEVectorPivotY, 1.0, fishERotation, fishENoiseTime); } void drawFishF() { drawAnyFish(6, fishFVectorPivotX, fishFVectorPivotY, 1.0, fishFRotation, fishFNoiseTime); } void drawFishG() { drawAnyFish(7, fishGVectorPivotX, fishGVectorPivotY, 1.0, fishGRotation, fishGNoiseTime); } void drawFishH() { drawAnyFish(8, fishHVectorPivotX, fishHVectorPivotY, 1.0, fishHRotation, fishHNoiseTime); } void drawFishI() { drawAnyFish(9, fishIVectorPivotX, fishIVectorPivotY, 1.0, fishIRotation, fishINoiseTime); } void drawFishJ() { drawAnyFish(10, fishJVectorPivotX, fishJVectorPivotY, 1.0, fishJRotation, fishJNoiseTime); } void drawFishK() { drawAnyFish(11, fishKVectorPivotX, fishKVectorPivotY, 1.0, fishKRotation, fishKNoiseTime); } void drawFishL() { drawAnyFish(12, fishLVectorPivotX, fishLVectorPivotY, 1.0, fishLRotation, fishLNoiseTime); } void drawFishM() { drawAnyFish(13, fishMVectorPivotX, fishMVectorPivotY, 1.0, fishMRotation, fishMNoiseTime); } void drawFishN() { drawAnyFish(14, fishNVectorPivotX, fishNVectorPivotY, 1.0, fishNRotation, fishNNoiseTime); } //function that will draw any of the unique fish by using their global variables void drawAnyFish( int uniqueFishNumber, float localFishPivotX, float localFishVectorY, float fishThrust, float localFishRotation, float localFishNoiseTime) { //determines what unique fish function is calling drawAnyFish and sets local variables to unique fish's corresponding global variables int localFishNumber = 0; localFishNumber = uniqueFishNumber; if (localFishNumber==1) { localFishPivotX = fishAVectorPivotX; localFishVectorY = fishAVectorPivotY; localFishRotation = fishARotation; localFishNoiseTime = fishANoiseTime; } if (localFishNumber==2) { localFishPivotX = fishBVectorPivotX; localFishVectorY = fishBVectorPivotY; localFishRotation = fishBRotation; localFishNoiseTime = fishBNoiseTime; } if (localFishNumber==3) { localFishPivotX = fishCVectorPivotX; localFishVectorY = fishCVectorPivotY; localFishRotation = fishCRotation; localFishNoiseTime = fishCNoiseTime; } if (localFishNumber==4) { localFishPivotX = fishDVectorPivotX; localFishVectorY = fishDVectorPivotY; localFishRotation = fishDRotation; localFishNoiseTime = fishDNoiseTime; } if (localFishNumber==5) { localFishPivotX = fishEVectorPivotX; localFishVectorY = fishEVectorPivotY; localFishRotation = fishERotation; localFishNoiseTime = fishENoiseTime; } if (localFishNumber==6) { localFishPivotX = fishFVectorPivotX; localFishVectorY = fishFVectorPivotY; localFishRotation = fishFRotation; localFishNoiseTime = fishFNoiseTime; } if (localFishNumber==7) { localFishPivotX = fishGVectorPivotX; localFishVectorY = fishGVectorPivotY; localFishRotation = fishGRotation; localFishNoiseTime = fishGNoiseTime; } if (localFishNumber==8) { localFishPivotX = fishHVectorPivotX; localFishVectorY = fishHVectorPivotY; localFishRotation = fishHRotation; localFishNoiseTime = fishHNoiseTime; } if (localFishNumber==9) { localFishPivotX = fishIVectorPivotX; localFishVectorY = fishIVectorPivotY; localFishRotation = fishIRotation; localFishNoiseTime = fishINoiseTime; } if (localFishNumber==10) { localFishPivotX = fishJVectorPivotX; localFishVectorY = fishJVectorPivotY; localFishRotation = fishJRotation; localFishNoiseTime = fishJNoiseTime; } if (localFishNumber==11) { localFishPivotX = fishKVectorPivotX; localFishVectorY = fishKVectorPivotY; localFishRotation = fishKRotation; localFishNoiseTime = fishKNoiseTime; } if (localFishNumber==12) { localFishPivotX = fishLVectorPivotX; localFishVectorY = fishLVectorPivotY; localFishRotation = fishLRotation; localFishNoiseTime = fishLNoiseTime; } if (localFishNumber==13) { localFishPivotX = fishMVectorPivotX; localFishVectorY = fishMVectorPivotY; localFishRotation = fishMRotation; localFishNoiseTime = fishMNoiseTime; } if (localFishNumber==14) { localFishPivotX = fishNVectorPivotX; localFishVectorY = fishNVectorPivotY; localFishRotation = fishNRotation; localFishNoiseTime = fishNNoiseTime; } //local fish variables float localFishVectorHandleX = (sin(localFishRotation)*8.0)+localFishPivotX; float localFishVectorHandleY = (cos(localFishRotation)*8.0)+localFishVectorY; float fishThrustComponentX = 0.0; float fishThrustComponentY = 0.0; float fishTailCX =sin(localFishRotation+(PI/1.1))*-9.0+localFishPivotX; float fishTailCY =cos(localFishRotation+(PI/1.1))*-9.0+localFishVectorY; float fishTailDX =sin(localFishRotation-(PI/1.1))*-9.0+localFishPivotX; float fishTailDY =cos(localFishRotation-(PI/1.1))*-9.0+localFishVectorY; //fish body stroke(150, 108, 10); strokeWeight(1); fill(255, 200, 20); ellipse(localFishPivotX, localFishVectorY, 7, 7); //fish tail noStroke(); fill(255, 200, 20, 175); triangle(localFishPivotX, localFishVectorY, fishTailCX, fishTailCY, fishTailDX, fishTailDY); //fish rotation system localFishVectorHandleX=sin(localFishRotation)*8.0+localFishPivotX; localFishVectorHandleY = cos(localFishRotation)*8.0+localFishVectorY; //fish movement system fishThrustComponentX=(localFishPivotX-localFishVectorHandleX)/16.0*fishThrust; fishThrustComponentY=(localFishVectorY-localFishVectorHandleY)/16.0*fishThrust; localFishPivotX=localFishPivotX+fishThrustComponentX; localFishVectorY=localFishVectorY+fishThrustComponentY; //bounces fish off of boundaries upon collision and sets outgoing angle to incoming angle //finds angle between fish and wall, then multiples that by 2, then adds or subtracts that angle to rotation depending on angle of approach int topLeftBoundarySize=0; int bottomRightBoundarySize=400-topLeftBoundarySize; //top boundary, if fish is facing left if ((localFishVectorY <topLeftBoundarySize) && (localFishVectorHandleX > localFishPivotX)) { localFishRotation=localFishRotation + (2.0*(atan((localFishVectorHandleY-localFishVectorY)/(localFishVectorHandleX-localFishPivotX)))); } //top boundary, if fish is facing right if ((localFishVectorY <topLeftBoundarySize) && (localFishVectorHandleX < localFishPivotX)) { localFishRotation= localFishRotation - (2.0*(atan((localFishVectorY-localFishVectorHandleY)/(localFishVectorHandleX-localFishPivotX)))); } //left boundary, if fish is facing up if ((localFishPivotX <topLeftBoundarySize) && (localFishVectorHandleY > localFishVectorY)) { localFishRotation=localFishRotation - (2.0*(atan((localFishVectorHandleX-localFishPivotX)/(localFishVectorHandleY-localFishVectorY)))); } //left boundary, if fish is facing down if ((localFishPivotX <topLeftBoundarySize) && (localFishVectorHandleY < localFishVectorY)) { localFishRotation=localFishRotation + (2.0*(atan((localFishPivotX-localFishVectorHandleX)/(localFishVectorHandleY-localFishVectorY)))); } //bottom boundary, if fish is facing left if ((localFishVectorY >bottomRightBoundarySize) && (localFishVectorHandleX > localFishPivotX)) { localFishRotation=localFishRotation + (2.0*(atan((localFishVectorHandleY-localFishVectorY)/(localFishVectorHandleX-localFishPivotX)))); } //bottom boundary, if fish is facing right if ((localFishVectorY >bottomRightBoundarySize) && (localFishVectorHandleX < localFishPivotX)) { localFishRotation=localFishRotation - (2.0*(atan((localFishVectorY-localFishVectorHandleY)/(localFishVectorHandleX-localFishPivotX)))); } //right boundary, if fish is facing up if ((localFishPivotX >bottomRightBoundarySize) && (localFishVectorHandleY>localFishVectorY)) { localFishRotation=localFishRotation + (2.0*(atan((localFishVectorHandleX-localFishPivotX)/(localFishVectorY-localFishVectorHandleY)))); } //right boundary, if fish is facing down if ((localFishPivotX >bottomRightBoundarySize) && (localFishVectorHandleY < localFishVectorY) && (localFishVectorHandleX<localFishPivotX)) { localFishRotation=localFishRotation - (2.0*(atan((localFishPivotX-localFishVectorHandleX)/(localFishVectorY-localFishVectorHandleY)))); } else { } //sets the noise that controls fish's random turning localFishNoiseTime = localFishNoiseTime +0.1; float boundaryRotDampener = 1.0; int BoundaryRotDampenerOffset = -8; //decrease fish's random movements when near boundaries to mitigate fish steering back into boundaries repeatedly if ((localFishPivotX <topLeftBoundarySize-BoundaryRotDampenerOffset) || (localFishPivotX>bottomRightBoundarySize+BoundaryRotDampenerOffset) || (localFishVectorY<topLeftBoundarySize-BoundaryRotDampenerOffset)||(localFishVectorY>bottomRightBoundarySize+BoundaryRotDampenerOffset)) { boundaryRotDampener=0.5; } //applies noise to fish's rotation, with consideration for if the fish is near the boundary float fishRotationRange = PI/72.0; float fishNoise = ((noise(localFishNoiseTime))-.5)*2.0; float fishJitters = fishNoise * fishRotationRange * boundaryRotDampener ; localFishRotation = localFishRotation + fishJitters; //resets escaped fish to within boundary if it somehow escapes if (localFishVectorY<topLeftBoundarySize-3) { localFishVectorY=topLeftBoundarySize+3; } if (localFishVectorY>bottomRightBoundarySize+3) { localFishVectorY=bottomRightBoundarySize-3; } if (localFishPivotX<topLeftBoundarySize-3) { localFishPivotX=topLeftBoundarySize+3; } if (localFishPivotX>bottomRightBoundarySize+3) { localFishPivotX=bottomRightBoundarySize-3; } //at end of function, stores local values of the unique fish to that fish's global variable if (localFishNumber==1) { fishAVectorPivotX = localFishPivotX; fishAVectorPivotY = localFishVectorY; fishARotation = localFishRotation; fishANoiseTime = localFishNoiseTime; } if (localFishNumber==2) { fishBVectorPivotX = localFishPivotX; fishBVectorPivotY = localFishVectorY; fishBRotation = localFishRotation; fishBNoiseTime = localFishNoiseTime; } if (localFishNumber==3) { fishCVectorPivotX = localFishPivotX; fishCVectorPivotY = localFishVectorY; fishCRotation = localFishRotation; fishCNoiseTime = localFishNoiseTime; } if (localFishNumber==4) { fishDVectorPivotX = localFishPivotX; fishDVectorPivotY = localFishVectorY; fishDRotation = localFishRotation; fishDNoiseTime = localFishNoiseTime; } if (localFishNumber==5) { fishEVectorPivotX = localFishPivotX; fishEVectorPivotY = localFishVectorY; fishERotation = localFishRotation; fishENoiseTime = localFishNoiseTime; } if (localFishNumber==6) { fishFVectorPivotX = localFishPivotX; fishFVectorPivotY = localFishVectorY; fishFRotation = localFishRotation; fishFNoiseTime = localFishNoiseTime; } if (localFishNumber==7) { fishGVectorPivotX = localFishPivotX; fishGVectorPivotY = localFishVectorY; fishGRotation = localFishRotation; fishGNoiseTime = localFishNoiseTime; } if (localFishNumber==8) { fishHVectorPivotX = localFishPivotX; fishHVectorPivotY = localFishVectorY; fishHRotation = localFishRotation; fishHNoiseTime = localFishNoiseTime; } if (localFishNumber==9) { fishIVectorPivotX = localFishPivotX; fishIVectorPivotY = localFishVectorY; fishIRotation = localFishRotation; fishINoiseTime = localFishNoiseTime; } if (localFishNumber==10) { fishJVectorPivotX = localFishPivotX; fishJVectorPivotY = localFishVectorY; fishJRotation = localFishRotation; fishJNoiseTime = localFishNoiseTime; } if (localFishNumber==11) { fishKVectorPivotX = localFishPivotX; fishKVectorPivotY = localFishVectorY; fishKRotation = localFishRotation; fishKNoiseTime = localFishNoiseTime; } if (localFishNumber==12) { fishLVectorPivotX = localFishPivotX; fishLVectorPivotY = localFishVectorY; fishLRotation = localFishRotation; fishLNoiseTime = localFishNoiseTime; } if (localFishNumber==13) { fishMVectorPivotX = localFishPivotX; fishMVectorPivotY = localFishVectorY; fishMRotation = localFishRotation; fishMNoiseTime = localFishNoiseTime; } if (localFishNumber==14) { fishNVectorPivotX = localFishPivotX; fishNVectorPivotY = localFishVectorY; fishNRotation = localFishRotation; fishNNoiseTime = localFishNoiseTime; } }