Week 8 | Reading Response

Emotion & Design: Attractive things work better

Norman’s article explains the often misunderstood relation between design, usability, and aesthetics. It’s a refreshing perspective that challenges the notion that usability and beauty are at odds with each other. Instead, he suggests they can and should coexist, creating products that are not only functional but also visually pleasing.

I found Norman’s personal examples, like his collection of teapots, to be relatable. It’s a reminder that the objects we use daily can be more than just tools; they can be sources of joy and satisfaction. The idea that an attractive design can make a product work better may sound unconventional, but it resonates with my experiences in web development. Often, web visitors experience better browsing and interactivity with a webpage if it is visually appealing.

The discussion about the impact of emotions on design is particularly interesting. Norman’s insights into how positive and negative affect can influence our cognitive processes and decision-making make me rethink the relationship between our emotions and the things we interact with daily.

Her Code Got Humans on the Moon

Margaret Hamilton’s story underscores the significance of gender diversity in the tech field. It prompts us to reflect on the ongoing gender disparity that still plagues the industry. While there has been some progress, we’re far from achieving true gender equality in tech. Indeed, some studies specifically focused on software developers suggest that as few as 8-10% of all software developers are female [1]. Hamilton’s journey from an era when women were discouraged from pursuing high-powered technical roles to becoming a pioneering figure in software engineering is incredibly inspiring.

What strikes me most is Hamilton’s unwavering determination and resilience. Her ability to lead a team, make critical technical decisions, and solve complex problems during the Apollo project is a testament to her expertise and commitment. Her dedication to perfection and her diligence in addressing potential issues serve as a valuable lesson in the importance of rigorous testing and debugging in software development. Moreover, we need to keep in mind the time when she was working, especially in terms of technological progress. Just picture this: the thousands of lines of code we can effortlessly write, compile, and debug in a matter of seconds today were back then written and meticulously refined using the available technology of that era. Here is her photo [2] while standing next to listings of the Apollo Guidance Computer (AGC) source code.

Hamilton stands next to listings of the Apollo Guidance Computer (AGC) source code.

 

Resources:

[1] https://jetrockets.com/blog/women-in-tech-why-are-only-10-of-software-developers-female
[2] https://www.wired.com/2015/10/margaret-hamilton-nasa-apollo/

Week 8 Reading Response

Norman’s chapter on emotions in good design was enlightening and reminds us that humans are more than just rational, logical machines. People appreciate art and beauty, and I suppose that even in the field of design, where ones of the goal is to make something as logically simple for a user as possible, there is still room for aesthetics. He wrote that ‘attractive things work better’, and I was reminded of how that applies to human interactions too — pretty privilege is a real thing. “Pretty people are perceived as smarter, funnier, more sociable, healthier, and successful” (First link I found on Google). Between two teapots that achieve the same goal of brewing tea, the more attractive design is usually the favored one, and sometimes you might even be willing to give up some functionality in favor of the design. Norman also talks about how different designs might be interacted with depending on the user’s mood or situation. In a stressful situation, a panicking user might not know how pull the fire doors, and might just push harder. This principle should be applied to all manners of design, and consider users that might not have the privilege of the time of figuring out a badly-designed place. For example, a hospital should be well-designed and clearly marked, because a panicking person bringing in their mother will not have the mental capacity to stand and read signs on where the Emergency Room is.

I found the anecdote in Margaret Hamilton’s article on her repeatedly warning the higher-ups about a potential bug really funny, and representative of the experiences I have had so far. A common design principle is to assume the user is stupid. Any error that is possible to be made can be made, even if they’re trained, or given the manual, or even if there’s a written “Do not Touch” sign in front of the object they’re not supposed to touch. From a design perspective, they have done everything right — verbally warn the astronauts not to touch the program, add a reminder in front of the screen to not touch the program. Yet, the astronauts touched the program even when it is usually not run in this scenario. Designs should always have tolerance for fault, no matter how unlikely the fault is. Of course, not every fault can be covered, for example you can’t design a door that can handle being torn apart by someone, so there should be some risk-reward management. How unlikely is it for this fault to be encountered, and how bad will it be if this fault is triggered? In the case of Hamilton’s code, the fault was unlikely to be triggered, but it causes a very scary crash with data loss if it was triggered, thus it would made sense to guard against that case, though I am saying this with the gift of hindsight.

Week 8 reading reflection ( both in the same post )

Emotions & Attractive by Donald A.Norman

The reading about three teapots is incredibly inspiring and thought-provoking. It goes beyond a simple story about teapots and delves into the profound world of human emotions and how they influence the design and usability of everyday objects.

What’s truly inspiring is the notion that design is a delicate dance between beauty, functionality, and user satisfaction. The three teapots exemplify this concept, teaching us that an object can be beautifully designed, functional, and a source of pleasure simultaneously. It’s a reminder that design should not be limited to either aesthetics or usability; it’s about achieving a harmonious balance.

