Midterm Project – M7md

Class Duel

Concept and Inspiration

For my midterm project, I decided to create a 2D fighting game called Class Duel. I wanted to make something related to my interest in RPGs, particularly games where players can choose different classes with their own strengths and weaknesses. I also drew some inspiration from Dark Souls III, mainly when thinking about the different classes and the fantasy setting. I didn’t want to recreate its combat system, since that would be far too complicated. Instead, I decided to make something simpler, combining RPG-style classes with a 2D fighting game. The player can choose between three classes: Knight, Rogue, and Mage. Each has different health, speed, attack damage, and abilities.

I also wanted to include something unexpected beyond the normal fight. After defeating the first enemy, there’s a 20% chance of encountering a secret boss called the Holy Knight. I thought this would make the game a little more interesting and give players another reason to replay it. There’s also a short dialogue sequence before the encounter, which changes depending on the player’s selected class. For the visual style, I went with fantasy backgrounds and character sprites to make everything feel more consistent.

How the Project Works and What I’m Proud Of

I started by experimenting with a much simpler version of the game, mainly to figure out how the basic interactions would work. At that stage, I was more concerned with testing the concept than with making everything look complete. I gradually added the combat mechanics, character classes, and different game states. The final game uses a Fighter class to manage movement, health, damage, and cooldowns. I thought this was a better approach than creating separate code for every character, especially since they share most of the same mechanics. I used conditionals to give the classes different stats and abilities. For the enemy, I kept things relatively simple. It moves closer to the player and has a random chance of attacking when it’s within range. Initially, the enemy was too difficult, so I reduced its movement speed and attack chance to make the fight more manageable.

Figure 2. An early version of Class Duel from my progress report, before the final character designs, animations, backgrounds and combat presentation were added.

After getting the basic mechanics working, I started working on the characters’ appearance and animations. This was one of the things I was particularly interested in trying because we covered sprite-sheet animation in class. I used nested loops to divide each sprite sheet into individual frames and stored them in a 2D array. Each row represents an animation, like walking, jumping, attacking, or blocking, and the columns contain the different frames. Then I used conditional statements to decide which animation should play depending on what the character is doing. I also decided to keep the normal enemy as a character drawn using p5.js shapes rather than another sprite sheet. I think this helped make the game look more complete compared to the earlier prototype.

Figure 3. The final version of game, showing the updated characters, fantasy background, and combat interface.

Another part I’m happy with is the combat system. I wanted the player to have more options than just repeatedly pressing the attack button, so I included blocking, parrying, class abilities, and special attacks. The Knight can use Guard Counter, the Rogue can throw a knife, and the Mage can create a barrier. Each class also has a special attack that becomes available once the special meter is full: Earthsplitter, Shadow Step, and Meteor. I used timers and conditions to manage things like blocking, stunning, and cooldowns. I also tried to make each ability visually different using simple shapes and animations. Adding background music and sound effects made a noticeable difference, since the combat felt fairly empty without them.

Code Highlights

One of the main techniques I used was sprite-sheet animation, which was based on an example we covered in class. The nested loops go through each row and column of the sprite sheet, while get() extracts individual frames and stores them in a 2D array.

for (let j = 0; j < rows; j++) {
  this.frames[j] = [];

  for (let i = 0; i < columns; i++) {
    this.frames[j][i] = sheet.get(i * w, j * h, w, h);
  }
}

For the enemy AI, I used the distance between the player and enemy, along with random(), to control movement and attacks. I chose a relatively low attack chance for the normal enemy so it wouldn’t become too difficult.

if (distance > 65) {
  this.x += this.speed * 0.35 * this.facing;
  this.isMoving = true;
}

if (distance <= 85 && random(1) < 0.03) {
  this.lightAttack();
}

The secret encounter also uses randomness. After winning the first battle, the game checks whether the player should encounter the Holy Knight. If the condition is met, it moves to the cutscene before starting the boss fight.

if (phase === 1 && enemy.health <= 0 && random(1) < encounterChance) {
  cutsceneTimer = 0;
  clearHeldKeys();
  gameState = "cutscene";
  playMusic(bossMusic);
}

