Midterm Project – Goalkeeper Challenge

Concept
As a kid, I admired strikers for scoring beautiful goals, but now I understand what a difficult and beautiful job goalkeepers have in saving their team. My admiration for goalkeeping grew, especially after watching the incredible 2022 World Cup Final between Argentina and France in Qatar.

In the game I’ve made, the player moves the goalkeeper’s gloves with a mouse or trackpad to save penalties. Each player starts with three lives and loses one for every goal conceded. Players can unlock new skins for their gloves. Making 10 saves in a single game unlocks the first skin, and reaching 15 saves in one session unlocks a second one.

The game also saves each player’s personal best record, allowing multiple users to compete and track their high scores. There is also a special golden ball: saving it grants an extra life (+1), but conceding a goal from it costs two lives instead of the usual one. The controls are simple: press ‘F’ for fullscreen and ‘S’ to view and select skins. There is also a hidden ‘R’ key to reset the game and clear all data.

Highlight of the code

function saveUserData() {
  let userData = {
    highScore: highScoreSaves,
    unlockedSkins: unlockedSkins
  };
  localStorage.setItem(currentUser, JSON.stringify(userData));
}

One smart technical decision I learned in my Intro to CS class was to automatically save each player’s progress and unlocked skins. This ensures that players don’t lose their scores and achievements when they close or reload the game. It definitely adds to the experience, making it feel like a real game that saves user accounts and their rewards.

if (dist(ball.x, ball.y, keeper.x, keeper.y) < keeper.size / 2) {
  saveSound.play();
  saves++;
  ball.reset();
}

Another important feature is collision detection, which I implemented using the mathematical dist() function. The method of checking for an overlap between two circles, which was also taught in my Intro to CS class, is a much easier way to calculate collisions in a simple game. When a collision is detected, the code plays the ‘save’ sound, increments the save counter, and resets the ball to its starting position. I think this approach is very simple, short, and super-efficient.

Sketch
https://editor.p5js.org/da3490/sketches/e03ZtWqpi

Reflection
I drew on my previous experience creating a Jetpack Joyride duplicate in my Intro to CS class to build this game’s features, including the login and menu pages, score tracking, user record saving, collision detection, and skins. While developing the UI took some time, it wasn’t logically difficult.

I would say that making the game adaptive to different screen sizes took the most effort. Instead of using fixed pixel values, I had to use percentages and mathematical relationships, such as width * 0.5 and height * 0.3. This approach was tricky but ensures the game looks and works properly on any device. I also added glow and glass effects to enhance the UI aesthetics. Using drawingContext and shadowBlur, I created transparent rectangles that produced a modern ‘glass’ look. While this style may be less popular now, it was a prominent trend in 2023-2024.

Future improvements
For future improvements, I would love to replicate FIFA-style penalties with a two-player mode: one player aims and shoots while the other plays as the goalkeeper.

To achieve a more realistic, front-facing perspective instead of the current view, I would need to implement 3D-like mechanics. This would involve angle calculations and scaling the ball’s size to create a sense of depth. The goalkeeper would use keyboard buttons to move in all eight directions (left, right, up, down, and diagonals) and would have a jump mechanic to make saves. For the shooter, the mouse would control the aim, while holding down the spacebar would determine the power of the shot.

Week 5 – Midterm Progress

Concept
I’m a huge football fan and also a huge supporter of Barcelona FC. I’ve always been fascinated by goalkeepers who do their best to save their team points. Those incredible moments of jumping their highest and catching the ball are something I would love to implement. I especially remember the incredible journey of Dibu Martínez (Argentina’s main goalkeeper) against France in the 2022 Qatar World Cup, where he saved two out of five crucial penalties, ultimately winning them the World Cup. So, I thought, why not step away a bit from my Dexter-inspired assignment and move into my other passions.

Highlight of the code

shoot(targetX, targetY) {
    this.totalSteps = random(20, 30); 

    let distX = targetX - this.x;
    let distY = targetY - this.y;

    this.dx = distX / this.totalSteps;
    this.dy = distY / this.totalSteps;

    this.isFlying = true;
    this.currentStep = 0;
}