The concept of “affect” introduced in the reading is particularly eye-opening. It showcases how our emotional state can dramatically alter the way we approach tasks and interact with products. Negative affect narrows our focus, enhancing concentration, while positive affect encourages creativity but also increases distractibility. This revelation challenges our traditional understanding of how emotions influence our behavior.

The most striking and, indeed, inspirational revelation is the idea that attractive things work better. This contradicts the common belief that aesthetics are secondary to usability. It suggests that, in our pursuit of enhancing functionality, we should not neglect the importance of creating products that are visually appealing and emotionally engaging.

In a world where we often prioritize utilitarian aspects, this reading encourages us to look beyond the surface. It teaches us that true beauty in design encompasses both form and function. The lesson is clear: we should aim to create products that not only serve their purpose but also bring joy and delight to our lives. This reflection challenges us to think differently about the objects we use daily and to strive for a world where everything we interact with is not only usable but also a source of inspiration and pleasure.

Her Code Got Humans on the Moon

What’s really interesting in this reading is the incredible journey of Margaret Hamilton. She was a woman who, in the 1960s, went against the norm. Back then, women weren’t usually encouraged to do high-tech jobs. But Margaret, with her math degree, got a job as a programmer at MIT. Her original plan was to support her husband’s law studies for three years and then get her own math degree.

But things changed when the Apollo space program came into play. Instead of following her original plan, Margaret stayed at MIT and led a big engineering project. She was among the very few women in that era to do this kind of work. What’s striking is that she brought her 4-year-old daughter, Lauren, to the lab on weekends and evenings. While her daughter slept, Margaret was busy writing code that would be used in the Apollo mission.

People were surprised by her dedication. They’d ask her, “How can you leave your daughter to work?” But Margaret loved her unique job. She enjoyed the camaraderie and the challenges of it. She felt like “one of the guys.” What’s intriguing is that, at that time, nobody really knew what software was. It was like the “Wild West” of technology. There were no courses or training programs for it. But Margaret and her team were pioneering the field as they wrote the code for the world’s first portable computer used in the Apollo program.

What’s also fascinating is that when the Apollo project began, software wasn’t a big deal. It wasn’t even mentioned in the mission’s engineering requirements. But as the project progressed, it became clear that software was essential. Margaret became responsible for the onboard flight software on the Apollo computers. The pressure was intense. She even rushed back to the lab after a late-night party once to fix a piece of flawed code. She worried about making headlines for a mission failure.

In the mid-1960s, more than 400 people were working on Apollo’s software. Software became a key part of winning the race to the moon. But it did more than that. Thanks to Margaret and her team, they set the stage for the software industry we know today, worth billions of dollars.

The process of programming back then was completely different from what we have today. They punched holes in stacks of cards, and these cards were processed on a massive computer. Everything had to be simulated before the actual mission.

Apollo missions carried two special computers: one in the lunar module and another in the command module. These computers were unique. They were designed by MIT engineers and were among the first to use integrated circuits instead of transistors. The computer was responsible for many critical tasks, even though it had very limited memory and computation speed compared to today’s standards.

One particularly intense moment was during the Apollo 11 mission, just before landing on the moon. There was a “documentation error,” and the computer started giving error messages. But thanks to Margaret’s technical arguments, the computer focused on the most crucial task—landing safely on the moon.

Another intriguing detail is how Margaret’s daughter, Lauren, once caused an error during a simulation. This led to changes in the documentation to prevent similar errors. It shows that even in highly technical fields, human elements and foresight play a role.

In the end, what’s most captivating about this reading is Margaret Hamilton’s exceptional journey. She not only helped land humans on the moon but also played a crucial role in shaping the software industry. Her story is a reminder that one person’s determination and innovation can have a significant impact on history.

Week 8- Reading Reflection

“Emotion and Attractive” by Donald A. Norman and “Her Code Got Humans on the Moon- And Invented Software Itself” by Robert McMillan

We were assigned to read two different materials with varying ideas, but both were thought-provoking. 

I would like to start with the most influential article about the mother of software engineering- Margaret Hamilton. She is a living example of the phrase “everything is possible”. While reading the text, I immediately thought about the photo of her standing next to the tons of coded papers- Apollo code. The reading material tells more about the background of that photo, showing the first gigantic step toward software engineering. Her dedication to work and the result of her achievements impressed me the most. Imagine writing the code to the system, which gets the humans on the moon and back when no one even had an idea what the software engineering was. Her biography leaves me astonished every time I read it. 

Scene at MIT: Margaret Hamilton's Apollo code | MIT News | Massachusetts  Institute of TechnologyFig. 1. Scene at MIT: Margaret Hamilton’s Apollo code | MIT News | Massachusetts Institute of Technology. Source: margaret-hamilton-mit-apollo-code_0.jpg

