This week’s readings have been interesting to read. Many times the concepts of usability and beauty come into play when people make their purchases, be it the new iPhone, a new mechanical keyboard with many RGB options, or just a shirt that has a rather unconventional design. Although, this is where we enter into this curious realm (at least for me) of the real effectiveness of these products.
Let’s give a scenario: would you rather have a phone that is internally more powerful but with an old design, or have a more modern one whose design is more updated, although performance-wise it is slower? Both are going to have their software outdated at the same time; therefore, what would one person pick? If the person is inexperienced with technology, this performance difference is not notorious, but those who do gaming on phones might apply a different lens to it. Not only does beauty transmit different feelings, but it also offers different ways to use and interpret it. For example, if I am going through a software error, I prefer that the system outputs the information about the error with detailed logs (in minimalistic fashion) as they are rather than just show a blue screen with a rather, obscure error. The first is generally related to settings where people are expected to be more technologically literate, but the latter is displayed more simplistically and is easy to associate with a system crash for most people; the only downside is that the technician might spend a bit more time understanding what is exactly happening. As Norman suggests, the system has to be prepared for unlikely scenarios, as seen in Hamilton’s case right around Christmas in 1968, where some astronauts accidentally used a function accidentally, but there were functions to mitigate it.
Obviously, even for myself, I would prefer something that is appealing to both my eyes and easy to understand. This is due to personal experiences and the fact that I see a certain beauty in seeing lots of logs of reports without feeling afraid. It is very difficult for me to choose eye candy over functionality, since my lens is a more technical one.
I think I might have liked challenges since I was a kid, and the idea of trying to do something different and challenging was very compelling.
During the weeks that passed in the I.M. lab, even though some of my works seemed a bit lacking in art, I was mostly focused on the technicality of things. For example, in one assignment I was experimenting with using the mouse as a medium of interactivity, and in the other I was experimenting with the concept of “gravity and physics”. When I noticed that what I was trying to do was possible, then I focused myself on delivering the best I could in terms of what I had learned so far. Thus, presenting “Ice&Glasses”, an interactable piece of art, and also a game that focuses on delivering the player with a good auditory and visual experience with the use of nostalgic-like art and a heavy focus on the use of the mouse.
As mentioned, thanks to the experimentation I did in previous assignments, I came to the realization that, most likely, everything that I imagined was possible to apply to it, but obviously, it would require a lot of time to apply.
The whole concept of the game is not inspired in reality by other mediums, but rather by something that came into my mind while I was doing Assignment #4, in which I wanted to simulate some diamonds falling as to represent some data; in reality, it looked more like ice cubes… Sadly, that simulation was an illusion since it only took into account some distance and then stopped when it reached it.
When I thought about ice cubes, I had a weird realization. When I thought about ice cubes, the first things that came to mind were ice cubes and glasses. I searched for it on Google and came across this A.I. picture:
After seeing this, I knew what I wanted to do.
With this idea in my mind, I wanted to actually create the illusion of physics and proper gravity in the game with the use of ice cubes and cup glasses. I had the code; it was only a matter of experimenting enough to find a way to implement this without causing massive slowdowns in the computer due to the amount of “if” conditions it would require.
The code
a. Overview
In summary, it is a lot of code.
It is easily the largest code I have ever created at the moment, and I am really proud of the outcome. Some of the highlights are the following:
1. It has a system to use the mouse without it going too spammy.
function mouseReleased() {
if (mouse.called == 1) {
mouse.called = 0;
if (cubes[mouse.grabbing] == null) {
} else {
cubes[mouse.grabbing].isgrabbed = 0;
}
}
//Allows to exit the game and avoid array issues.
mouse.grabbing = "nothing";
}
2. A collision system.
function checkCollision(i, c) {
//Check collition in X axis.
if (
cubes[i].y + cubes[i].h > cubes[c].y &&
cubes[i].y < cubes[c].y + cubes[c].h
) {
if (cubes[i].type == "ice") {
if (cubes[i].insidecup == 1) {
if (
cubes[i].x < cubes[c].x &&
cubes[i].x > cubes[c].x - 25 &&
cubes[c].type == "glass"
) {
cubes[i].hit_x_r();
}
if (
cubes[i].x + cubes[i].w > cubes[c].x + cubes[c].w &&
cubes[i].x + cubes[i].w < cubes[c].x + cubes[c].w + 25 &&
cubes[c].type == "glass"
) {
cubes[i].hit_x_l();
}
if (
cubes[i].x + cubes[i].w > cubes[c].x &&
cubes[i].x + cubes[i].w < cubes[c].x + 8 &&
cubes[c].type == "ice"
) {
cubes[i].hit_x_l();
}
if (
cubes[i].x < cubes[c].x + cubes[c].w &&
cubes[i].x > cubes[c].x + cubes[c].w - 8 &&
cubes[c].type == "ice"
) {
cubes[i].hit_x_r();
}
} else if (cubes[i].type == "ice" && cubes[i].insidecup == 0) {
if (cubes[c].type == "ice") {
if (
cubes[i].x + cubes[i].w >= cubes[c].x &&
cubes[i].x + cubes[i].w <= cubes[c].x + 25
) {
cubes[c].hit_x_r();
} else if (
cubes[i].x <= cubes[c].x + cubes[c].w &&
cubes[i].x >= cubes[c].x + cubes[c].w - 25
) {
cubes[c].hit_x_l();
}
} else if (cubes[c].type == "glass") {
if (
cubes[i].x + cubes[i].w >= cubes[c].x &&
cubes[i].x + cubes[i].w <= cubes[c].x + 15
) {
cubes[c].hit_x_r();
} else if (
cubes[i].x <= cubes[c].x + cubes[c].w &&
cubes[i].x >= cubes[c].x + cubes[c].w - 15
) {
cubes[c].hit_x_l();
}
}
}
}
if (cubes[i].type == "glass") {
if (cubes[c].type == "ice") {
if (
cubes[i].x + cubes[i].w >= cubes[c].x - 3 &&
cubes[i].x + cubes[i].w <= cubes[c].x + 10 &&
cubes[c].insidecup == 0
) {
cubes[c].hit_x_r();
} else if (
cubes[i].x <= cubes[c].x + cubes[c].w + 3 &&
cubes[i].x >= cubes[c].x + cubes[c].w - 10 &&
cubes[c].insidecup == 0
) {
cubes[c].hit_x_l();
}
} else if (cubes[c].type == "glass") {
if (
cubes[i].x + cubes[i].w >= cubes[c].x - 3 &&
cubes[i].x + cubes[i].w <= cubes[c].x + 40 &&
cubes[c].isgrabbed == 0 &&
cubes[c].insidecup == 0
) {
cubes[c].hit_x_r();
} else if (
cubes[i].x <= cubes[c].x + cubes[c].w + 3 &&
cubes[i].x >= cubes[c].x + cubes[c].w - 40 &&
cubes[c].isgrabbed == 0 &&
cubes[c].insidecup == 0
) {
cubes[c].hit_x_l();
}
}
}
}
//Check collition in Y axis.
if (
cubes[i].x <= cubes[c].x + cubes[c].w &&
cubes[i].x + cubes[i].w >= cubes[c].x
) {
if (cubes[i].type == "ice") {
if (
cubes[i].y + cubes[i].h > cubes[c].y &&
cubes[i].y + cubes[i].h < cubes[c].y + 15
) {
cubes[c].hit_y_d();
}
if (cubes[c].type == "ice") {
if (
cubes[i].y > cubes[c].y &&
cubes[i].y < cubes[c].y + cubes[c].h + 1
) {
//To avoid any issues with clipping, this makes sure that every block that is inside the cup that is above it, it will share the "inside of" property.
index2 = cubes.indexOf(cubes[c]);
index3 = cubes.indexOf(cubes[i]);
if (index2 > -1) {
if (cubes[index2].insidecup == 1) {
cubes[index3].insidecup = 1;
}
}
cubes[c].hit_y_u();
}
}
if (cubes[c].type == "glass") {
if (
cubes[i].y + 45 > cubes[c].y + cubes[c].h &&
cubes[i].y < cubes[c].y + cubes[c].h &&
cubes[c].x + cubes[c].w > cubes[i].x + 10 &&
cubes[c].x < cubes[i].x + cubes[i].w - 10 &&
cubes[c].insidecup == 0
) {
cubes[c].hit_y_u();
}
}
}
if (cubes[i].type == "glass") {
if (
cubes[i].y + cubes[i].h > cubes[c].y &&
cubes[i].y + cubes[i].h < cubes[c].y + 15 &&
cubes[c].insidecup == 0 &&
cubes[c].type == "ice"
) {
cubes[c].hit_y_d();
}
if (cubes[c].type == "ice") {
if (
cubes[c].y > cubes[i].y &&
cubes[c].y + cubes[c].h < cubes[i].y + cubes[i].h - 90 &&
cubes[c].x + cubes[c].w > cubes[i].x + 25 &&
cubes[c].x < cubes[i].x + cubes[i].w - 25 &&
cubes[c].insidecup == 0
) {
//Find who cube index is inside. Also, this is really necessary to fix a bug with the cubes going out of the glass cup.
index2 = cubes.indexOf(cubes[c]);
if (index2 > -1) {
cubes[index2].insidecup = 1;
}
} else if (
((cubes[c].y > cubes[i].y - 20 && cubes[c].y < cubes[i].y - 2) ||
(cubes[c].y > cubes[i].y + cubes[i].h + 1 &&
cubes[c].y < cubes[i].y + cubes[i].h + 10)) &&
cubes[c].insidecup == 1
) {
//Find who cube index is outside. Also, this is really necessary to fix a bug with the cubes going out of the glass cup.
index2 = cubes.indexOf(cubes[c]);
if (index2 > -1) {
cubes[index2].insidecup = 0;
}
}
if (
cubes[i].y + cubes[i].h > cubes[c].y &&
cubes[i].y + cubes[i].h - 30 < cubes[c].y + cubes[c].h &&
cubes[c].insidecup == 1
) {
cubes[c].hit_y_u();
}
}
if (cubes[c].type == "glass") {
if (
cubes[c].y + cubes[c].h > cubes[i].y &&
cubes[c].y + cubes[c].h < cubes[i].y + 150
) {
cubes[c].hit_y_u();
}
}
}
}
//Check collition with table.
if (
cubes[c].y + cubes[c].h > scenario_table.y &&
cubes[c].y + cubes[c].h < scenario_table.y + 60 &&
cubes[c].x + cubes[c].w > scenario_table.x &&
cubes[c].x < scenario_table.x + scenario_table.w
) {
cubes[c].hit_y_u();
} else {
cubes[c].tempy = 1000; //Send to deletion.
}
}
3. A gravity and acceleration system.
function Gravity(i) {
if (cubes[i].y + cubes[i].h < cubes[i].tempy) {
cubes[i].gravity();
}
}
The function is the following in Cubes.js:
gravity() {
//14 seems more than enough to simulate gravity and acceleration.
if (this.acceleration < 14) {
this.acceleration++;
}
this.y += this.acceleration;
}
4. A code that helps keeps variety in the ice cubes (that means, from a single .png have different outcomes like different sizes and angles)
display() {
//Push() and pop() isolates the figure properties.
push();
if (this.type == "ice") {
//Different rotations for the same cube.
if (this.rotated == 0) {
translate(this.x, this.y);
rotate(0);
} else if (this.rotated == 1) {
translate(this.x + 30, this.y + 2);
rotate(90);
} else if (this.rotated == 2) {
translate(this.x + 30, this.y + 30);
rotate(180);
} else if (this.rotated == 3) {
translate(this.x - 2, this.y + 30);
rotate(270);
}
image(cubeimg, 0, 0, this.w, this.h);
}
b. The separation of classes
The code is divided into the following way:
Cubes.js (Has the logic for the ice cubes and glasses).
Levels.js (Originally started as a set of levels, it is now a set of rules established in order to ensure that there are gameplay elements).
Menu.js (It contains the start menu, tutorial, credits, selections, information and winning or losing screens).
UI.js (It is the information the player will not only see but be able to interact with. For example, it displays how many ice cubes are left and an icon of a door to return to the start menu).
Scenario.js (it has the code that allows the display of the scenario and the logic of the spawners).
Mouse.js (Created with the sole purpose of allowing a better use of the mouse and its events, like also allowing to store data in its class).
I also divided the graphics and sounds into their respective folders, since there were a lot of them.
c. Difficulties
The collision system took a lot of time, easily around 10 hours, and I discovered a good method by just accident since I was still trying to make it in the way of finding the distance between two objects, when in reality, the best possible solution in this case is just to continuously apply force in specific directions according to whether an object is nearby or trying to clip through it. Not only that, but using the mouse as a medium to drag other objects and still be able to display physics was very complicated.
The graphics
This is one of the parts that were actually very fast to do, maybe either to already having the idea in my mind or due to having experience in using tools such as GIMP for photo editing.
Since I wanted to capture the essence of nostalgia (like in the crayon.ai image), I had to actually go in my way to “downgrade” some images I found on Google. Here are some screenshots of the process I went through in creating these images:
Here I was just starting
A bit more of progress.
The “ice cubes”
Some of the layouts
After I finished editing all these images, since I would look very bad in full screen due to the realism of these images, I applied a filter to make them more “nostalgic.”
The process was very similar to the rest of the images.
As an important note, the ice cubes are made yellow in order to stand out even more with the glass cups, as in to allow the best possible user engagement possible by using intuition.
The sound & music
Most of the sounds I obtained accomplished their purpose, but some of them were a bit delayed; thus, I had to use a tool called “Audacity” to cut some of the delay to allow the best possible feedback for the user.
Also, the music choice was still the same, although I decided to go with the second proposed option from my report, since it reflected a more nostalgic and calming ambient:
A problem… Where is the gameplay?
Indeed, there was only one problem: Where is the gameplay? I had only created an interactable piece of art, but it really conveyed gameplay elements. For the user, it was like there was gameplay, but it could not be seen anywhere; thus, I had to come up with a solution: Divide the game between “normal” gameplay and “sandbox,” which is more of what I envisioned.
In the normal mode, the player has the established challenges of aligning the cubes and the glass cups in a visible red highlight, under a time limit, and without losing any object. The sandbox mode is just complete freedom, and there are no penalties. Also, the player has the ability to use the keyboard in order to spawn more objects quicker or to delete all of them in an instant.
Trying to figure out the gameplay.
Improvements and Conclusion
I wanted to improve the collisions a bit more and add more effects for images, but due to time constraints, it was not possible. Also, the challenges could vary more; for example, move the ice cubes to the glass cup while avoiding the red-highlighted zones that will make you lose the game immediately.
Still, I am really proud of my work, and this allowed me to have more confidence in my skills as a programmer, and also as an artist, since I had to come up with proper solutions to create the best outcome possible, while also maintaining a good (possibly thoughtful) experience for the user.
Extra content
If you want to see some progress, here are some old versions of the midterm:
This week’s reading was interesting from the technical and social sides of things. The concept of creating something for experimentation, and even art, to then transform it into a weapon of mass surveillance (and even war) is something that can provoke many thoughts. Indeed, I know that my iPhone applies many processes internally, which allowed face recognition to happen in the first place, and probably surveillance of me without my consent (just probably).
I remember when I was a child. I was impressed when I first saw another human face through Skype in 2013. Yes, the machine was just displaying a set of pixels that were observable through my screen, but the fact that another human, who was residing in another country, was actually seen was truly impressive! Then the smartphone arrived, and more complex algorithms were starting to get implemented, which allowed for further experimentation and user engagement.
Therefore, I would argue that the reading really did not change that much my views on video image processing, aside from the thought-provoking fact that a war medium originated from an art experiment. And I have not used many of the algorithms that allow modifying the perception of you through the screens of other people.
In conclusion, I would not argue that the author is biased, as he presents factual information and techniques for students or professionals to implement in their careers. Nevertheless, most information could be considered outdated as it was presented around 2006–2007. In today’s world, we have Artificial Intelligences that are capable of understanding humans and even replicating them through simulations, which can then be shared as a small clip through social media.
Since I love the concept of interactivity, I thought to myself: “It is possible to simulate physics and collisions between objects in a simple art?”. Many ideas came into my mind, but I fixed into creating something simple and, arguably, realistic: A interactable painting that displays a glass cup and ice cubes, that you can interact with and displays a sense of physics and collisions.
Design
When I arrived at my idea, I first started to narrow my vision on what is possible to make. In my previous projects, I had done things such as abstract paintings with the use of figures, and “physics” like simulation where diamonds fall and stack on top of each other (although honestly they look more like ice). Given this, I made a sketch to understand how can I implement these physics:
Me trying to figure out the collisions and physics.
And also searched a reference in Google Images for the ideas for the art, thus I arrived at this image created by crayon.ai:
In order to interact with the painting, the user only needs to point at the objects and press at them, either only clicking or holding it to be able to move the object freely. Also, the sound design for this art will be kept minimum, as art, in my opinion, should be a relaxing experience. If a glass cup falls on the wooden table, the appropriate sound will play, if an ice cube falls into the glass cup, the appropriate sound will also play.
Therefore, I found the following references for the music used is the following:
This makes me want to create a nostalgic-like art.
Or also this one, which is more classical and makes me go through a more conventional art style:
Challenges
Physics are hard to program and simulate, due to the many conditions one has to create and also ensure to keep the illusion that the properties could be seen in real life. Due to this, I had to ignore the idea of also adding rotations since it would be difficult to complete in a timely manner.
For example, my current code for collisions and gravity looks like this:
//Display cubes and apply collision and gravity.
for (let i = 0; i < cubes.length; i++) {
cubes[i].display();
//We check collision with the glasses. (Since we are simulating glass cups, the collision for the top is disabled for the glass cups}.
for (let c = 0; c < glasses.length; c++) {
//Check if it is on the X range of the table.
//Check if it is on the X range of a cup.
if (
cubes[i].x < glasses[c].x + glasses[c].w &&
cubes[i].x + cubes[i].w > glasses[c].x
) {
//I am standing on an edge of a cup on the right side?
if (
cubes[i].x < glasses[c].x + glasses[c].w &&
cubes[i].x + cubes[i].w > glasses[c].x + glasses[c].w
) {
print("right corner detected");
if (cubes[i].y + cubes[i].h >= glasses[c].y) {
}
}
//What about the left side?
else if (
cubes[i].x < glasses[c].x &&
cubes[i].x + cubes[i].w > glasses[c].x
) {
if (cubes[i].y + cubes[i].h >= glasses[c].y) {
print("left corner detected");
}
} else {
cubes[i].gravity();
}
//Please do not pass the cup.
if (cubes[i].y + cubes[i].h >= glasses[c].y + glasses[c].h) {
print("Im here 3");
}
//Nothing else we can check.
else {
cubes[i].gravity();
}
//Please do not pass
//If the cube is on the X range, then check Y axis to apply collision
} else {
cubes[i].gravity();
}
}
//We check collision with the cubes. Also, it is important to add the number 1 to avoid comparing the current index.
for (let c = 0; c < cubes.length; c++) {
//Check if it is on the X range of a cube.
if (
cubes[i].x < cubes[c].x + cubes[c].w &&
cubes[i].x + cubes[i].w > cubes[c].x
) {
//I am standing on top of the cube?
print("top of a cube detected");
if (cubes[i].y + cubes[i].h >= cubes[c].y) {
//Make a comparison.
} else {
cubes[i].gravity();
}
//If the cube is on the X range, then check Y axis to apply collision
} else {
cubes[i].gravity();
}
}
Simulating the art seems challenging, but in theory, it should be possible to finish if I add images that are similarly.
Due to the nature of this project, I want to keep the player immerse in the art while also understanding (intuitively through the elements of the painting) that it is interactable.
Keeping all the classes consistent among the shared properties. Likewise, in order to keep best programming practices, I decided to divided it into the following way:
Items:
Glass.js (Glass cup)
Cubes.js (Cubes)
Items that are part of Scenario.js:
Table (A wooden table)
GlassSpawner (Still deciding on how to represent it, because I want to keep consistency with the art)
Menu & HUD:
Menu.js (Can display both the start menu and instructions)
UI.js (Buttons that will be displayed which allows the player to return to the main menu or disable the music and/or SFX).
Audio:
Audio.js (For both music and SFX).
Risk Prevention
In order to ensure I finish the project, I need to work at least per day on it. The hours can vary since at the time I am writing this I am still a college student.
The menus are possible to make without issues, the only difficult part that risks the entire project is the creation of the physics and collisions.
Keep in mind that, if difficulties present, I can ask the professor to clarify or suggest new ideas on how to approach certain part of the code.
Used code that I made before for the physics and collisions in order to reduce time spent.
Midterm project in its current form
Here is a quick showcase of how my midterm looks as of February 26th, 2024. This will be kept as it is, to showcase the progress once it is finished:
I have not had the time to fix the cube physics, sadly. Also, keep in mind, you can move the red square with the mouse if you hold the left click.
Conclusion
This idea was born due to the need of experimenting with new, challenging ideas. Simulating these properties in a canvas is hard without using any reference, but at the end, this will help me increase my confidence as a programmer.
For this week’s assignment, I decided to stay away from displaying only basic shapes (not really) and instead do something different, as in having no inspiration from other sources. This code could arguably not be considered art in the sense that it does not portray an intriguing, thoughtful work; instead, it is more of an interactive piece of media that showcases data in an interactive way.
Since I also have a passion to try new and challenging ideas, I thought about implementing “gravity” and collisions in a database, and I decided to use the following CSV: Diamond Prices 2022. From this data, I removed some information that was not useful for this canvas. So, once I finish implementing my idea, we have the following canvas that displays falling diamonds, each one with a different price and size:
Even though it appears simple at first hindsight, it was difficult for me to properly implement the collisions without creating a code that could be considered spaghetti. I easily spent around 4–5 hours to make it work properly without the use of external tools for guidance; I generally tried to stay away from them since the idea of having a challenge is compelling for me. Furthermore, since I was also thinking about the user, I tried to implement as much information as possible to help the user understand what was going on “behind the cameras”.
As mentioned, the implementation of the collision was challenging, although I could find a way to implement it with the following code:
//Check for collision.
for (let i = 0; i < diamonds.length; i++) {
diamonds[i].display(img);
if (i > 0) {
for (let c = diamonds.length - 2; c >= 0; c--) {
if (
diamonds[i].x <= diamonds[c].x + diamonds[c].w &&
diamonds[i].x + diamonds[i].w >= diamonds[c].x
) {
if (diamonds[c].y < diamonds[i].tempy && diamonds[c].landed == 1) {
diamonds[i].tempy = diamonds[c].y;
}
}
}
if (diamonds[i].y + diamonds[i].h < diamonds[i].tempy) {
diamonds[i].applygravity();
} else {
diamonds[i].landed = 1;
}
} else if (diamonds[i].y + diamonds[i].h < height / 1.005) {
diamonds[i].applygravity();
} else {
diamonds[i].landed = 1;
}
//Check if it is safe to release another diamond given the Y and X coordinates.
if (diamonds[i].y > machine.y + 140) {
machine.safetorelease = 1;
} else if (
machine.x + machine.w - 15 > diamonds[i].x &&
machine.x + machine.w - 15 < diamonds[i].x + diamonds[i].w &&
diamonds[i].landed == 1
) {
machine.safetorelease = 0;
} else {
machine.safetorelease = 1;
}
}
//Helps to erase the last displayed diamond to avoid overlapping.
if (machine.safetorelease == 0) {
diamonds.pop(diamonds.length - 2);
machine.safetorelease = 1;
}
This code also helps to avoid overlapping between diamonds, since the machine will not stop releasing diamonds.
In conclusion, I learned a lot with this assignment, and while I wish I could find ways to implement sin()and cos(), this time at least I could do something different and challenging.
The assigned reading was interesting. It provided information on how design, readability and usability can coexist with each other. This is something that I have been looking into lately, as when you have a mind as a designer, you not only care about how things look, but rather, how can you communicate to the user everything they should know about how to operate a device without the need to go through a manual? In my life, I have been confused over several devices since they operate in strange manners. Take, for example, a modern iPad. Their power button can seem very hidden if the tablet is using a fall protector, and it is frequent that I do not find an obvious quick way to turn it on since I am not familiar with the device, so I just ask the owner to turn it on for me.
The same connection regarding design can be applied to operating systems, for example. If one person uses Windows and makes the switch to Mac, it is very likely that common features will stand out between them, but since both operating systems excel at the act of “show, don’t tell,” their UIs will often communicate to the user what a certain thing will do to avoid confusions in this shift. The same scenario cannot be applied to someone who is new to computers, as it will require more time to get used to them.
For this assignment, once again, I proceeded with going abstract, but I tried to get inspired by Dan Croll’s Music Video “Tokyo” which is animated by Simon Landrein (sadly, the video is blocked in the UAE). This video has a different approach to animating, as it contains all the visible elements inside a frame, which is also inside another frame (YouTube’s video player on this occasion). It is an interesting approach, and I wanted to try to replicate it.
Once I could replicate the frame borders with the use of line(), I noticed that it would not be enough for what I wanted to do, because if figures were drawn, they would also be displayed outside the frame. So to hide the rest of the figures, I employed rect() to cover all areas behind the drawn lines, and thus, the same technique as in the video is possible. I first started with the idea that I wanted to make the edges of each frame interactable and all the contents inside the portrait change, but soon it proved not only to be challenging, but very time-consuming, so I discarded the idea and thought about going for a different approach.
Since the assignment required me to create a “generative artwork,” I once again thought about the past week’s material, as it involved creating art with the use of algorithms and subsystems. And not only that, but I decided to once again go with the use of figures, which are, on this occasion, more interactable.
The user is free to use the mouse to interact with the canvas. If the mouse is pressed outside the frame borders, it will create new figures and a bit of an illusion; figures are emerging off the scene. And if the mouse is pressed inside the frame, two things will happen: the colors will change, and the figures will approach slowly, depending on where the mouse is. Furthermore, if the user clicks continuously inside the frame, the figures will disperse randomly.
The part of the code that I feel most proud of is where most of the interaction with the figures happens, which is this code block:
//This is to help with creating new figures, move and change color.
if (mouseIsPressed){
//Collision detection outside portrait.
if ((mouseX > 0 && mouseY > 0) && (mouseX < frame.w/8 && mouseY < frame.h) || (mouseX > frame.w/1.15 && mouseY > 0) && (mouseX < frame.w && mouseY < frame.h) || (mouseX > 0 && mouseY > 0) && (mouseX < frame.w && mouseY < frame.h/8) || (mouseX > 0 && mouseY > frame.h/1.15) && (mouseX < frame.w && mouseY < frame.h)){
createfigure();
} else {
//Move figures to current mouse position if the cursor is inside the portrait.
for (let i = 0; i < figure.length; i++){
if (figure[i].x != mouseX || figure[i].y != mouseY){
if (figure[i].x < mouseX){
figure[i].x += 5;
}
if(figure[i].x > mouseX){
figure[i].x -= 5;
}
if (figure[i].y < mouseY){
figure[i].y += 5;
}
if(figure[i].y > mouseY){
figure[i].y -= 5;
}
//Change color of items depending on mouse position.
figure[i].color1 = mouseX;
figure[i].color2 = mouseY;
figure[i].color3 = mouseX+mouseY;
}
}
}
}
In this code, an if statement is first used to ensure that the mouse is, indeed, outside the canvas to create figures with the function createfigure(). If the condition is not met, a for loop and many if statements are used to assure that the array is fully checked for each object (or figure) inside it and to then modify the attributes like X and Y position, and color. This is to be able to move them while also changing the color with the position of the mouse on the screen.
For future assignments, I will try to go for a more artistic approach and not that many uses of figures, since art can be employed in many ways rather than just going full abstract.
When I started reading the assigned material, I was entertained by the author’s voice, as it was not what I expected from a book. Not only that, but starting the chapter challenging the idea of what “interaction” means made me think, “What is that video games and productivity share?”. For example, we could argue that both of them require a certain level of concentration to be fully completed, but while one is applying all the degrees of interactivity (listening, thinking and speaking), the latter is very dependent on the activity being done. My homework can tell me what instructions to follow, but it cannot think on its own, although a video game will be able to give me feedback as its nature is more communicative; without this, video games would be unsatisfying.
Furthermore, I never imagined myself looking at a fridge as a medium of interactivity, since for me the concept of “interaction” was always applied in the medium of technology: the user does an action and the computer communicates. Regarding the design aspect of interactivity, it is complicated. While a Graphic Designer is important to ensure visual consistency throughout a project, as the author says, it is not all eye candy. Similarly to video games, there needs to be someone who can understand what steps to follow to have a good level of interaction and engagement. A video game designer would not put the hardest level at the start of the game as it would create a lot of frustration; likewise, a designer focused on intractability would not force users to write commands on a website to enter a page. All graphic and interactable elements need to coexist to allow the best user engagement possible.
I found the assigned video Casey Reas’ Eyeo talk on chance operations very interesting, as I could observe how, from the simplest of algorithms, we can create and simulate something that we can see in real life. For example, if a designer wants to create a maze without crafting everything at hand, the designer could, in theory, just make an algorithm to create a series of maze-like patterns and just translate them into real life.
Not only that, but I did not realize that real life is composed of multiple algorithms, thus changing my belief that algorithms are not exclusive to only computers. We can translate real-life algorithms into computer code to simulate them, and it is even possible to create art by combining multiple real-life systems into code. So if I want to create a piece of art that combines trees and vegetables, I find it possible to create an algorithm to create trees with vegetables on them.
For this assignment, I wanted to make something not so elaborate, but with a bit of randomness. After watching Casey Reas’ Eyeo talk, I find the concept of creating art with random elements interesting. One of the first ideas I had was to create a ball that multiplied each time it hit the wall. Despite wanting to do this, I realize that it would not have been possible due to the fact that I wanted to keep myself limited by the current knowledge taught in class. Yes, as students, we should find more information on how to do things, but in the same philosophy of designing video games, often creativity is found under restrictions.
Therefore, I decided to make something continuous, something that would fill the entire canvas with elements. For this, I particularly added the background code outside the draw() function and put it in the setup(), as I would create the illusion that many figures are being drawn at the same time. After I decided this, I wanted to create a simple algorithm that would dictate what type of ellipse, where, what color, shape and X and Y coordinates it would be. There are many variations to allow for a colorful variety of ellipses to be drawn rapidly on the canvas. Although, despite having most of the homework “finished,” I knew that it would not have been enough.
So, after a bit of thought on how to do it, I decided to add a circle that would bounce after detecting a collision with the canvas boundaries. It is similar to a practice we did in class, but that I could not finish on time due to working a bit slower than the rest of the class. The bouncing circle (or ball) was the trickiest part because I did not want to make something static, but rather entirely random to allow for different generative art.
I only used for() loops for this code as I did not find any use for while(), at least, in what I wanted to do. Also, if you click on the canvas, it will clean and reset everything. Likewise, the ball will always start on random positions, axis and at random speeds.
Particularly, I feel happy because I could figure out how to make the ball bounce every time in hits the walls. Here is the code behind it:
//Bouncing ball.
fill(0) //The ball in black color, in this canvas, looks the best (at least in my opinion).
//Check if the ball is passing the boundaries. If yes, determine the wall and assign a random X velocity and Y velocity value that keeps the ball inside the canvas.
if(cx+vx+cw>=0 && cx+vx+cw<=width && cy+vy+cw>=0 && cy+vy+cw<=height){
print("It works.");
} else if (cx+vx+cw>=width){
randomdecision = int(random(0,2))
if (randomdecision==0){
boundaryc = 2;
} else {
boundaryc = 3;
}
} else if (cx+vx+cw<=0){
randomdecision = int(random(0,2))
if (randomdecision==0){
boundaryc = 1;
} else {
boundaryc = 4;
}
} else if (cy+vy+cw<=0){
randomdecision = int(random(0,2))
if (randomdecision==0){
boundaryc = 1;
} else {
boundaryc = 3;
}
} else if (cy+vy+cw>=height){
randomdecision = int(random(0,2))
if (randomdecision==0){
boundaryc = 2;
} else {
boundaryc = 4;
}
}
//Once the wall is detected, and a decision is made as to which direction it should go, the ball will bounce according to the side, and will be randomly assigned an X and Y velocity.
if (boundaryc == 1){
vx+=random(1,5);
vy+=random(1,5);
} else if (boundaryc == 2){
vx-=random(1,10);
vy-=random(1,10);
} else if (boundaryc == 3){
vx-=random(1,10);
vy+=random(1,10);
} else if (boundaryc == 4){
vx+=random(1,10);
vy-=random(1,10);
}
circle(cx+vx,cy+vy,cw) //Once all the randomness is applied, the circle is drawn following the established rules.
This task, at least personally, was not that challenging, although I felt I could do more. For future projects, I would like for my art to have a system that allows creating certain patterns randomly.