Problems and Areas for Improvement

One of the biggest challenges was getting the different mechanics to work together. Making a character move wasn’t too difficult on its own, but things became more complicated once I added jumping, attacking, blocking, abilities, and different game states. I also ran into problems with keyboard input and sound playback, especially when trying to switch between different background tracks. I experimented with different approaches before settling on keyPressed() for individual actions and keyIsDown() for movement and blocking. The sprites were another challenge because the individual frames didn’t always align properly, making some animations look inconsistent.

If I had more time, I would improve the animations and make the special attacks feel more impactful. I originally wanted to include more detailed cutscenes, especially for the Holy Knight encounter, but ended up keeping that part relatively simple. I would also like to improve the enemy AI because its current behavior is mostly based on distance and randomness. Honestly, I’m happy that I managed to create a playable fighting game with different classes, combat mechanics, animations, sound, and a secret encounter. Although it was difficult and required a lot of trial and error, I was still able to make it work.

Inspirations

My main inspirations were Super Smash Bros. and Dark Souls III, although I drew different ideas from each game. Super Smash Bros. influenced the general fighting-game format, particularly the side-view combat, movement, and the idea of having different characters with their own abilities. On the other hand, Dark Souls III partly inspired the fantasy setting and the character classes, especially how different classes can have their own strengths and weaknesses. I didn’t intend to recreate either game, but rather combine some of the things I liked about them into something simpler that I could make using p5.js.

Fight - Super Smash Bros. Ultimate | Interface In Game

Inspiration for the side-view combat and character abilities.

DARK SOULS™ III

Inspiration for the fantasy setting and class-based character design.

Visual and Audio Assets

Use of AI

I wrote the code for Class Duel myself, but I used AI as a tutor for a few concepts that went beyond what we covered in class or caused bugs I couldn’t solve. I would describe the problem, ask the AI to explain the idea behind it, and then write or fix the code myself. I also used ChatGPT to generate the character sprite sheets.

Gravity and double jump (update(), jump()): In class we moved objects by a fixed speed each frame, but a jump should slow down at the top and speed up on the way down. ChaTGPT explained that gravity changes velocity and velocity changes position: velocityY += gravity makes the fighter fall faster each frame, and a jump sets velocityY to a negative jumpStrength so gravity slows them down until they fall. I also had a bug where holding UP used both jumps at once. It also explained that keyIsDown() is true every frame, unlike keyPressed(), so I added jumpKeyDown, which forces the player to release UP before the second jump.

Parry system (update(), receiveAttack()): I wanted blocking and parrying on the same key but didn’t know how to tell them apart. After asking ChatGPT, it suggested counting how many frames C has been held with blockTimer. If an attack lands within the first 10 frames (blockTimer <= parryWindow), it’s a parry, which blocks all damage and stuns the attacker. After that it’s a normal block that reduces damage to 60%. To stop players from holding block forever, blockLimit ends the block after 3 seconds and starts a 5-second blockCooldown.

Sprites: The Knight, Rogue, Mage and Holy Knight sprite sheets were generated with ChatGPT. I wrote the SpriteAnimator class to cut each sheet into frames (5 animation rows for idle, walk, jump, attack and block, with 4 frames each) using the 2D-array method from the Week 5 example, and updateAnimation() chooses the row based on what the fighter is doing.

 

Week 5 Reading Assignment – M7md

One thing I found interesting about the reading was the difference between how humans and computers see. I was not completely surprised that computer vision has more limitations because, at the end of the day, computers interpret information numerically. Even when we write code using programming languages, it eventually has to be translated into something the computer can process. What I found more interesting was the idea that instead of only improving the algorithm, we can change the physical environment to make it easier for the computer to see. Techniques such as background subtraction, brightness thresholding, and frame differencing depend on things like contrast, lighting, and movement. Computer Vision for Artists and… At first, I wondered how changing the environment would help when the computer still has to translate what it sees into data either way. However, I think the point is that these changes make that data easier to distinguish. For example, making a person stand out strongly from the background gives the computer clearer differences in brightness or color to work with. I found it interesting that sometimes changing the environment can be more effective than simply making the software more complicated.