Discussing the reading “Emotion and Attractive” by Norman, I would like to say that the reading told the basic things, which are usually overlooked by the designers. In other words, he mentioned such a foundational, yet significant aspect of the design that is neglected in the production of the goods and services. Making a connection with the previous reading “The Psychopathology of Everyday Things”, I would like to suggest that the complexity of the things is part of the “ugliness” of the goods. The point of view of the author is that the aesthetics of the product is more than its facade, including usability, understandability, and easiness along with beauty. However, I think that this focus on aesthetics may vary depending on the context because the things made for emergency situations need to be as simple and as understandable as it is possible, giving less attention to physical appearance, while the things for the occasional use in free time or for professional purposes can give the priority to the aesthetics. Furthermore, I would like to admit that his idea that the beauty of the product stimulates cognitive thinking better could convince me. We tend to put more mental effort into understanding the usage of the thing subconsciously if we find that appealing than non-attractive things. This might vary depending on the mood and the conditions. He gave a well-drawn example of that with the teapots. If you are in a mood and have free time, you would probably go with the most aesthetic teapot even if it’s not the most user-friendly, but if you are in a hurry, the most usable one, even if it’s not the most pleasurable one. Overall, it can be concluded that Norman emphasized the fundamental aspect of the design in clear terms and examples, which resonates with my perspective of the significance of the aesthetics of products.

Final Midterm Project

Midterm Project Link: https://editor.p5js.org/jiho.choi/full/Iz4oCo4Lf

I wanted to make my Midterm project personal and the first thing that naturally popped into my mind was music. Music is such a big part of my life and I can confidently say that I probably will never be seen anywhere without my earphones. The original plan was to incorporate illustrations to use as music backgrounds, but I was experiencing an art block after my comlab webcomic assignment. I physically couldn’t get myself to draw again so instead I decided to code and make use of my knowledge thus far. Essentially, different songs would show different illustrated backgrounds that corresponded to my most profoundly remaining memory of that music. Whilst the backgrounds came off a bit cliche, it was still an honest memory so I was somewhat fine with it. Because my past assignments lacked a clear focus on aesthetic appearance I tried my best to achieve that particular quality. I thought a vintage radio graphic would look more visually pleasing and doable to code so that was the path I stuck with.

The way it works:
1) press play ==> music plays.
2) pause music ==> background changes to default.
3) skip button + play button ==> plays next song.

This process wasn’t at all a fond memory but instead was incredibly taxing, stressful and frustrating. Up until coding the vintage radio, things were going very smoothly and I was having so much fun… but once it got to coding the backgrounds, there was rapidly building friction. I was unfortunate enough to experience first-hand the importance of manually saving your code every 10secs. I had spent 6 hours coding my bg#1 and I thought it was autosaving as I went. Clearly I was wrong and the webpage malfunctioned and gave me the: “something went wrong” page…
But overall I’m proud that I was able to pull off what I would consider in my books a complex piece. Again, I used assignment#3 as a a guiding reference to creating my own version of this piece.

Parts I am most proud of:

function mouseClicked() { 
  let x = 337; // x-coordinate of the second ellipse
  let x2 = 387; // x-coordinate of the third ellipse

  if (mouseX >= x - 20 && mouseX <= x + 20 && mouseY >= 471 && mouseY <= 511) {
    if (song.isPlaying()) {
      song.pause();
    } else {
      song.play();
    }
  } else if (mouseX >= x2 - 20 && mouseX <= x2 + 20 && mouseY >= 471 && mouseY <= 511) {
    if (playButtonCount === 0 || playButtonCount === 2) {
      currentSongIndex = (currentSongIndex + 1) % songs.length;
      song.stop();
      song = loadSound(songs[currentSongIndex]);
      if (playButtonCount === 0) {
        song.play();
        playState = 1;
        playButtonCount = 1;
      }
    }
  }
}

1) mouse click function to control when the music plays and pauses and skips to the next song. This I really had to sit down and think and for some parts, especially those requiring maths (marking down the boundaries of buttons) it was more trial and error and once again hardcore searching on google.

class Wave {
  constructor(xIncrement, yIncrement, xoff, yoff, color) {
    this.xoff = xoff;
    this.yoff = yoff;
    this.xIncrement = xIncrement;
    this.yIncrement = yIncrement;
    this.color = color;
  }
  displayWave(yOffset) {
    fill(this.color);
    stroke(255);
    strokeWeight(3);
    beginShape(); //creating wave shapes in variation 
    for (let x = 0; x <= width; x += 3) {
      let y = map(noise(this.xoff, this.yoff), 0, 1, 600 + yOffset, 700 + yOffset); //determining minimum/ maximum height of waves
      vertex(x, y);
      this.xoff += this.xIncrement; //increments this.xoff by this.xIncrement 
    }
    this.yoff += this.yIncrement; //increments this.yoff by this.yIncrement 
    vertex(width, height + yOffset);
    vertex(0, height + yOffset);
    endShape(CLOSE); //
  }
}

