//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;
}
}