For my sonic story I wanted to create a looped animation involving a water droplet falling into a pond, fish getting caught by a hook and flung out of the water, and the “fish” returning back into the water in the form of a droplet. Logistically, I couldn’t get the animation to flow the way I intended to, but I used sound to create a sense of mood in an otherwise modern positive color story.
I created storyboards in Illustrator prior to “animating” in p5.js to plan out the scenes. They illustrate what my animation is supposed to communicate.
sketch wordpress//FISH STORY
/*PREMISE: Water drops into a pond, where ripples form.
Pans down to swimming fish.
A fishing hook descends and a fish takes the bait.
The fish is yanked out of the water.
The animation loops.
*/
//global variables
var x; // translate multipliers
var y;
var sx = 1; //scale multipliers
var sy =1;
function preload() {
//sounds downloaded from freesound.org
drop = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/waterdrop.wav");
ambience = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/ambience.wav");
looming = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/looming.wav");
}
function setup() {
createCanvas(480, 480);
useSound();
frameRate(40);
}
function soundSetup() {
drop.setVolume();
ambience.setVolume(1.5);
looming.setVolume(1.2);
}
function draw() {
background(247, 242, 223); //cream
//play sound
print(frameCount.toString());
if (frameCount == 50) {
drop.play();
} else if (frameCount == 100) {
ambience.play();
} else if (frameCount == 180) {
looming.play();
} else if (frameCount == 400) {
looming.stop();
}
//animate visual assets
if (frameCount >=0 & frameCount<50) {// water drops
waterbody(0,0);
waterdrop(0,frameCount*2);
} else if (frameCount >= 50 & frameCount <80) {//ripples form
waterbody(0,0);
ripple(0,0);
} else if (frameCount >= 80 & frameCount <100){
translate(0, -3* frameCount)
push();
waterbody(0,0);
pop();
ripple(0,0);
} else if (frameCount >= 100 & frameCount <250) {//teal fish keeps swimming
waterbody(0, -260);
//pink fish
fill(255, 75, 130);
fish(-frameCount,0);
//teal fish
push();
fill(28, 158, 175);
translate(300, 250);
scale(.6);
fish(-frameCount, 0);
pop();
if (frameCount >= 180 & frameCount <250) {//hook descends
//waterbody(0, -260);
//main fish
fill(255, 75, 130);
fish(-frameCount,0);
hook(0, frameCount-200);
}
/*} else if (frameCount >= 100 & frameCount <180) {//fishes swim by
/*} else if (frameCount >= 180 & frameCount <250) {//hook descends
//waterbody(0, -260);
//main fish
fill(255, 75, 130);
fish(-frameCount,0);
hook(0, frameCount-200);
*/
} else if (frameCount >= 250 & frameCount <350) {//hook ascends with fish
waterbody(0,-260);
hook(0, 100+(-2* frameCount));
fill(255, 75, 130);
fish(0,0);
//teal fish
push();
fill(28, 158, 175);
translate(300, 250);
scale(.6);
fish(-frameCount -100, 0);
pop();
}
//loop animation
if (frameCount> 400){
frameCount =0;
}
}
//draw visual assets
//ABOVE WATER
function waterbody(x,y){
noStroke();
//waterbody
push();
translate(x,y);
stroke(255); //white outline
fill(148, 213, 213); //light teal
rect(0, 260, width, height);
pop();
}
function fullwaterbody(x,y){
noStroke();
//waterbody
push();
translate(x,y);
stroke(255); //white outline
fill(148, 213, 213); //light teal
rect(0, 0, width, height);
pop();
}
function ripple(x, y){
translate(x,y);
scale(sx,sy);
noStroke();
//ripple1
push();
fill(28, 158, 175); //dark teal
ellipse(width/2, 383, 620, 242);
pop();
//ripple2
push();
stroke(255);
fill(255, 75, 130); //pink
ellipse(width/2, 350, 382, 121);
pop();
//ripple3
push();
fill(96, 201, 224); //light blue
ellipse(width/2, 350, 189, 60);
pop();
//ripple4 (center)
push();
stroke(255);
fill(247, 242, 223); //cream
ellipse(width/2, 350, 99, 31);
pop();
}
function waterdrop(x,y){
noStroke();
//waterdrop
push();
translate(x,y);
fill(255, 75, 130); //pink
ellipse(width/2, 176, 38);
triangle(width/2, 135, width/2+16, 166, width/2-16, 166);
}
//UNDER WATER
function hook(x,y){
//hook
push();
translate(x,y);
noFill();
stroke(28, 158, 175); //dark teal
strokeWeight(5);
strokeCap(SQUARE);
line(width/2 +20, 92-20, width/2 +20, -300);
arc(width/2, 92-20, 40, 50, 0, PI, OPEN);
pop();
}
function fish(x,y){
noStroke();
push();
translate(x,y);
ellipse(width/2, height/2, 38);
triangle(width/2+40, height/2, width/2 +10, height/2 -16, width/2 +10, height/2 +16);
triangle(width/2+40, height/2, width/2 +60, height/2 -10, width/2 +60, height/2 +10); //tail
pop();
}