2) I had been googling different ways people had used p5.js to embody beach art and I spontaneously came across the noise function used by someone with really high qualifications. Of course the code was way too complicated for me to understand fully let alone use so I continued browsing but found another more helpful link, by p5.js. I used the code provided and tweaked around with numbers to understand what each line of code did and what role of the numbers were, since there were a lot… Similar to the one above this also required a lot, A LOT  of trial and error, especially with creating multiple wave layers(?) which took up half my day.

IMPROVEMENTS: There is a lot I’d like to mention for improvements…
1) firstly, I didn’t realise the space in the radio handle was opaque. I was on a race against time and so couldn’t afford to really observe the drawing. This is especially such a shame since it really cuts back on the aesthetics.

2) Another thing I’d like to mention is the fact that the details of the background aren’t quite clear because the radio size is too big. Of course I already went through a prior episode and so didn’t think it wise to change all the numbers relating to class: radio. Instead I opted to make the canvas bigger, originally it had been 800, 800. (prior episode==>) This too was an incredibly onerous process because every positioning detail relies on coordinates. So I had to go through each line of code to adjust the numbers, of course I’d like to believe that there is a much better solution but again, with my current knowledge on coding, this was the best I could come up with.

3) the requirement for this project was that a loop is required, a way to reset the experience. That was what my on/ off button was for. My plan was that when the on/off button was pressed when music was playing, music would pause. But if button was pressed when no music was playing, song would restart and automatically play. This for the life of me would not work. Somehow I got the last 2 buttons to work yet the first one was refusing to cooperate. If I tried to implement some code targeting the first button, then the interaction for the last button would not work. Of course I still have not been able to conquer this specific part of the code…

4) music backgrounds… This gave me such a headache I spent almost 5-6 hours trying to look for a solution but came up with zilch. When I tried to integrate the codes from e.g., sunset.js to sketch.js (my main sketch file), for some reason which to this day I still don’t know, the positioning, stroke weight and order of shapes went haywire. I really cannot think of a reason why since the backgrounds were created on a same-sized canvas. Because I couldn’t present a blank, half finished project, I had to compromise by uploading the png form of these javascript files, which didn’t look too bad. It just looked a bit dull since everything was static.

5) another thing relating to background, I felt like there was a big quality difference in bg#1 and bg#2 which still really irks me and leaves me feeling dubious about the quality of my project. For next time, I’d like to really delve into and experiment with the cool p5.js effects before contemplating a design because that’s how I discovered the noise function. Through serendipitous search!

6) finally along the way a part of my code ceased to work: click radio = radio change colour. There was too much to keep track of and if one thing worked, another didn’t, so I don’t even know at what point it stopped working. I ran out of time at the end and I am planning to go through to try and solve the issue.

Links and images to separate relating javascript files:


background#1 – “rises_the_moon”:
https://editor.p5js.org/jiho.choi/full/G8s6Rfgxn

background#2 “in_my_room”:
https://editor.p5js.org/jiho.choi/full/koRh51OvD

 

 

 

 

 

Midterm Project

Full Link to the Project: https://editor.p5js.org/MayaLeeeeee/sketches/-N67RBhJJ

Project: Hey, Breathe

*** The project is shown cut-off due to the layout of the Intro to IM page.

Concept)
The overall concept was to create an interactive game, where the movement of the player would depend on the voice of them. I initially planned to use both pitch and volume for the movement. (Higher pitch would move the character up, lower pitch would move the character down; higher volume would make the character move faster,  lower volume would make the character move slower).

However, as I continued with my work, I had to change that. Although playing with the pitch of sound was interesting (the playing of the game was really funny), it was absolutely impossible to play the game. The pitch changed so much that the character couldn’t stay still and it continuously spiked up and came down. I tried to manipulate it, but there was not much I can do to lower the sensitivity etc.

So, I changed the up and down movement to arrow keys. However, I did keep the idea of the input sound’s volume deciding how fast the character is moving. I wanted the character’s x position to stay still, so this eventually became the speed of the map moving.

Methods)
Basically, I have 3 elements in my game: character, obstacles, and collectibles. The red circle is the player, the black box the obstacles, and the green circles the collectibles. For the obstacles and the collectibles, I had to find a way to keep track of their locations, so that I can check if the player has hit the obstacle or has collected the collectible. I do so by using an array.

for (let i = obstacles.length - 1; i >= 0; i--) {
    obstacles[i].move(characterSpeed);
    obstacles[i].show();
    if (gameStart && character.hits(obstacles[i])) { //check if it hits obstacles
      console.log("Game Over");
      isGameOver = true;
      song.play(); //sound effect for when game over
    }
    if (obstacles[i] && obstacles[i].offscreen()) { //if offscreen, delete the obstacle from array
      obstacles.splice(i, 1);
    }
  }

I push a new obstacle/collectible into the corresponding array. I also use splice when I check if there’s anything off screen. I check the locations of obstacles and collectibles, see if they’re off screen, and if so, delete them from the array by using splice.