The Ball class uses a simple, yet highly effective, trick to achieve smooth motion without needing complex physics calculations. For example, the shoot(targetX, targetY) method instead of calculating a constant velocity that needs to be constantly adjusted, the game calculates total movement distance and divides it by a random number of steps (this.totalSteps). Thus, giving the ball its speed.

Sketch

Uncertainties & Complexities
I didn’t use sounds for now and any kind of images or icons. So, I’m a bit concerned about that. Apart from that, I quite like the progress I’ve made, and I think I’m able to finish the project on time. But, if I do get to add those images and icons, and sound properly soon, I want to incorporate other essential stuff that would make the game a lot better. It took a while how do I ensure that the ball always hits the intended target, and I figured it could be easily done when the currentStep equals the totalSteps, so that’s how I keep track of whether ball should stop or not. Collision detection was a bit of struggle too, but I already did Intro to CS project, so I used as Professor suggested once to use circles to detect the collision by dist() between their radiuses.

Future improvements
I asked couple of my friends while I was in the library what do they think of the project, and some said that I could add different ball types like if you save a golden ball you get +3 points instead of +1, and if you don’t you lose -2 lives instead of -1. Also, I’m not quite sure how it works on p5js, but when we worked on Processing during my Intro to CS class, we were able to add CSV file to have a database of users, so we could keep track of best score across all users. Maybe, I will look into that and try to figure out how to add a database.

 

Week 5 – Reading Reflection

What are some of the ways that computer vision differs from human vision?
Computer is really context dependent compared to humans. We have eyes and can generally differentiate objects and perform any actions with any inputs, but no computer vision algorithm is completely autonomous. Each algorithm is dependent on its code and assumptions about the specific scene it is analyzing. If conditions such as absence of movement or poor lightning are present, then algorithm may fail.

What are some techniques we can use to help the computer see / track what we’re interested in?
As mentioned in the abstract, we need to increase the contrast more so the computer vision can differentiate between environment background and people’s movements. Those include lighting that silhouettes people, contrasting costumes. Also, using Infrared Illumination improves signal-to-noise ration in low-light conditions and retroflection marking materials.

Choosing the right imaging hardware is essential too. For example, telecentric lenses so object’s magnification is independent from the distance, polarizing filters to reduce glare from reflective surfaces, and very purposeful choice of cameras for high resolution, frame rate, short exposure, dim light, UV light, or thermals.

How do you think computer vision’s capacity for tracking and surveillance affects its use in interactive art?
It is, for sure, a core mechanism and an engine that gives power to interactive art. I strongly believe that computer vision’s ability to detect, track, measure presence, motion, color, and size completely changed how interactive art is perceived since it’s invention. Techniques such as background subtraction of frame differencing, even though simple, are very profound in how they helped to make thousands of modern interactive art installations. For example, advanced tools like EyesWeb specifically focus on the tracking and surveillance and provide ‘analysis and processing of expressive gesture’. Now, it is not just about detecting movement, but rather interpreting for specific musical or visual artistic purposes. I also think that first interactive piece called Videoplace that I read about on my other IM class gives audience agency and computer vision acts as a bridge between human input and computer’s further output much like a computer mouse, but rather detects human movement and gestures.

Week 4 – Reading Response

Don Norman’s ‘The Design of Everyday Things’ touches very important aspect of proper design that is both convenient and understandable to the user. He talks about engineer making clever decisions, but they don’t properly communicate how to use what they have developed and blames all of it on bad design. I fully agree that good design should have signifiers and have a simple conceptual model, so that in user’s head everything connects easily.

What’s something (not mentioned in the reading) that drives you crazy and how could it be improved?
I suppose most of it is done purposefully, but I hate how some website pop-ups hide the dismiss button. It is either tiny, camouflaged, or doesn’t exist. I do usually press top right corner and try to guess it’s location, and sometimes it works, but most of the time I’m redirected to a random website. I believe that such websites prioritize business over user needs, and they are not following the principles of human-centered design. The design intentionally hides the way to escape, and it is a false affordance, and in simple words a trap. Solution is quite simple, but again I don’t think companies want to respect user rights: 1. Create a clear and easy-to-click ‘X’ or ‘Close’ button. 2. Respect user’s initial goal, giving full access to the content they came for, and offer in a smaller window their additional services.