I also think computer vision creates an interesting relationship between interaction and surveillance. Tracking someone’s body can make an artwork feel much more interactive because the body itself becomes a way of communicating with the system and receiving feedback from it. I could imagine experimenting with something like this myself. I have seen a musical work where artists used Wii remotes to affect sound through their movements, and computer vision could create a similar interaction without necessarily relying on a traditional controller. At the same time, I think there is an important ethical boundary. The reading shows that computer-vision artworks can track willing participants as well as people who are unaware that they are being observed. Computer Vision for Artists and… I would be comfortable interacting with an artwork that tracks me as long as I am informed beforehand, especially if there are clear rules about what happens to the data being collected. Tracking people without their knowledge crosses a line for me, even if being unaware is supposed to be part of the artistic experience. Computer vision can make interactive art more responsive and interesting, but I don’t think creating an experience should come at the cost of the participant’s awareness or consent.

Week 5 Midterm Progress Report – M7md

Concept

For my midterm, I wanted to make something that feels more like a complete game experience rather than just a small interaction or visual experiment. I’m interested in fighting games because of how intense and dramatic the characters in those games can be.  The game characters have different strengths, the player has to react quickly and a lot of variables can influence the outcome of the game.

One game that influenced this direction is Super Smash Bros. I like how different characters can completely change how a match feels because of their movement, range, attacks and abilities Even though the basic goal stays the same, learning how a character works changes how you approach the fight. I want to take that idea of different play styles, but use my own class system and combat mechanics instead of recreating the game.

What I want the player to experience is a short but intense duel where they have to understand how their chosen class works, react to the enemy, and decide when to attack, defend, or use a special. I also want the fight to feel a little cinematic, with moments like special clashes, low-health sequences, and stronger visual effects when something important happens.

The player will choose between three classes: Knight, Rogue, and Mage.

The Knight will have high health and defense but slower movement and only close-range attacks. The Rogue will have lower health but move faster and attack at close and mid range. The Mage will have medium health, lower defense, and mainly use ranged attacks.

Each class will also have its own special attack. The Knight will use “Earthsplitter,” the Mage will use “Meteor,” and the Rogue will use “Shadow Step.”

I also want the fights to have short cinematic moments so they do not feel like a basic fighting game. These could include special clashes, low-health moments, and possibly victory animations if I have enough time. For special clashes, if two strong attacks meet, the game could briefly pause and use a timing challenge to decide which attack wins.

Design

The experience will start with a title screen asking the player to press Space. After that, the player will see the controls, then choose a class before starting the fight.

so it would look like this:

Start Screen -> Control -> Class Select -> Fight -> Win/Lose Screen -> Restart

The player will move using the arrow keys and will be able to double jump. During combat, they will have a light attack, heavy attack, block/parry, class ability, and special attack.

Blocking can be held for up to three seconds. If it is held for too long, it goes into a five-second cooldown. The first few moments of blocking will also act as a parry window. A successful parry will avoid damage, stun the enemy for two seconds, and add to the special meter.

The special meter will fill by both dealing and receiving damage, but taking damage will fill it faster.

 

Code Structure

I started by separating the fighter logic into its own fighter.js file. Both the player and the enemy use the same fighter class:

player = new Fighter(200, height - 145, "Player", false);

enemy = new Fighter(width - 200, height - 145, "Enemy", true);

The last value tells the fighter whether it is controlled by the player or by the AI.

The AI is very simple for now. It faces the player, moves toward them slowly and sometimes attacks when it gets close enough. I can make it more complex later if I have time.

Most Challenging Part & Risk Prevention

The part I was most worried about was getting the actual fighting system to work. There are a lot of things that eventually need to work together, like movement, attacks, hit detection, health, AI, different classes, blocking, and special attacks.

