Week 5! Functions and Sparkling Stars!

Click and drag to zoom, double-click to change colors.

Press Spacebar for fullscreen.

Press "C" to reset colors to default.

This week’s assignment was all about wrapping up our code into functions. Making your own functions is great for two reasons. 1: It’s a nice way to tidy up your code, making it much easier to debug and isolate variables and such. 2: By giving your function parameters you can easily repeat it with variation. Here is a link to the sketch.

Oh, and before I continue, I should add that we were urged to execute this on one of our old sketches. So I chose my very first sketch to revisit. Here is a link to that for comparison.

In the above example I used eight functions, two of which I created from scratch. The ones I created are called “drawStars” and “drawPlanets.” Guess what those do.

For “drawStars,” I gave my function just one boolean true/false paramater. Basically it says if “sparkleState” is true (cute, right?), do this:

//sparkling stars:if (sparkleState == true) {for (let i = 0; i < 1; i++) {push();fill(255)noStroke();let noiseX = noise(i, 0);let noiseY = noise(i, 1000);let starX = map(noiseX, 0.1, 0.9, width * -0.25, (width + (width * 0.25)));let starY = map(n…
 

The beauty of functions if that all it says in the Draw workspace is: “drawStars(true);”, and this one line accounts for 30 lines of code. Similarly, my “drawStars” function accounts for about 60 lines of code. “drawStars,” however has significantly more parameters that I defined. I gave it 12 parameters, so you can give it up to 12 arguments.

Those parameters are:

  • X coordinates

  • Y coordinates

  • planet width

  • planet height

  • planet ring width ( a percentage value based on planet size)

  • planet ring height (also a similar percentage value)

  • planet ring color

  • red value of planet

  • green value of planet

  • blue value of planet

  • plant ring angle

  • zoom value (a percentage value in relation to overall scaling)

By utilizing these parameters, I can repeat the planets with a great deal of control over the variation. For example, the top-left planet has a ring more in-line with the horizon, as well as a darker color, while the planet in the bottom-right has no ring. Additionally I was able to use the scale value variability I created with the parameters to be able to scale the planets at different rates when you zoom. This creates the illusion that the two smaller planets are further away. If they scale at the same rate as the one “in front,” the illusion is not as effective.

Here’s what that looks like:

if (zoom < 6.7) {drawPlanet(width * 0.2, height * 0.3, width, width, 3, 0.6, 100, redrandom, greenrandom, bluerandom, 0, 0.1);}if (zoom < 8) {drawPlanet(width * 0.8, height * 0.7, width * 0.65, width * 0.65, 0, 0, 255, redrandom2, greenrandom2…
 

The “if” statements preceding each “drawPlanet” function call are what make the planets disappear if you zoom in far enough. This creates the illusion that you’re sort of zooming past them, or traveling through them.

I also added some mouse and key functionality as you probably noticed. You can change the color back to the default red by pressing “C,” and you can also zoom in with the mouse and randomize color with a double-click.

My biggest success, though, was finally making a sketch that can be viewed in full screen mode. I accomplished this by using the “fullscreen()” function. But, that on its own is not enough. I also had to make a boolean expression that would toggle back and forth between my 600x400 pixel canvas size and a full-window canvas size, and it works great! BUT… if you press the escape button while in full screen mode it messes up my system for toggling the canvas size back and forth. Still trying to work that one out.

I also wanted to talk about how I made the star background. There were a lot of other little things I did to finesse this particular sketch, but I for sure want to mention that. With some guidance from our talented professor, Allison Parrish, I was able to wrap my brain around the “noise” call, at least a little bit anyways. I wanted to randomize the stars in the background, but as anyone who has played with p5js knows, putting a “random” call inside of the Draw loop gets really annoying really fast. Like epileptic seizure annoying. Enter, the “noise” call.

I don’t totally understand its origin, but “noise” generates a random value between 0 and 1. What sets it apart from “random” is that the value it generates will be the same for every cycle of the draw loop, so in this way you can create static objects in random-looking places. The behavior is weird in practice, though, because it seems to center the center of the canvas. If you map noise to values between 0 and the canvas bounds, you get this:

Illustration of red planets in space with the stars more densely concentrated in the center.
 

Where are all the stars at the edge? As you can see, when you map noise this way it disproportionately favors the center. So, the way I fixed this was by mapping the values 25% outside of the canvas bounds. Then you get this:

Illustration of red planets in space with a more even distribution of stars in the background.
 

Not bad right? A little more even and fair to the edges? I call it a success. You’re welcome to disagree.

As for the sparkling stars (the animated ones), I used the “random” call to my advantage. If you generate random stars in random places on its own, it does end up being really annoying. The workaround I came up with was to make the background in the Draw loop have a subdued alpha channel, meaning I lowered its opacity. This creates the appearance of the stars fading out, when in reality the background is fading in by layering a translucent background repeatedly on top of the stars with every cycle of the Draw function. This is also a good tip for making anything animated using “random” to be less annoying. Oh! This is also what gives the psychedelic tracer look to the planets as you zoom in and out.

I hope you enjoyed this one. Until next week….

Hugs,
Zach