How can you apply some of the author’s principles of design to interactive media?
My friend lent me a book by William Lidwell ‘The Universal Principles of Design’, and I like how author there talks about very specific concepts, and some of the topic from there overlap with Don Norman’s ideas of simple user interface. I think for my future p5js sketches if I’m using preload() function I will be using loading indicator of a spinner to provide a feedback to the user that system is working. Also, when hovering over the button, it will change color slightly also a form of feedback, meaning that the button can be clicked. Overall, I want to create genuine and very simple system that will not confuse the user and at the core of it will be human-centered design.

Week 4 – Displaying Text

Concept
As always I just kept on with the concept of doing my assignment related to Dexter. He is part of Miami Metro Homicide division. So, I thought maybe text displaying randomly through .csv file would be a nice integration. A bit delusional, but Dexter would make a report of his killings of other bad people in a Miami Metro Case Files. It would consist of Observation, Target, Method, Justification, and Disposal rows.

Highlight of the code

// Get Observation: Go to the first row (OBSERVATION_ROW), split it, and pick one random part.  

  let observationOptions = split(strings[OBSERVATION_ROW], ',');
  let observation = random(observationOptions);

  let targetOptions = split(strings[TARGET_ROW], ',');
  let target = random(targetOptions);

  let methodOptions = split(strings[METHOD_ROW], ',');
  let method = random(methodOptions);

  let justificationOptions = split(strings[JUSTIFICATION_ROW], ',');
  let justification = random(justificationOptions);

  let disposalOptions = split(strings[DISPOSAL_ROW], ',');
  let disposal = random(disposalOptions);

Assigning each row to values from 0 to 4, using preload() function and this part of the code is the main functionality of the sketch. The code above is essential in order to split and then randomly pick a word from each row in .csv. After, by calling text() function I can easily display the randomly picked words inside the draw() function. One of the things I learnt during the class and implement is noLoop() and inside the mouseClicked() function loop() so that only when clicking the words would shuffle.

Sketch

Reflection
I like that my works are very conceptual in a sense that they follow the same storyline and are logically connected. For example, this one – it is about Dexter Morgan’s life as a blood spatter analyst at Miami Metro PD, so he has to fill out some reports on case files. Randomizing his victims, his way of killing them, justifications is a funny way to learn new concept and at the same time be interested in the work I’m doing. In the future, even though maybe not very connected to this one, I would love to learn how to do something similar to wavy patterns of blood using sin or cos functions, representing the world of Dexter Morgan. I think such patterns could be like an intro animation to the Dexter TV series with beautiful red patterns over white background.

Week 3 – OOP

Concept – Inspiration
I want to keep my portfolio for this class associated with Dexter series as long as possible because assignments are not very specific and require some kind of inspiration to make. I thought while I’m passionate about this TV show, why not save myself time and just pursue doing this assignment inspired by it. For this assignment I used OOP, classes, and different mouse functions as I mentioned in my previous post. My inspiration were blood stains on white walls. Dexter was a blood spatter analyst, and he had pictures of some in his office. So, by holding left-click and dragging across the screen user would draw thinner blood lines along the cursor, while when pressing the key, user would draw big chunk of blood in form a circle where cursor is located. Also, by scrolling mouseWheel user would be able to clean the wall from blood using pop().

Dexter Blood Splatter Pictures In Lab? | RPF Costume and Prop Maker Community

Highlight of the code

function mouseDragged() {
  if (mouseButton === LEFT) {
    marks.push(new BloodCluster(mouseX, mouseY)); // one cluster per drag
  }
}

function keyPressed() {
  marks.push(new Tomato(mouseX, mouseY));
}

function mouseWheel() {
  if (marks.length > 0) {
    marks.pop(); // remove last (cluster or tomato)
  }
}