I did not want to work on all the visuals and class abilities first and then find out later that the basic combat was too difficult to make work. To reduce that risk, I made a very simple version of the fight first using stick figures as placeholders.

 

For now, I focused only on the main things I would need for a fight. I got movement and double jumping working, added a simple AI opponent, made a basic light attack, added hit detection and health, and made a win/lose screen that lets the player restart the fight.

One thing I specifically wanted to test was hit detection. For the light attack, I made a point in front of the fighter depending on which direction they are facing, then checked how close the enemy is to that point.

let attackX = this.x + 45 * this.facing;
let attackY = this.y - 35;

let distanceX = abs(attackX - targetX);
let distanceY = abs(attackY - targetY);

if (distanceX < 45 && distanceY < 65) {
  otherFighter.health -= this.lightDamage;
}

Getting this basic prototype working makes me more confident about continuing with the idea. It also means I can build the more complicated attacks and class differences on top of something that already works instead of trying to build everything at the same time.

Next Steps

Next, I want to start adding the actual class differences, heavy attacks, blocking and parrying, the special meter, class abilities, and the animated special attacks.

The stick figures are only placeholders for now. If I have enough time, I want to replace them with my own sprite sheets and improve the AI and cinematic effects later.

 

Week 4 Production Assignment – M7md

Concept

For this assignment, I wanted to create a data visualization that did not look like a normal graph or chart. I used a Pokémon  dataset containing Pokémon  from Generations 1-6 and focused on their types and base stats. Each Pokémon is represented by a moving ribbon. Different parts of the Pokémon’s data control different parts of the visual:

  • HP changes the thickness of the ribbon
  • Attack changes how much it bends
  • Defense changes how smooth the movement is
  • Speed changes how quickly it moves
  • Type 1 controls the main color
  • Type 2 adds a second color if the Pokémon has another type

Clicking the sketch chooses a random Pokémon from the dataset.

I also wanted to experiment with sound, so I used Estrellita by Manuel. Ponce, using the violin and piano arrangement credited to Jascha Heifetz in the video I used. The loudness of the music affects how much the ribbon moves, while the Pokémon’s speed stat slightly changes the playback speed of the song.

I choose Estrellita because I liked how the softer music worked with the movement of the ribbon. I also considered using the Pokémon Theme Song, which has a stronger rhythm and would probably produce a much more energetic result.

Code I Like

One part I liked was connecting the Pokémon stats to different properties of the ribbon.

let ribbonThickness = map(currentHP, 1, 255, 40, 120);

let curveAmount = map(currentAttack, 1, 190, 40, 130);

let ribbonSmoothness = map(currentDefense, 1, 230, 0.03, 0.01);

let moveSpeed = map(currentSpeed, 1, 180, 0.002, 0.012);

I liked this because every Pokémon uses the same system, but the result changes depending on its stats.

Another part I liked was how I connected the music to movement:

let musicLevel = amplitude.getLevel();

smoothMusicLevel = lerp(smoothMusicLevel, musicLevel, 0.045);

let musicMovement = map(smoothMusicLevel, 0, 0.08, 0, 50);

Cause initially the ribbon reacted too suddenly to every small change in the music. I used lerp() to make the value move gradually toward the new music level instead.

How Was This Made?

I started by loading the Pokémon CSV file and keeping only the columns I needed: name, types, hp, attack, defense and speed. The stat values from the CSV file were text, so before using them in calculations I converted them to integers using int().

For the Pokémon type colors, I used an object with key value pairs:

let typeColors = {
  Normal: "#b7b2a8",
  Fire: "#d96c4a",
  Water: "#5d8fbf"};

Which let me use the Pokémon’s type as the key to find its color.

I used TRIANGLE_STRIP to make the ribbon. Instead of drawing one large shape manually, it connects pairs of vertices into a continuous strip. I also used .toUpperCase() for the Pokémon name and types so the text matched the visual style.

For the sound, I used the p5.Sound Library, which was new to me. I loaded the MP3 using LoadSound() and created a p5.Amplitude() object to measure the loudness of the music.

amplitude = new p5.Amplitude();
song.connect(amplitude);

