Project Link:
https://domenica123s.github.io/cclab/object-dancer-template/
Brief Description:
Introducing Robert Jelly: The Breakdance Dancer! Robert is a slippery/slimy green creature who grooves by flinging his arms in all directions, since he’s legless. He thrives on floating across the dance floor, flaunting his jaw-dropping moves and unique style.
Highlights of my Coding Process:
At the beginning, I was undecided on which creature to draw on the canvas since I aimed to achieve an interesting motion. Then, I was reminded of this cartoon character (which I got inspired by) who loved to dance and had some moves that I found intriguing.
For the body I did the following loop:
Let numOfEllipses = 8; let baseEllipseWidth=100; let baseEllipseHeight=20; let ellipseWidthStep= (100-baseEllipseWidth) /numOfEllipses; let ellipseHeightStep= (30-baseEllipseHeight) /numOfEllipses; let spacing=-10; letstartY=0; for (leti=0; i<numOfEllipses; i++) { let currentY=startY+ (i* (baseEllipseHeight+spacing)); let currentWidth=100-i*ellipseWidthStep; let currentHeight=30-i*ellipseHeightStep; noStroke(); fill(127, 247, 8); ellipse(0, -20, 80, 50); ellipse(0, currentY, currentWidth, currentHeight);
I started by determining how many ellipses will be drawn in the series (8). Then I defined the characteristics of the ellipse like the initial size of the ellipse in the series as well as setting the width and height. The variable ellipseWidthStep determines how much the width and height decrease for each ellipse. Then the loop that iterates the times that the ellipses will be drown. Finally, the line `ellipse(0, currentY, currentWidth, currentHeight);`: draws the current ellipse in the series. currentY is calculated based on the iteration count i.
Arm movement:
Since Robert Jelly only has arms it was important to given them a full range of motion so simulate the dancing. For this part of my code I used sin and cos:
class DomeDancer { constructor(startX, startY) { this.x=startX; this.y=startY; this.armLength=50; this.armSpeed=0.05; this.angle=0;
update() { // Update arm angle this.angle+=this.armSpeed; } // arms this.drawArm(-40, 20, -1); this.drawArm(40, 20, 1);
I started by coding below the already declared class, the line `this.x = startX;` and `this.y = startY;` set the initial x and y coordinates of the dancer. The I added the properties for the arms which were the length, speed at which the dancer’s arms will move and finally the initial angle. Then I drew the arms with the line call drawArm within the constructor to draw the left and right arms of the dancer. The update method updates the angle of the arm based on the speed.
drawArm(x, y, direction) { letarmAngle=sin(this.angle) *0.3+0.5; letarmX=x+cos(TWO_PI*armAngle) *this.armLength*direction; letarmY=y+sin(TWO_PI*armAngle) *this.armLength; stroke(105,210,0); strokeWeight(10); line(x, y, armX, armY);
The line armAngle, calculates the angle at which the arms will be drawn by using sin function to generate a value between -1 and 1 , ensuring that the arm swings in both directions around the base position. The next line let armX = x + cos(TWO_PI * armAngle) * this.armLength * direction; calculates the x-coordinate of the endpoint of the arm. The last line let armY = y + sin(TWO_PI * armAngle) * this.armLength, calculates the y-coordinate of the endpoint of the arm.
Noise for floating:
I wanted Robert Jelly to move around the canvas, in order to achieve this I used the noise property.
class DomeDancer { constructor(startX, startY) { this.x=startX; this.y=startY; this.noisesetX=random(1000); this.noisesetY=random(1000); } update() { //upadate noise letnoiseX=noise(this.noisesetX); letnoiseY=noise(this.noisesetY); this.x=map(noiseX, 0, 1, width*0.4, width*0.6); this.y=map(noiseY, 0, 1, height*0.4, height*0.6); this.noisesetX+=0.02; this.noisesetY+=0.02;
In this code snippet the this.noiseSet(x,y) are properties that give the dancer random values for updating Robert’s positions through Perlin noise. Followed by stating the range in which the dancer is allowed to move, by mapping the noise lines map( ).
Reflection:
One of the main things I noticed when using the template for this mini-project is that in the sketch.js, the benefit of an in-class function is that it allows for encapsulation and organization within itself. This means that functions defined within that class can operate directly on the class’s properties and methods by keeping related functionality together. I think using class makes it easier to manage and understand the code.
As mentioned above, we had to use a template for this assignment, which made it quite challenging for me to develop my code around it. If it weren’t for the guidelines within the code (provided by the professor, which seemed to be a step-by-step tutorial and very helpful!), I believe the main challenge lies in basic conventions like naming variables, which showcase the varying approaches people have when coding. Initially, it led to incompatible coding, resulting in numerous bugs and code crashes since the code did not follow my usual flow and logic.
By using the `DomeDancer` class exemplifies the significance of modularity, which is that by encapsulating the dancer’s properties and behaviors within a class, the code achieves a modular structure that enhances organization and maintainability. Each method update( ) and display( ) focuses on specific aspects of the dancer’s functionality, allows for clear separation making it easier to understand and work with different parts of the code independently. Furthermore, the `DomeDancer` class can be reused across multiple instances or even in other projects without significant modifications.