Future Improvements)
There is a bug where if the volume of the input sound is too big, the player passes right through the obstacles and doesn’t end the game. I am guessing that the speed of movement is quicker than the speed of checking (or something like that), and the program is not perfectly checking all the obstacles etc.

*** sound used: https://freesound.org/people/MATRIXXX_/sounds/345666/

Midterm Project

Fullscreen link: https://editor.p5js.org/fhgggtyf/full/_GaqN8_Sa

Overall Concepts

The concepts didn’t change much compared to what I thought of when planning. However, instead of staring with randomly generated maps, I chose to use the original map for the first few levels so that the difficulty won’t get too insane at the beginning. Then, after the user is familiar with the game, they will encounter randomly generated maps which are insanely difficult. The main gameplay is the same with the original Pac-Man version, but the success condition for finishing a level no longer is to eat all pellets but also reaching the portals to get to the next level. Each level has a theme which is rotated in a pool of three: fire, wood, and water. Each theme has its own sets of environment and music. This is because I do not want this game to only feel like a game to the user, but feel like a real adventure in various landscapes. The player also gets a record of their final score after their 3 health is depleted. The four ghosts each have a different logic system of pursuing the player, and the mode changes of the ghosts are coherent with the original game. As levels increase, scatter mode and chase mode ratios will change to make difficulties higher.

Implementation

The game is mostly separated into 3 modules: Game, Player, Ghosts. It could be divided to make the structure clearer but since its not such a big project I decided to keep it simple.

The game module is responsible for controlling how the game progresses. There are 3 game states, which are start, in game, and game over. In the in game state, it is responsible for the game interactions, level states, and sending signals to the ghosts making them go to different modes. There should be a game effect controller to do this but I integrated the elements into the game module instead. Basically, this module controls all in-game state changes and the program state changes.

the player module is responsible for taking in inputs and converting it into actions of the player object. it also contains stats of the player.

The ghosts module is used for calculating the actions of the ghosts. each ghost have its own rules in pursuit of the player. Also the ghosts have different states, which would effect their destination points. Overall, All ghosts have the same rules pursuing a certain destination point. However, different ghosts usually have different destination points due to their unique behaviors. Therefore I have subclasses inheriting the Ghosts class so they can determine their own destinations. These squares refers to their different destination points based on their behaviors. The squares in the following image stands for the destinations of each of the ghosts.

The code is shown below.

class Ghosts{
  constructor(){
    this.position=[1,1];
    this.img=blinkyImage;
    this.vulnerable=false;
    this.addPointFlag=false;
    this.absPos=[round(this.position[0]),round(this.position[1])];
    this.prevAbsPos=this.absPos;
    this.state=0;//prepare state
    this.dir=[1,0];//no direction
    this.speed=ghostSpeed[game.gameLevel];
    this.dest=[0,0];
    this.next=[0,0];
    this.sur=[[this.absPos[0],this.absPos[1]-1],
              [this.absPos[0]+1,this.absPos[1]],
              [this.absPos[0],this.absPos[1]+1],
              [this.absPos[0]-1,this.absPos[1]]];
    this.choices=[];
  }
  
  checkState(){ // Check ghost's state to determin action
    if(this.state==0&&this.absPos[1]>11){
      this.resetMode();
    }
    else if(this.state==9){
      if(this.absPos[0]==13&&this.absPos[1]==15){
        this.state=0;
        this.addPointFlag=false;
      }
    }
    else{
      if(game.frightened && game.frightenedTimer<=7){
        this.frightenedMode();
      }
      else{
        this.vulnerable=false;
        game.frightened=false;
        game.frightenedTimer=0;
        if(game.cycleTimer/(int(chaseTime[game.gameLevel])+int(scatterTime[game.gameLevel]))<=5 && game.cycleTimer%(int(chaseTime[game.gameLevel])+int(scatterTime[game.gameLevel]))<scatterTime[game.gameLevel]){
          this.scatterMode();
        }
        else{
          this.chaseMode();
        }
      }
    }

    
  }
   
  defeatedMode(){
    this.state=9;
    this.img=eyesImage;
    this.dest=[13,15];
  }
  
  resetMode(){
    this.dest=[13,11];
  }
  
  checkMoved(){ // check if the ghost moved a whole block, if moved calculate new destination
    this.absPos=[round(this.position[0]),round(this.position[1])];
    this.sur=[[this.absPos[0],this.absPos[1]-1],
              [this.absPos[0]+1,this.absPos[1]],
              [this.absPos[0],this.absPos[1]+1],
              [this.absPos[0]-1,this.absPos[1]]];
    if(this.absPos[0]!=this.prevAbsPos[0] || this.absPos[1]!=this.prevAbsPos[1]){
      this.calcMovement();
      this.prevAbsPos=this.absPos;
    }
  }
  