I used getLevel() to get the current amplitude of the song. That value is then used to affect the ribbon’s movement and width. I also used constrain() so the music could not make the movement become too extreme.

musicMovement = constrain(musicMovement, 0, 60);

The Space bar controls the song using isPlaying(), play() and pause(). I also used rate() to slightly change the playback speed based on the Pokémon’s speed stat.

let songSpeed = map(currentSpeed, 1, 180, 0.9, 1.1);

song.rate(songSpeed);

I kept the change small because I still wanted the song to be recognizable.

Development & Problems

One of the biggest problems was getting the shape to actually look interesting. My first version looked much more like a sine wave or a signal than a ribbon. While experimenting with the ribbon shape, I found this p5.js ribbon sketch that used TRIANGLE_STRIP. It helped me understand how a smoother strip could be built from connected vertices, although I simplified the idea and used it differently in my final version.

Initially, I used a sine wave to create the shape. It was smooth, but it looked too much like a graph. I experimented with different waves and later used noise() to make the movement less repetitive.

I also changed the ribbon from a small horizontal shape into a much larger diagonal form so it became the main part of the composition. Another issue appeared when I started working with sound. At first, the amplitude value stayed at 0.000 even when the song was playing. I later found that I need to connect the song to the amplitude analyzer:

song.connect(amplitude);

After that the values started changing. Later I had another issue, because the ribbon’s movement was too erratic. I used lerp() to smooth the value and tested different amounts until the movement felt calmer.

Reflection

This assignment ended up being more experimental than I expected. Before working on it, I mostly thought of data visualization as showing information through charts or points, but this project made me think more about how data can also control shape, movement, color, and sound. I liked that each Pokémon could have a different visual result even though the same system was being used for all of them.

The sound section was probably the most unfamiliar part for me because I had not used p5.sound before. It took some trial and error to figure out how to load the audio, measure its amplitude, and make the ribbon respond without the movement becoming too distracting. I also experimented a little with sonification by letting the Pokémon’s Speed stat affect the playback rate of Estrellita. The difference is small, but I liked that the Pokémon data was affecting both the visual and the audio. I considered using the Pokémon theme instead because its stronger rhythm would probably make the audio reaction more obvious, but I preferred the softer movement I got from Estrellita. If I continued working on the project, I would probably experiment more with how different parts of the music could affect the ribbon instead of adding more visual elements.

Credits

Pokémon data from the Pokémon CSV dataset by armgilles.
Pokémon Solid font from dafont.
Estrellita by Manuel M. Ponce, using the violin and piano arrangement credited to Jascha Heifetz in the recording used for this project. I do not own the recording. The audio sources in this project are used only for this classroom assignment and documentation.
The Pokémon Theme Song was also considered as an alternate audio source.

Week 4 Reading Assignment – M7md

One everyday design that frustrates me is a website or app that makes a simple task difficult by hiding the next step in menus. I would make the main actions easier to find and give clear confirmation when a choice has worked. Norman’s door example helped me see why: his friend could not tell where to push because the doors hid useful clues, so he had to guess. A screen can cause a similar problem when its actions are not visible. This made me pay more attention to discoverability. I agree that designers should anticipate likely mistakes rather than blame users immediately. At the same time, Norman writes from a designer’s perspective, so he puts much responsibility on design. I find that useful, but it can underplay how users’ familiarity and practical limits also shape what happens.

I would apply some of Norman’s principles to interactive artwork. I tend to think of interaction as a two-way exchange: the audience does something, and the artwork responds. The artwork could use a visual or sound cue to show what actions are possible, then change in color, movement, or sound to show that it registered an action. It would not need to explain the artwork’s meaning. The reading makes me think that clarity about how to engage can coexist with openness about what the response means. If people have no clue what action is possible, they may not participate; if every response is explained, there may be less room for exploration. I wonder how an artist can make an interaction understandable while leaving its meaning open to the audience.

Week 3 Reading Assignment – M7md