(Do not give too much attention to class called ‘Tomato’ it is just for me to navigate throughout the code better). Apart from that, I think this part of the code the crucial rule. it helps with drawing blood lines and bigger blood drops on the wall and cleaning it using mouseWheel(). Generally, I think also using arrays to store blood stains and then applying .pop() was the part of the code that helped a lot to perform next actions. Of course, in order to understand how those functions work, I looked through p5js reference page for keyPressed() and mouseDragged().

Sketch
Initially, I had some issue with class Tomato drawing oscillating circles as blood marks and troubles with cleaning the wall from blood marks in general when using mouseWheel(). But, after storing marks inside the array, applying .pop(), and some clever code arrangement the issues were solved. To be honest, took a lot of time to figure it out.

Reflection
I’m quite fulfilled by the work I’ve done. It definitely followed my initial vision of how I wanted my final result to look like. I like how neat everything looks in code, the organization is very easy to understand. I learned new functions and wise use of arrays to store blood marks using marks = []. In the future, I want to incorporate more mouse functions in my projects to enhance the interactivity of the project like mouseReleased() would also draw some different kind of blood. Also, I would want to make specific type of blood pattern when pressing the key, so blood marks would be kind of the same – more like in real life.

Week 3 – Reading Reflection

What do you consider to be the characteristics of a strongly interactive system?
After reading Chris Crawford’s chapter on Interactivity, I would strongly agree with what he has to say. It is definitely when both parties (actors as he says) are listening, thinking, and speaking. Otherwise, in more computer terms providing input, processing, and producing output. How would we measure the strength of interactivity of each system? To be honest, as long as it has those three components, I would consider the system interactive. However, whether it is super interactive or less interactive I think depends on person’s perception of what’s is enough interactivity for artwork and what’s not. For example, for me any type solo video-game like ‘Jedi Fallen Order’ is already a peak of interactivity because you control the character, you listen what the game instructs you to do, you think, and game also challenges you too. I feel like making the user think critically and act is an excellent characteristic for strong interactive system.

What ideas do you have for improving the degree of user interaction in your p5 sketches?
The one thing that comes to my mind is how we use mouseX and mouseY commands to make something move along our cursor. Also, new commands introduced by the end of the class using mousePressed, scroll, mouseReleased are too a way to interact in p5js. I would love to incorporate more of such functions in my future sketches to express my feelings and interests.

Week 2 – Reflection

How are you planning to incorporate random elements into your work?
I think Casey Reas’s presentation of how randomness and control are somehow interconnected in computer generated art is quite on point. There is always an underlying algorithm that has some kind of order it follows in order to generate ‘random’. I remember he quoted Gerhard Richter: “Above all, it’s never blind chance: it’s a chance that is always planned, but also always surprising”. From the works I saw, I really liked the ‘Tissue Work’ because it seems to have lot of order and at the same time a little bit of imprecision, which makes those tiny vehicles draw very intricate lines along their path. I would want to incorporate the same idea of leaving a trace after a movement of certain objects, and have them follow a certain type of order as in the ‘Tissue Work’.

Where do you feel is the optimum balance between total randomness and complete control?
Casey showed us some example of Lia’s works, I want to talk about that. The first one with perfect ordered grid, when it starts to deviate somewhere there is definitely a thin line between pure random and complete control. I believe that finding such optimum balance is hard. I would say Fractal Invaders when you add a bit of symmetry to the randomness is an example of how I can create a balance between the randomness and control. Honestly, I think balance is always something audience likes in the artwork, which makes it more appealing and understandable to them. The perfect balance for me is when on one hand elements start to seemingly move randomly, but at the same time when you add more of such elements they form some kind of a pattern like in the ‘Tissue Work’. Otherwise, as I mentioned before, applying a bit of symmetry to the coin flip based randomness of black and white (referring to Lia’s Fractal Invaders) is also a perfect balance between randomness and control.

Week 2 – For loops

Concept
I am continuing the story of Dexter. I tried to incorporate as many things as we learned this week, including for loops, width/2, the mouseIsPressed function, and oscillations using the random function. What the audience sees is unstable because the varying sizes of circles are constantly changing, representing chaos when Dexter Morgan is not himself but is controlled by his inner devil, which he calls the Dark Passenger. The blood slide at the top represents him in this state, showing that he is currently in Bay Harbor Butcher mode. The frameRate is set higher to emphasize how stressed and uncontrollable he is at this point.