  calcMovement(){ // calculate new destination and how to get there
    this.choices=[];
    this.sur.forEach(element => {
      if((element[0]!=this.prevAbsPos[0] || element[1]!=this.prevAbsPos[1]) && mapData[game.mapNum][element[1]][element[0]]!=1){
        if((this.state != 0 && this.state != 9)&& mapData[game.mapNum][element[1]][element[0]]==3){
        }
        else{
          this.choices.push(element);
        }

      } 
    });
    
    if(this.choices.length==0){
      if(this.absPos[0]==1 && this.absPos[1]==14){
        this.position=[26,14];
        this.absPos=[round(this.position[0]),round(this.position[1])];
        this.choices.push([25,14]);
      }
      else if(this.absPos[0]==26 && this.absPos[1]==14){
        this.position=[1,14];
        this.absPos=[round(this.position[0]),round(this.position[1])];
        this.choices.push([2,14]);
      }
    }
    
    let closest = Infinity;
    
    this.choices.forEach(element => {
      
      let difference = sq(element[0]-this.dest[0])+sq(element[1]-this.dest[1]);

      // Check if the current element is closer than the previous closest element
      if (difference < closest) {
        closest = difference;
        this.next = element;
      }
    });
    
    this.dir=[this.next[0]-this.absPos[0],this.next[1]-this.absPos[1]];
  }
  
  moveToNext(){ // move
    if(this.dir[0]!=0){
      this.position[0]+=this.dir[0]*this.speed*deltaTime/1000;
      this.position[1]=this.absPos[1];
    }
    else{
      this.position[1]+=this.dir[1]*this.speed*deltaTime/1000;
      this.position[0]=this.absPos[0];
    }
  }
  
  frightenedMode(){
    this.vulnerable=true;
    this.img=vulImage;
    if(this.choices.length>1){
      this.dest=this.choices[floor(random(this.choices.length))];
    }

  }
  
}

class Blinky extends Ghosts{
  constructor(state,dest,position,img){
    super(state,dest,position,img);
    this.position=[13.5,11]
    this.img=blinkyImage;
  }
  
  scatterMode(){ // Scatter mode determine destination
    if(this.state!=2){
      this.dir[0]=-this.dir[0];
      this.dir[1]=-this.dir[1];
      this.state=2;
    }
    this.dest=[27,0];
  }
  
  chaseMode(){ // Chase mode determine destination
    if(this.state!=1){
      this.dir[0]=-this.dir[0];
      this.dir[1]=-this.dir[1];
      this.state=1;
    }
    this.dest=player.position;
  }
  
  display(){
    if(this.state!=9 && this.vulnerable==false){
      this.img=blinkyImage;
    }
    fill("red");
    // rect(this.dest[0]*40,this.dest[1]*40,40,40);
    image(this.img,this.position[0]*40,this.position[1]*40,40,40);
    fill(0); // Set the text fill color to black  
  }

}

In the code above I only shown one subclass so that it won’t be too long. The basic concept of the subclasses are similar. I am pretty proud of this part because the structure is clear and it made the development progress so much easier.

Areas for Improvement

Some areas of improvements could be the aesthetics of the different scenes. I planned to do a pixelated low-poly tile-map styled map design but it turned out to look very unnatural and dirty. If I have more knowledge in graphic design I might be able to do better. Another thing is that the program has a few minor rule bugs that may allow the user to gain points incredibly fast (with a great risk). Maybe I’ll fix them in the future. Also, the random maps may cause the ghosts to behave abnormally because of the limitations of a 43-year-old algorithm. It could also be refined. Also a user login system could be applied to store people’s personal bests online. Apart of random maps, I could also add one way areas or blockages that would slow the player down, etc. But that would require refines in the ghosts’ AI, which I didn’t have time to do in this project.

Midterm Presentation: The Designer Chair Plunge

Sketch:

Link to full screen: https://editor.p5js.org/llluka/full/EZEndFCFm

https://editor.p5js.org/llluka/sketches/EZEndFCFm

Concept:

The game, titled “Designer Chair Plunge,” is a fun and interactive experience that puts players’ reflexes and decision-making skills to the test while exploring the world of designer chairs. The goal is for the player to save a designer from a risky fall, guided by a humorous story in which the chairs are personified as fighters. As the player, you select your “fighter” from a range of well-known designer chairs including Barcelona, Eames, Panton and Wassily chairs, and the classic white plastic chair is added for the humorous effect. When the game begins, you must manipulate your chosen chair in order to capture a falling designer.  Your score rises with each successful rescue. However, be careful not to let a designer plunge to the ground, as this will result in an offensive game over. “Designer Chair Plunge” combines design appreciation and gaming components, creating a novel and enjoyable way to interact with the world of furniture design.

Technical Implementation:

The game is built on the p5.js framework utilizing object-oriented programming. There are various screens in the game for the introduction, chair selection, gaming, and ending. PNG images and sounds are used in the technological implementation to create an immersive experience. Chairs and designers are represented by images, and interactions are managed through mouse input, where the player selects their chair and attempts to catch designers falling from the top of the screen. The game keeps track of the player’s score and ends the game if a designer hits the ground. The “restart” function not only resets the game state but also ensures the music restarts from the beginning, creating a consistent and enjoyable audio experience for the players. Here is the code for the restart function:

function restart() {
  screen = 0; // switch to intro screen
  score = 0;
  designer.reset();
  designer.speed = 2; // reset the speed of the fall
  mozart.stop(); // stop currently playing sound
  mozart.play(); // start the sound from the beggining
}

Moreover, the falling designer figures are randomized from 3 distinct images. Here is a function inside my Designer class that handles that:

display() {
    if (this.r < 0.3) {
      image(subject_1, this.x, this.y, this.width, this.height);
    } else if (this.r < 0.6) {
      image(subject_2, this.x, this.y, this.width, this.height);
    } else {
      image(subject_3, this.x, this.y, this.width, this.height);
    }
  }

Nevertheless, an important part of the game’s look and feel is not in the code. At first, I experimented with different images of the chairs found online, however, nothing really seemed to match my vision for the game. Therefore, I decided to draw the chairs myself to give the experience a unified aesthetic. Here are my PNG images (I used Adobe Fresco on my iPad to produce them):

 

 

 

 

 

Reflection:

I am very happy about the final look and feel of the project. It turned out  exactly as I imagined it to be (refer back to the moodboard in Midterm Progress #1). I am especially satisfied with the concept and design of the game, and how I managed to create and maintain a unified feel of the mid-century modern aesthetic with the tiny details such as my own drawings, sounds, and the two graphic images. I also applaud myself for the humorous aspect of the game – there is no way to “win” the game, and thus the designer is never going to be satisfied, just like in the real life.

Mid-Term project

Link to the sketch: https://editor.p5js.org/nafiha/full/215NRUgea

Concept : From the beginning of my mid-term project, I was inspired to create a cooking game, a passion that has been with me since my childhood. Initially torn between the realms of cooking and baking, I eventually decided to choose baking, given my fondness for it. However, as I started on the journey to develop the game, I soon realized that simulating baking was a far more complex task than actually baking in the real world.

Over the past few weeks, I hunt through into the mechanics of enabling users to click on various ingredients and watch them smoothly move towards a designated destination, such as a mixing bowl or even autonomously. I began with simple shapes like circles to grasp the fundamentals of this interaction. I focused on the feature of clicking on ingredients rather than implementing a drag-and-drop functionality, mastering these concepts before delving into the coding aspects.

What particularly piqued my interest was a class where our professor taught us how to create a dynamic, moving background. I decided to incorporate this element into my game, kickstarting my coding journey. The concept is intentionally straightforward and minimalist to ensure a hassle-free user experience. Upon starting the game, the required ingredients will be presented. Users need to simply click on each ingredient to successfully complete the game. Once the game is won, a cupcake will appear and they have the option to restart and play again. A picture of the sketch which was initially done to practice the method has been attached.


Part of the code that I am proud of  : This is the picture that I drew as a screen for instructions. The part of the code that I am especially proud of is when I learned to add the moving background as I mentioned earlier and to click on images from the computer to add on. And learning the function of lerp, was also exciting.

if (img.moving) {
// Move the image towards the center of the screen
let targetX = width / 2 - img.size / 2;
let targetY = height / 2 - img.size / 2;
let speed = 0.5; // Adjust the speed as needed
img.x = lerp(img.x, targetX, speed);
img.y = lerp(img.y, targetY, speed);
}
image(img.image, img.x, img.y, img.size, img.size);
}
}

Areas for improvement: Throughout the development process, I encountered numerous challenges, some of which I successfully resolved, while others remained elusive. Initially, I struggled with the issue of smoothly transitioning from one screen to the next, a task that seemed quite discouraging. After acquiring the necessary skills to address this, I then faced the problem of the background image overlapping with the added objects, which required a significant amount of time and effort to pinpoint and rectify.

In addition to these hurdles, I had originally intended to implement a time limit for the ingredient addition phase, which I, unfortunately, still couldn’t figure out. Nevertheless, apart from the time limit issue, I managed to overcome every other challenge that came my way.

midterm project: a life odyssey

link to sketch: https://editor.p5js.org/parchinkos/full/6Wh1hDMjG

link to p5.js web editor: https://editor.p5js.org/parchinkos/sketches/6Wh1hDMjG

(for some reason the initial start screen music doesn’t play on full-screen)

concept:

I knew from the beginning that I wanted to make a game. The aesthetics I had in mind for my project were always there, too – I’m a huge fan of 16-bit and 8-bit pixel art, and I knew I wanted to incorporate that art style into my work. I was also torn between the type of game I wanted to make; I could make it a complex story told through an RPG game format, or I could lean towards something more simple but with more gameplay. In the end, I ended up doing the latter, because it held one’s focus on the project for much longer. The gameplay for my project was inspired by simple platform games like Google’s T-Rex runner game or even Flappy Bird. Essentially, the player stays in one position throughout the game but has to avoid obstacles and/or hurdles throughout the way. My game has collectibles, which the player gathers for points, and obstacles which the user has to jump/avoid or else they lose points.

The main thing that I thought about was what I wanted the setting of the game to be. This semester, I’m taking a core class called Hindsight which focuses a lot on autobiographical story. So naturally, my mind went towards something similar: different life phases for different levels. Initially I was making it my own, but then I realized it would be infinitely more interesting if I loosely based the levels around my father’s life. He’s lived through much more different ‘settings’ (I’ve been in a city for my entire life). The game isn’t super focused on his life story, but the general inspiration for each level can be seen below.

chapter 1: the simple life

My dad grew up in a village, and on a farm, so the setting of this level is inspired by that! You also collect mangoes because that’s his favorite fruit.

 

 

chapter 2: the concrete jungle

In his late teens/early twenties, he moved from his village to Karachi, a large metropolitan city. It was his first time being in such an environment, so the level is based on the novelty of that. Cars, crows and rats are things one often finds in big cities like this which is why they’re the obstacles.

chapter 3: setting sail

After completing training at his cadet college (which was why he moved in the first place), my dad officially joined the Navy. He spent a lot of time at sea in his early years, which is why the last level he’s on a boat. At first I wanted there to be fish or something, but that seemed a bit difficult so I just settled on making the obstacles birds.

how it works

The functionality is relatively straightforward. There is a player object, which actually stays in place the entire game. The only movement from the user is that it can jump (and double-jump!) using the spacebar. The player object is given the illusion of moving because everything else – the obstacles, the collectibles, the background – move towards the player. The collectables and obstacles essentially have speeds at which they move towards the user, and if the player collides with a collectible points are added and deducted for obstacles. The placement of the obstacles and the collectables are random. Once the user has passed all obstacles in the game, the game advances to the next level.

My player class can be seen below.

class Player {
  constructor(spritesheet, spritesAcross, spritesDown, x, y, speed) {
    this.w = int(spritesheet.width / spritesAcross);
    this.h = int(spritesheet.height / spritesDown);
    this.across = spritesAcross;
    this.down = spritesDown;
    this.direction = 2;
    this.sprites = [];
    for (let y = 0; y < spritesDown; y++) {
      this.sprites[y] = [];
      for (let x = 0; x < spritesAcross; x++) {
        this.sprites[y][x] = spritesheet.get(
          x * this.w,
          y * this.h,
          this.w,
          this.h
        );
      }
    }
    this.x = this.w + 15;
    this.y = y;
    this.ground = y;
    this.speed = speed;
    this.step = 0;
    this.jump = 15;
    this.vy = 0;
    this.canDoubleJump = true;
    this.g = 1;
    this.isMoving = true;
    // this.score = 0;
  }

  setGround(newY) {
    this.ground = newY;
  }

  updatePosition() {
    this.y += this.vy;
    // gx -= obstacleSpeed;

    if (this.y < this.ground) {
      this.vy += g;
    } else {
      this.vy = 0;
      this.y = this.ground;
      this.canDoubleJump = true;
    }

    if (this.isMoving) {
      if (frameCount % this.speed == 0) {
        this.step = (this.step + 1) % this.across;
      }
    }
    // print(isMoving);

    image(this.sprites[this.direction][this.step], this.x, this.y);
  }

  doAJump() {
    if (this.y >= this.ground) {
      this.vy = -this.jump;
      this.canDoubleJump = true;
    } else if (this.canDoubleJump) {
      this.vy = -this.jump;
      this.canDoubleJump = false; // Consume double jump
    }
  }

 

things i’m proud of

One of my favorite things to do when I’m working on a technical creative project is figuring out the ambiance/aesthetics of the piece. Sometimes, I spend more time on that than the actual code. So needless to say, I’m the most proud of the aesthetics of this project. Not only does it it looks very in line with my initial vision of a retro game project, but I’m proud of how I was able to create the atmosphere for every setting. The background graphics, the obstacles, the collectibles, and the music. I think it all ties together very well and makes the game super immersive.

improvements

While I’m happy with how my project turned out, there is definitely room for improvements, or small changes that could completely elevate the level of my work.

  • Canvas size! I think because I was thinking of platform games on small screens, I kept the canvas size small. But I now wish it was bigger – unfortunately my code wasn’t typed in the most adaptable way, so it became a bit difficult to change the size towards the end.
  • Small features like being able to turn off the music would help a lot as well as I know the game is a bit heavy on the sound, which can be a bit disruptive.
  • Making the scoring system much more refined, i.e. adding points based on how elevated the collectable object is.

These changes seem relatively straightforward to implement, but I couldn’t mostly because of time restrictions.