In this project, we are designing our own dancing character utilizing the object-oriented programming we learned so far. And eventually join a Grand Dancing Party with all the other characteristics from the creative coding class. Really looking forward to that!
My dancer is a flame with the motion of the usual flame we see in reality and a fantastical face with bouncing eyes and a shocked mouth haha.
! Inspired by Leyla's midterm project: https://leylabevis.github.io/CCLab_F24/ProjectA !
To mimic the shape of a flame, I formed the shape with circles from small to big using the map function and for loop.
To mimic the movement of a flame, I utilized sin.
let x;
let y;
function setup() {
createCanvas(400, 400);
x = width/2;
y = height/2;
}
function draw() {
background(0);
fill(255);
push();
translate(x, y);
for(let i=0; i<400; i+=10){
j = 20*sin((frameCount-i)/100);
//j = 0;
let s = map(i, 0, 400, 60, 6);
stroke(255);
circle(i/4,j,s);
}
pop();
}
A few steps to make the single element into a basic flame shape:
Rotate the sin motion with rotate(), push(), pop();
Duplicate three elements with different positions, size, frequency, and amplitudes or the directions that can be decided by negative amplitude;
Add a constantly changing ellipse underneath to hide the three different ends;
let x;
let y;
let m;
function setup() {
createCanvas(400, 400);
x = width/2;
y = height/2;
m = 80;
}
function draw() {
background(0);
fill(255);
push();
translate(x, y);
rotate(80);
for(let i=0; i<400; i+=10){
j = 10*sin((frameCount*10-i)/100);
//j = 0;
let s = map(i, 200, 400, 40, 1);
stroke(255);
circle(i/4,j,s);
}
for(let i=0; i<600; i+=10){
j = 10*sin((frameCount*10-i)/100);
//j = 0;
let s = map(i, 0, 600, 80, 1);
stroke(255);
circle(i/4,j+30,s);
}
for(let i=0; i<400; i+=10){
j = -10*sin((frameCount*10-i)/100);
//j = 0;
let s = map(i, 200, 400, 40, 1);
stroke(255);
circle(i/4,j+50,s);
}
pop();
m = -20*sin(frameCount/10);
noStroke();
ellipse(width/2+30,height/2,m+100,85);
}
In order to make the image more real, I mapped the opacity to blur the edge of the flame and added different layers of different colors, different paces, amplitudes and directions. The yellow part was later removed to give way to the mouth.
https://editor.p5js.org/kw3508/sketches/Rpy25j2in
let opa = map(i, 0, 300, 255, 10);
fill(255,opa);
Bouncing eyes: still utilizing sin to build this motion. Tried to make them in heart shape but weren't as cute so changed back to circles.
push();
//translate(this.x-width/2, this.y-height/2);
let v = 5*sin(frameCount*0.4);
fill(0);
circle(-5,v-10, 10);
circle(55,v-10,10);
// fill(255,0,0);
// noStroke();
// triangle(this.x - 10, this.y + 5, this.x + 10, this.y + 5, this.x, this.y-5);
// ellipse(this.x - 5, this.y - 2.5, 5);
// ellipse(this.x + 5, this.y - 2.5, 5);
pop();
Mapped the size of the mouth moving with the same pace as the eyes.
push();
translate();
noStroke();
let s = sin(frameCount*0.4);
let size=map(s,-1,1,20,40);
fill(207, 27, 14);
ellipse(25,10,size/1.5,size);
pop();
I think object-oriented programming isn't giving me a hard time so far. We basically just need to adjust what we learned before into a certain format. So I found it quite convenient to test out a basic shape in p5.js web and then adjust it into Visual Studio Code. During the process I also found myself getting a lot more familiar with shifting between p5, Visual Studio Code, GitHub page and GitHub software which was super confusing in the midterm project for me.
Practical tips learned:
Inspector comes in handy;
Sin is very useful not only in motion but also shape, I can map the sin to create a shape that's small at two ends and big in the middle (didn't use in the final result);
It's better to calculate in proportion than to try out specific numbers.
What is the benefit of your class not relying on any code outside of its own definition?
It feels very safe when I know it's an independent object haha don't know if that makes sense. It's quite convenient to have a universal translate and starting point and then make changes inside.
What make it challenging to write code that has to harmonize with the code other people have written?
I needed to correctly detect which part of the code shouldn't be changed and how should I incorporate mine. But for the code this time it wasn't tricky but quite straightforward and clear.
Describe the terms modularity and reusability using the example of your dancer class.
I think the reason why we are using class is to keep its independence and that in a huge sense is providing modularity and reusability. Though not too obvious in my own dancer code but to combine all the dancers for the dance party, classes allow us to break down a complex project into smaller, manageable parts (objects). This modular approach makes code more organized, easier to maintain, and promotes reusability.