By pressing the button, the audience sees calm Dexter Morgan, an ordinary husband with golden wings that symbolize how kind and loving he actually is in real life when the Dark Passenger is absent. He appears more stable, with the random function set to produce smaller differences in circle sizes, and the frameRate is lower to represent that. White represents his good nature, while red represents his killings and dark side..

Highlight of the code I am proud of

if (mouseIsPressed) {
      frameRate(5);
      if(mouseX <= width/2){
      textSize(32);
      fill('rgb(255,255,255)');
      stroke(0);
      text('Dexter Morgan', mouseX, mouseY);
    }
      for (let x = 0; x <= width-460; x += 50) {
        for (let y = 100; y <= height-100; y += 50) {
      fill ('gold');
      randomNumber = random(30, 40);
      rect(x, y, randomNumber);

else {
    frameRate(30);
    if(mouseX <= width/2){
      textSize(32);
      fill('red');
      stroke(0);
      text('Bay Harbor Butcher', mouseX, mouseY);
    }
  // blood
    fill(255, 255, 255, 90);
    rect(225,10,150,80);
    fill('#AC153A');
    circle(300,50,50);
    
    for (let x = 120; x <= width-120; x += 50) {
      for (let y = 350; y <= height; y += 50) {
    fill ('red');
    randomNumber = random(40, 80);
    circle(x, y, randomNumber);}}

I would say I made good use of if and else statements. I wanted the user to press a button to see Dexter’s good side, and when not pressing anything, they would see his dark side. By adding an if (mouseIsPressed) statement along with an else, I was able to make my concept work. Otherwise, I didn’t use else statement, initially, and only had if mouseIsPressed. So, those to visualizations of white & gold overlapped with red.

Sketch

Reflection
I believe Dexter’s unstable character could be developed further. For example, I’d like to incorporate another mouseIsPressed command into his evil character, so that when pressing more, the circles’ oscillations would become faster and grow larger and larger. However, to achieve this, I need to make sure that two mouseIsPressed commands don’t overlap, so I need to come up with a creative solution.

Week 1 – Portrait

Introduction to the Portrait

Last summer, I watched Dexter (the TV series), which has multiple seasons and sequels. I really enjoyed it, and it inspired me to create a portrait of the main character. I opened a picture of Dexter on my computer and worked on the portrait in p5.js on my MacBook while I was in the library. Since I already have some background in HTML, CSS, and JavaScript, I didn’t struggle much while making it.

A quick introduction to the character: he is a serial killer who targets other serial killers, following his own moral code. His ritual involves keeping trophies from his victims, specifically by collecting blood slides after cutting their faces. In my portrait, the rotating element around him represents those blood slides, one of his signature trophies.

Code that I liked

fill(255, 255, 255, 90)
translate(300,300)
let angle = frameCount * 0.01;
rotate(angle);
noStroke()
rect(225,10,150,80)

fill('#AC153A')
circle(300,50,50)

I really like how I managed to create certain details. For example, when I wanted arcs for the eyebrows or around the ears, I achieved them by covering parts of ellipses with skin coloured shapes. I used the same method for the mouth, ears, and eyebrows. That I think involves a lot of logic. More importantly, I applied some techniques I learned from a tutorial to make the blood slides rotate around Dexter, which I thought was a great touch. So, the code above showcases rotation of the blood sample based on the frameCount. By increasing the constant, the blood sample would rotate even faster.

Reflection

For improvements: I’d like to add more interactivity and animation in the future. For example, animating blood actually dripping down his face would be a really cool effect. I could also add knife animations circling around him. Since I’m so invested in the show, I like to think of this piece almost as a self-portrait of my interests and feelings at the moment of doing this assignment. It feels very personal and entertaining to me, even if that sounds a bit delusional. For future projects, I definitely want to experiment with WEBGL to explore a 3D space. That way, I could even create a full 3D knife kit for Dexter, or add other extra details.