Before reading Crawford’s The Art of Interactive Design, I already thought of interaction as some form of two-way communication, where both sides depend on each other for the interaction to continue. Because of this, his idea of interaction as a process of listening, thinking and speaking felt somewhat self-explanatory to me rather than completely changing how I understood it. However, I agree with his argument that interaction can exist at different degrees. Two systems might both respond to a user, but one can offer much more interaction depending on how it processes and responds to what the user does. I don’t think every interaction has to necessarily be meaningful either. Some interactions can feel pointless, even if they technically involve communication. What interests me more is whether the interaction actually contributes to what the creator is trying to achieve.

This made me think differently about the sketches I have created so far in this class. I haven’t really designed them around the people interacting with them. Most of my decisions have been based on my own interests and what I wanted the sketch to show. For future sketches, I would like to experiment more with interactions that can produce unexpected results rather than having every user action lead to the exact same response. For example, the program could respond differently depending on what the user does or how they interact with it. If I’m creating something specifically for another person to interact with, I think I would want their actions to lead to something that encourages them to continue experimenting with the sketch or even makes them think about what is happening. This makes me question whether an interaction can be considered successful even if it works, but fails to get further response from the user.

Week 3 Production Assignment – M7md

Concept

For this assignment, I wanted to create a generative night sky using objects and arrays. My main inspiration was Rosalina’s Storybook from Super Mario Galaxy. I liked the soft, hand-drawn look of the scenes, especially the textured blue backgrounds and glowing stars. I was not trying to recreate the image itself, but I wanted my sketch to have a similar storybook feeling. The bigger stars are created using a Star class. Each star has its own position, size, color, glistening speed, and texture. I also added smaller stars and small colored points in the background so the sky would not feel too flat or empty.

Every 10 seconds, the main stars move to new random positions, so the composition keeps changing while the sketch is running.

Rosalina’s Storybook from Super Mario Galaxy. image taken from a fan-compiled PDF shared on Reddit.

 

Code I Like

glisten() {
    // Move through the glistening animation at this star's own speed
    this.sparkleTime += this.sparkleSpeed;

    // Turn the sine value into a transparency value from 80 to 255
    this.brightness = map(sin(this.sparkleTime), -1, 1, 80, 255);
  }

How Was This Made?

For the main part of the assignment, I created a Star class that acts as a blueprint for the stars. Each object stores information such as its position, size, color, and glistening speed. I then created 30 different Star objects and stored them inside an array:

let stars = []; 
for (let i = 0; i < 30; i++) {
 let star = new Star( random(20, width - 20),
 random(20, 350),
 random(6, 28),
 random(starColors) ); 

stars.push(star);

This array lets me go through all of the objects using one loop:

for (let i = 0; i < stars.length; i++) {
    stars[i].glisten();
    stars[i].display();
  }

This made it easier to control many stars without writing separate code for each one.

Functions I Used

I used a few functions that we have not really covered in class yet.

I used sin() together with map() to create the glistening effect. sin() gives a value that smoothly moves back and forth, while map() converts that into the transparency range I wanted.

I used color() and setAlpha() so I could keep the original color of each star while changing its transparency.

To make the custom four-point star, I used beginShape(), vertex(), and endShape(CLOSE). These let me create my own shape by choosing where each point should be.

I also used push(), pop(), and translate(). I had used .push() and .pop() before with arrays, but these versions are different. push() saves the current drawing settings and transformations, while pop() restores them. I used them with translate() so each star could be moved to its own position without affecting the other stars.

For the glow, I reused:

drawingContext.shadowColor

drawingContext.shadowBlur

I had used these before in my previous assignment. shadowColor controls the color of the glow, while shadowBlur controls how soft and spread out it is.

For the background, I used randomSeed(). The background uses random points for texture, but without randomSeed() they would move every frame. Using randomSeed(5) makes the same random pattern repeat, so the texture stays still.

I later used randomSeed(millis()) when changing the star positions. Since millis() keeps changing, this gives the stars a new random arrangement instead of repeating the same one.

I also reused millis() from a previous assignment. This time I used it to check when 10 seconds had passed, and then I called a function that gives all of the stars new random positions.

Reflection

The visual side of this assignment changed quite a bit while I was working on it.

At first, I tried using lines and many small marks to make the background look more like crayon, but some versions looked more like digital scanlines or like I had scribbled over the whole background.

I eventually changed the texture to smaller points and reduced how many there were. This kept some texture without making it too distracting.

I also made a simple mistake at one point where I forgot to redraw the background inside draw(). Since the stars were animated, their old frames stayed on the screen and created trails.

After fixing that, I had another problem where the randomly generated texture changed every frame. I solved this using randomSeed() so the same random texture would be redrawn each time.

Later, I noticed that the stars changed position after the first 10 seconds but then seemed to keep returning to the same arrangement. This happened because the fixed randomSeed() used for the background was also affecting later uses of random(). I fixed this by using randomSeed(millis()) before generating new star positions, which gives it a different seed each time.

The sky also felt too empty at first. I increased the number of main stars from 20 to 30, gave them a wider range of sizes, and added smaller stars in the background instead of filling the screen with even more large stars.

For future improvements, I would probably try to make the stars themselves look even more hand-drawn so they match the Storybook inspiration more closely. I also think sound or some kind of interaction could be interesting, but I wanted to keep this version focused on the visual side.

Week 2 Reading Assignment – M7md

Even before watching Casey Reas’ talk, I tried using randomness in my previous assignment without thinking deeply about the balance between randomness and control. I programmed the “YOU DIED” screen to have a chance of appearing after a random amount of time between 15 and 20 seconds. The program could decide when the change happened and whether it happened, but still the outcome was controlled, albeit slightly, by me. Looking back at it, it was not completely random. I created the rules first then allowed the computer to make smaller decisions within them. I liked that because the unexpected change made my work feel more alive and a bit more personal, since it was a game reference I enjoyed including.

I’m planning to develop this further with week two’s production assignment, in which I’ll create a glitched screen using loops. I could randomize the positions, lengths, colors or timing of the glitches so the screen does not produce exactly the same image each time. However, I would still control the color range and general layout. For me, the optimum balance is when I can recognize my original idea in every result, but I still can’t predict what the result would be. Complete control might make the work feel too repetitive, while total randomness could make the glitches look meaningless. What I’m interested in is something in the middle where I design the system, but the system can still surprise me. It also makes me wonder whether deciding what the computer is allowed to change is more important than deciding exactly where everything appears.

Week 2 Production Assignment – M7md

Concept

For this assignment, I wanted to create something that looked like a glitched screen using simple shapes and randomness. I started with the idea of having a grid of shapes that would constantly change, with their colors, sizes and the speed of the screen changing randomly.

At first, the colors were completely random, but I felt like the result was too chaotic and wasn’t very visually appealing, at least to me. I decided to limit the colors to a smaller palette inspired by two images I liked. I mainly took inspiration from the deep blues in one image and the warm yellow and gold colors in the other.

 

Yuvi's longing (feat. Eureka Republic) - song and lyrics by Hagali, EUREKA REPUBLIC | Spotify

color reference 1: Illustration from Yuvi’s Longing. I liked the warm gold and yellow lighting in this image.

 

Download Neon Cyberpunk Night Image - Cyberpunk, Neon, Futuristic | StockCake

Color reference 2:  cyberpunk cityscape with darker and futuristic colors.

 

Code I Like

//move down the screen
for (let y = 25; y < height; y += 50) {
  //move across the screen
  for (let x = 25; x < width; x += 50) {
    
    if (random() < 0.5) {
      rect(x, y, ShapeWidth, ShapeHeight);
    } else {
      ellipse(x, y, ShapeWidth, ShapeHeight);
    }
  }
}

The part I like most is this one, where I used two loops, mainly for how simple it is. The first loop moves down the canvas while the second moves across.

What I liked more was what I could do inside those loops. I was able to randomly decide what shape appears, and both its color and size. Even though the code itself is quite short and simple, it creates something that constantly changes and looks different every time.

How Was This Made?

I started by making a simple grid using two for() loops and then placed a shape at each position. I used an if statement with random() to give each position a 50% chance of being a rectangle or ellipse.

After getting the basic grid working, I started adding randomness to different parts of it. The width and height of each shape are randomized. I also randomized frame rate so the screen changes at an inconsistent speed, which helped give it the glitched feeling I wanted.

Originally, I used completely random RGB values for the colors, but I wasn’t happy with how it looked. I created two arrays containing a smaller selection of colors instead, one for the shapes and another for the dark background. The program still chooses the colors randomly, but only from the colors I selected.

Towards the end, I removed the outlines, made the shapes slightly transparent and allowed them to overlap. I also used drawingContext.shadowColor and drawingContext.shadowBlur to add a warm glow around the shapes. I kept the glow color the same but randomized the amount of blur so that some shapes glow more than others.

Reflection

For this assignment, I liked seeing how much could be done with something as simple as loops and basic shapes. The first version worked, but it mostly looked like random colorful shapes changing on the screen. I wasn’t completely happy with it even though it technically did what I wanted.

Most of the changes I made afterwards were actually quite small. Limiting the colors, increasing the size of the shapes, removing their outlines, adding transparency and eventually adding the glow changed the way it looked without making the code much more complicated.

I also liked having some control over the randomness this time. Instead of allowing the program to choose any possible color, I gave it a smaller palette and let it choose randomly from that. The final result is still unpredictable and changes constantly, but I have more control over what those random results can look like.

Some improvements or changes I could do are adding more shapes and have different patterns instead of only two. I could also have different kinds of effects such as having only certain parts of the screen change while others don’t. I feel like doing that would make the work feel more glitched compared to how it is at the moment.

Week 1 Assignment – M7md

Concept

For this assignment, I created a self-portrait inspired by video game character select screens. Instead of trying to make it realistic, I represented myself as a simple character with stats such as energy, luck and focus. For the character itself, I took some inspiration from Nintendo Mii’s characters.

Default Miis - MiiWiki

Mii character reference – Nintendo

I also wanted to add some sort of twist, so every 15-20 seconds there is a chance for the screen to switch to a different one.

Code I like

The part I’m probably most proud of is the hair. At first, I thought it would be simple to make, but it ended up taking a lot of experimenting to get it to look the way I wanted.

I started with an ellipse behind the head to make the main shape of the hair. I then used several triangles for the strands at the front and the spikes on the side. A lot of it was just changing coordinates, seeing how it looked, and adjusting them again until I was happy with it.

//hair
  fill('black');
  triangle(116,251,132,247,124,269);
  triangle(130,247,149,244,140,272);
  triangle(147,244,165,244,156,268);
  triangle(163,244,182,247,173,272);
  triangle(180,247,198,253,188,268);

  triangle(123,238,90,244,120,263);
  triangle(115,260,87,263,112,287);

How Was This Made?

I made the portrait using basic shapes like rectangles, ellipses, triangles, arcs, and lines. I built the character piece by piece, starting with the head and body before adding the hair, face, and character information.

After finishing the normal character screen, I made a second version for the “YOU DIED” screen. I used a variable called isdead to decide which one should be shown. I then used the built-in functions, millis() to keep track of time and random() to give the sketch a chance to change between the two screens every 15–20 seconds. Most of the process was experimenting with values and coordinates and then looking at the result. If something looked wrong, I would change the numbers and try again.

Reflection

I enjoyed this assignment because I could make the self-portrait about something I like instead of just trying to recreate my actual appearance. Turning myself into a character-select screen made it feel more personal, and I liked adding the random “YOU DIED” screen as a small unexpected part of it.

The hair was probably the most annoying part to get right, but it also ended up being the part I was happiest with. If I were to improve the project, I would spend more time on the character itself by adding more details and making the body and face look better. I would also add more possible causes of death instead of always showing “Missed Deadline,” so that the death screen could be different each time. Another thing I would change is to make the text feel more “alive,” by making them blink instead of staying static.

edit: added image reference, sources for functions used, and made some minor improvements to text.