In the final week of the semester, I continued to work on my generative system assignment. I still had to do the following:
- Draw a sun that is displayed behind the clouds.
- Put measurements on the thermometer and make it display the temperature of the current city.
- Allow the user to change between cities with the arrow keys or buttons
- Make the clouds move based on the current city’s wind speed.
- Make the clouds continually generate, instead of stopping at 200
- Determine the current condition and animate it.
- Populate the animation with images of each existing city, as well as more cities depending on how much time I had.
I started off by looking at how to draw a sun. I could’ve drawn a bright circle in the sky, but I wanted to make it more animated, like it was constantly burning. I wasn’t sure where to start, so I looked online to see if anyone had done something similar for inspiration. I found an example on Open Processing, which did exactly what I wanted my sun to do except this one was done using processing rather than p5.js. After reading through the code, I was able to understand what was going on.
I realised how similar processing was to p5.js and I was able to determine that:
- void is the same as function.
- size is the same as createCanvas.
- All of the floats, ints, etc. needed to be turned into variables in p5.js
- dist is a preset variable in p5.js so it wouldn’t work properly, I had to change its name to something else.
The example made the user press the spacebar to generate a new drawing every time, where I wanted mine to keep changing continuously so I left the loop in mine and didn’t put in any user control, I just followed the way that they drew it to get a similar effect. I decided to keep the sun in the same spot in each location instead of making it random as well, in case it were to show up in front of an object in the background image and not look as effective.
I then looked at drawing the measurements on the thermometer. I created a loop that would divide the height of the thermometer tube by 50 and draw a line in every instance. I wanted some form of numerical element though as well to make the identification easier so I thought about how I could do that. I remembered once using a formula that would check if a number was divisible by another number by determining if the remainder of the division was 0, so I looked that up and found the answer on W3 Schools. You can use a percentage sign to check the divisibility of a number like this:
if (number % 5 == 0) {
}
In this case, if the number variable divided by 5 returned a remainder of 0, it would therefore be divisible by 5 and would run whatever is inside the if statement. So this is what I used for my thermometer, if the number was divisible by 5 it would display it as text, else it would display it as a line. I then drew a box over the top of the red mercury on the thermometer, with a height that is controlled by the temperature. I tested it on several locations and the accuracy was perfect.
My assignment then looked like it was really starting to come together as you can see below, note that I took the cloud for loop out so that it only displayed one cloud and I could see what I was doing with the sun and temperature. I also removed the temperature text as I had determined that my thermometer was working correctly.
I then looked at adding user navigation in. This was easy as I had already done similar things in previous examples. I used my flow and response example, where a new bouncing ball was generated every time the user pressed the down arrow on their keyboard, to write code that would increase and decrease the currentCity variable whenever the user pressed the left or right arrow keys. I then used the Spider-Man colouring in example, where I had buttons to change colours, to create buttons that would do the same as the arrow keys on the keyboard.
This worked straight away but I had to set conditions for it to loop once it reached the end of the array (go back to the start after it reaches the end, or to the end from the start if going backwards), otherwise it would crash. This was fairly easy too, I just had to set the currentCity to equal 0 if it went over the length of the cities array, or set it equal to the length of the array if it went under 0.
As I was navigating through the different locations, the thermometer was jumping straight from one value to another, so I thought I might try and make it a little bit nicer. I put in another variable which checked whether the new temperature was greater than or less than the temperature of the previous city and then lowered it or raised it gradually instead of instantly, creating a nice animation effect.
The next thing that I wanted to look at was the clouds. So far, I had only been able to create so many before they would disappear, and I couldn’t get them to move based on the wind speed that I had retrieved. I ended up fixing both of these issues by making the x position of the cloud reset to a new position whenever it hit the width of the canvas, and setting the windSpeed variable before any of the functions so that it was accessible to the cloud function.
I now had everything working as I wanted it to apart from the last bit of text left on the screen – the condition. I needed to create if statements that would run animations based on the retrieved condition, and I also needed to create new animations for:
- Storm clouds.
- Rain clouds.
I also noticed with my animation that sometimes when changing to a new city for the first time, the graphics would build up on top of each other and look messy until the image loaded properly. I realised that this was because I was loading the images in the draw function and not in my preload function. I moved the bit where it loads the images into the preload function, and created a for loop which stored each one in an array. However, this array was relying on a number value so I had to take the shuffle function off my array of cities in order for the numbers to line up with the images array. Instead of having the cities display in a random order each time, I now made the first displayed city random and then the rest alphabetical.
I ended up managing to show rain and lightning in the animation as well. I originally started off trying to display rain in a similar way to the clouds, with different blue ellipses falling all over the screen. I found it hard to replicate because when you clicked into a rainy city, the rain clouds would start rolling in but the rain would start displaying all over the screen, even where the rain clouds hadn’t reached yet. I need some kind of way to make the rain start scrolling in with the clouds and then stay on the screen whilst it is raining and then scroll back out again when you click into a non-rainy city. When playing around with it, I found that placing angled, white strokes all over the screen that display randomly looked more effective and it was easier to implement. I also decided to make the city condition change instantly, rather than trying to make the rain adapt to the new condition scrolling through. I thought that in doing this, the user won’t be given any false impressions about the weather conditions because they will instantly be shown when the button is pressed and they won’t have to wait for the new condition to roll onto the screen. It also allows them to navigate the interface whilst understanding the conditions more quickly.
When thinking about how to replicate the lightning during a thunderstorm, I decided to have a look at Open Processing again for inspiration. I found this example, which keeps on drawing a new line to different x positions until it reaches a certain height, creating a line that keeps changing direction as it falls. I thought that this was a very good representation of the way that lightning acts so just like with the sun, I decided to base my animation off of the Open Processing example. This worked effectively, and I found this screenshot in particular very interesting, looking like the lightning is striking a ferry on the harbour:
When showing my work to my tutors and peers, I received feedback on how it was an interesting concept (particularly with the animating thermometer), and how it was good to have the API working in there. However, Paris was cloudy with a wind speed of 0 at the time, meaning that the clouds were blocking the sun and not moving themselves, so there was no animation at all to offer to the user (this was the first time that I had come across a situation like this). I asked for feedback on how I could make situations like this more interesting and I was told that it might make it better if more information was shared so that there was more to look at in each city. My aim for this project was to create a visual generation rather than text, hence the removal of all of the text I had in the animation when I was testing it, so we thought that maybe I could show the time and create a dark overlay to show whether it was night time or day time in that city. I also didn’t really want to take too much away from the real factual information that it was giving by making it display something completely random. This may not have been offering much more animation wise, but at least it would offer the user more interesting things to take in and it would mean that it would be acting as a clock as well, rather than just a barometer. I also believed that once I populated it with more cities, it would offer a more interesting experience because the user could keep clicking through the different cities rather than looking at the same four. With only two days left until it was due (in which I had to go to work all day on both of those days), and the blogs due on the same night, I decided to have a go at adding these in as well.
I came across a few difficult situations. Firstly, I was receiving no single time value back with the weather data, only a string that had the date, time and time zone. I wanted to be able to check whether the current time was before or after sunset and sunset in that city and then display a dark overlay if the sun wasn’t up. I found this example on W3 Schools, which takes sections of a string, so I got the section of just the hours and minutes for the current time, sunrise time and sunset time. I then had to convert them to numbers and check whether the current time value was before sunset or after sunrise, and if it was make it draw a dark overlay over the image and behind the cloud.
I decided to try and add a moon in as well, in which I used my sun animation, turning it to white and removing the excess scribble outside of it’s diameter. This created a really effective look except it kept drawing it over and over just like the sun, making the moon constantly move and look unrealistic. After ages of playing around with it, I managed to get it to stop constantly being drawn by removing the random variables from the moon function and placing them in the setup, making them only change when the city changes so that a new moon is generated for each city, but it keeps drawing the same moon whilst it is on the same city. I also added a glow behind it with ellipses that increase in opacity and brightness as they get smaller. I ended up with this cool night time animation:
After getting all of the code working properly, I began to populate the generative system with different cities. This was very easy to do because of the way that I set it up. All I had to do was get the WOEID from the website that I had found earlier, place it in the cities array, and then create an image named after that city and place it in the assets folder. I kept doing this and made sure that there was a lot of cities in there so that there was a lot to look at. I also made sure that I included cities with all different weather conditions in order to increase the chances of every aspect of the animation being shown when it is run, this included having tropical cities such as Darwin to increase the chance of there being a thunderstorm included and I wasn’t disappointed:
As I added more and more cities, I surprised myself with how interesting it was becoming, being able to constantly navigate through the cities and see all of the different animations. It actually helped me to learn more about the time zones and weather conditions in different cities by being able to navigate through them and compare them so quickly. I found myself at times thinking that things didn’t seem right and maybe something was wrong (even though I felt my code was right), and then I’d Google it to find out it was in fact correct, it was just something I didn’t know about the city. For example, I saw at 7:30pm that the sun was down in Brisbane and Sydney but then when I got to Melbourne it was sunny and I thought “oh no, what’s gone wrong here?”. I Googled it to find that the sun doesn’t set until around 8pm in Melbourne.
Overall I was very impresssed with what I was able to create at the end of the semester, I felt like I had included a lot of the things that I had learnt throughout the progress of this course. Through learning the extra feature in using an API to access data, I felt like I was creating a more generative experience by using real world information to generate data. I had hoped to be able to create something with information like this since I saw the example earlier in the semester that used flight paths to create an animation so I was very happy to be able to do something like this in the end and create something that continually interests even myself.
NOTE THAT I FOUND THAT FOR SOME REASON THE ANIMATION ONLY RUNS FROM A LIVE PREVIEW IN A CODE EDITOR AND NOT FROM THE INDEX.HTML FILE