Week 3_Generative Artwork

 

click to change scene

Concept

 

 

 

 

 

 

The idea came from jet skiing, which I do casually, so I already had a clear picture in my head of what the water looks like from the seat, the way the surface keeps moving underneath you and the horizon never sits still. I also took inspiration from the car example that was posted for the class. That example uses a simple object moving across the screen against a background, and I used the same basic structure here, but replaced the car with a jet ski and the road with a moving sea.

I extended the idea in two ways. The first is the water itself; instead of one flat background, the ocean is built from four Wave objects stored in an array, each one drawn lower, darker and moving at a slightly different speed. Drawing them in order means the closer waves cover the ones behind, which gives a sense of depth, and the topmost wave doubles as the horizon so the sky meets the sea along a curve rather than a straight line. The second addition is time of day. Clicking the canvas switches the whole scene between daytime and nighttime, changing the sky and water colours and swapping the sun for a crescent moon with stars behind it. I wanted the piece to have more than one state so there was a reason for the viewer to interact with it rather than just watch it.

How it was made

The sketch is built from four classes: Wave handles one band of water, Bubble is a small circle that floats upwards, Star is a dot in the sky, and Jet ski draws the craft and its rider. Each class stores its own values in the constructor and has its own move and display methods, so the draw function stays short; it just loops through the arrays and tells each object to move and draw itself.

The objects are created once in setup using for loops and stored in three arrays: waves, bubbles and stars. Doing it this way means I can change how busy the scene is by editing a single number. Asking for seventy stars instead of twenty is one character in a loop condition, not seventy lines of code, and this is the main reason the program uses objects and arrays.

The most important part of the code

beginShape();
    vertex(0, height);
    for (let x = 0; x <= width; x += 10) {
      vertex(x, this.y + sin(x * 0.02 + this.offset) * this.waveHeight);
    }
    vertex(width, height);
    endShape(CLOSE);

This builds one wave as a single filled shape. The loop walks across the canvas and places a point every ten pixels. The height of each point comes from sin, which rises and falls smoothly between -1 and 1, so multiplying it by the wave height turns that into a rise and fall measured in pixels. Adding the offset shifts where the curve starts, and because the move method increases that offset a little every frame, the whole wave appears to travel sideways. The two extra vertex calls at the bottom corners close the shape off so it fills downwards instead of being just a line.

What makes this the key part is that everything else in the artwork depends on it. Each Wave object is given its own wave height, speed and starting offset, so the same six lines produce four waves that all look different and move at different rates. That difference in speed is what creates the sense of depth, since the nearer waves move faster than the ones further away. Without this one piece of code the scene would just be flat blocks of color.

Reflection

The hardest part of this project was not writing the classes themselves but getting the layers to sit correctly on top of each other. My first version drew the sky as a plain rectangle ending at a fixed height, and the result looked wrong straight away; there was a hard straight line cutting across the middle of the canvas where the sky stopped, which broke the illusion completely. I fixed this by changing how the background is built. Instead of drawing a sky rectangle and a water rectangle, the sky color now fills the entire canvas and the waves are drawn over the bottom half of it, with the topmost wave acting as the horizon. Because that wave is made with sin like all the others, the edge between the sky and the sea is a curve rather than a straight line, and the whole scene reads as one thing instead of two blocks stacked on top of each other.

Looking back, most of my difficulties were about order and timing rather than logic; which order things are drawn in, when the canvas gets cleared, and when an object is moved relative to when it is visible. The classes and arrays were the straightforward part once I understood that a class is written once and an object is created from it many times. If I were to take this further I would like the jet ski to actually sit on the surface of the wave and tilt with it, rather than bobbing independently, since that is the one part of the scene that still gives away that the jet ski and the water are not really connected.

Leave a Reply