Midterm Project: Scuba Diving

For the midterm project, I decided on making a scuba diving game where the player will be encounter sea treasures and sea monsters in a continuous stream. The player will accumulate points by colliding with sea treasures but when a collision is made with a sea monster, the player’s initial life points of 3 is reduced by 1. After the life points reach zero, the game will end and the player will have to start again.

This idea was inspired by a game a made with the python kivy module. In that version, the player moves a track and accumulates points by staying on the underwater track for as long as possible. A screenshot is included below:

The game will look something like this:

Female scuba diver swimming under water Stock Photo

I downloaded scuba diver sprites and extracted the various stances. I set up a background image for the game and created movements with the mouse and keyboard.

You can click at the on any position to make the sprite move or you can move by pressing the arrow keys on the keyboard. The code is below:

function keyPressed() {
if (keyCode === DOWN_ARROW) {
posy += speed;
}if (keyCode === LEFT_ARROW) {
posx -= speed;
}if (keyCode === RIGHT_ARROW) {
posx += speed;
}if (keyCode === UP_ARROW) {
posy -= speed;
}
}

function mousePressed(){
posx = mouseX;
posy = mouseY;
}

The sketch is embedded below:

 

Improvements:

  • Change the sprites based on the different movements
  • Make the transition between sprites smooth
  • Add monster and treasure sprites
  • Let the monster and treasure sprites flow continuously from right to left randomly and with different speeds
  • Add sound when collisions are with treasure and monsters
  • Display an interface for starting and ending the game

Midterm Progress

For the midterm project, I will be drawing inspiration from the Snake game on old Nokia phones. The aesthetics of the game will be the same as the one seen below.

However, I want to increase the complexity of program which will randomly generate a moving maze. This is to incorporate a sense of randomness to the game.

Firstly I will have to use the lessons learned in the OOP lectures, to create the Snake and the food class. The snake class will also have a sub class depicting each body component (for length of snake). I have started work on the snake class and body classes.

After this is done we will implement a maze class where certain walls will be in a fixed position and other walls will appear and disappear randomly. I want to make this more frequent when the hallway is further away from snakes head.

Midterm Progress

Concept

For my midterm project, I really wanted to learn to work with sprites and add movement to my characters. An idea for the game came to my mind when I looked at different sprite sheets on the internet and found pony characters. I chose them because their movements include flying,jumping as well as walking, which seemed really interesting to work with. You can see an example of the sprite below:

pony sprite | Pony, Sprite, Mlp wingsMy Little Gauntlet — Yet another update. All the manes and tails...

That’s why my game concept will be around the theme of the cartoon “My little pony” 😁 I am planning to make a game similar to vertical jumping games, where my rainbow pony(character of Rainbow dash) will fly in the sky, and maintain the weather and clear the skies. The player earns bonus points for every cloud cleared and loses points when the character hits a bolt of lightning.

Process

As the first step into my game, I started working on backgrounds and an algorithm that changes the background and indicates a change of level. So I created a dummy variable that increases with time and that leads to a change. I also added background music to my sketch.

Next steps

1. Create classes for clouds and lightning and locate them into my canvas

2. Make my pony move

3. Work on the point counting system which will then lead to the change of levels(background)

[Tetris] Update 1 2022/10/3 — Game Interface & Block Display

Concept

For this project, I created a Tetris. Tetris is a simple game, in which users move or rotate blocks to fill a game field. Once a horizontal line is created with blocks, blocks on the line will be removed and the user will gain a certain amount of points. Users will gain points if:

  1. Removes blocks by making a horizontal line of blocks.
  2. Uses hard drop
  3. Extra points if multiple lines are removed at once

Although I am using a high-resolution screen, I wanted to give a “retro” appearance to the game (8bit). To achieve this effect, I used 8-bit style fonts and images.

Tetris (NES) - online game | RetroGames.cz

Code

Coding the game was indeed complex because the game required not only game logic, which I partially implemented, but also a friendly user interface. For this reason, I used 3 js. files, each responsible of running the code (sketch.js), displaying game interface (Page.js), and running game (Game.js).

Before making an actual “gaming” part of the project, I made the game interface of the game first. For this project, I used Press Start 2P font downloaded from https://fonts.google.com/specimen/Press+Start+2P.

1. sketch.js

<2022/10/3> UPDATE 1

This file manages how different pages will be displayed based on the user input. Depending on the user input, the game will show the main page, game page, instruction page, interrupt page, or game.

function draw() {
  background(0);
  if (!escapePressed) {
    //if user did not press ESC
    if (currentPageIndex == 0) {
      //MAIN PAGE
      displayMain();
      if (mySelectorMain != null) {
        //draw selector object
        mySelectorMain.drawSelector();
      } else {
        //if selector is new, create new selector object
        mySelectorMain = new selector(150, 340, 21);
      }
    } else if (currentPageIndex == 1) {
      //START GAME selected
      startGame(); //start game based on Game.js
    } else if (currentPageIndex == 2) {
      //HOW TO PLAY selected
      displayInstructions(); //display instructions
    }
  } else {
    if (currentPageIndex == 1) {
      //when user is in the middle of the game
      displayReturn("EXIT GAME AND RETURN TO MAIN?");
      if (mySelectorESC != null) {
        //draw selector object
        mySelectorESC.drawSelector();
      } else {
        //if selector is new, create new selector object
        mySelectorESC = new selector(230, 310, 21);
      }
    } else if (currentPageIndex == 2) {
      //when user is reading instructions
      displayReturn("QUIT READING AND RETURN TO MAIN?");
      if (mySelectorESC != null) {
        //draw selector object
        mySelectorESC.drawSelector();
      } else {
        //if selector is new, create new selector object
        mySelectorESC = new selector(230, 310, 21);
      }
    }
  }
}

Code above will display appropriate pages based on the current index of the game and ESC input(0: MAIN PAGE, 1: GAME, 2: INSTRUCTION). If ESC is pressed, the game will display RETURN TO HOME PAGE with appropriate texts.

//When keyboard input is given
function keyPressed() {
  if (keyCode == DOWN_ARROW) {
    if (currentPageIndex == 0) {
      /*Main page. Move selector accordingly. Selector will move 
      to HOW TO PLAY when it was previously at START GAME, and vice versa*/
      if (mySelectorMain.y == 340) mySelectorMain.y = 400;
      else mySelectorMain.y = 340;
    } else if (
      (currentPageIndex == 1 || currentPageIndex == 2) &&
      escapePressed
    ) {
      /*if ESC is pressed in the middle of the game or in the instruction,
      move selector accordingly.Selector will move to NO when it was previously 
      at YES, and vice versa*/
      if (mySelectorESC.y == 310) mySelectorESC.y = 370;
      else mySelectorESC.y = 310;
    }
  }
  if (keyCode == UP_ARROW) {
    if (currentPageIndex == 0) {
      /*Main page. Move selector accordingly. Selector will move 
      to HOW TO PLAY when it was previously at START GAME, and vice versa*/
      if (mySelectorMain.y == 340) mySelectorMain.y = 400;
      else mySelectorMain.y = 340;
    } else if (
      (currentPageIndex == 1 || currentPageIndex == 2) &&
      escapePressed
    ) {
      /*if ESC is pressed in the middle of the game or in the instruction,
      move selector accordingly.Selector will move to NO when it was previously 
      at YES, and vice versa*/
      if (mySelectorESC.y == 310) mySelectorESC.y = 370;
      else mySelectorESC.y = 310;
    }
  }
  if (keyCode == ENTER) {
    if (currentPageIndex == 0) {
      //user selects START GAME. Change currentPageIndex to 1
      if (mySelectorMain.y == 340) currentPageIndex = 1;
      //user selects HOW TO PLAY. Change currentPageIndex to 2
      else currentPageIndex = 2;
    } else if (
      (currentPageIndex == 1 || currentPageIndex == 2) &&
      escapePressed
    ) {
      /*ESC is pressed in the middle of the game or in the instruction.
      If user selects YES, change currentPageIndex to 0 (returning to MAIN PAGE);
      if user selects NO, simply return to the current page*/
      if (mySelectorESC.y == 310) {
        //YES
        currentPageIndex = 0;
        escapePressed = false;
      } else {
        //NO
        //user selects NO
        escapePressed = false;
      }
    }
    //Reset selector objects' position (DEFAULT: First option)
    mySelectorMain = null;
    mySelectorESC = null;
  }
  //If ESC is pressed, change escapePressed to true;
  if (keyCode == ESCAPE) {
    if (currentPageIndex != 0) escapePressed = true;
  }
}

Code above deals with user inputs and how the game will react to each  input. For this version of the game, user has an option to select different options using up/down arrows and enter. Variables with name including “selector” are objects of triangles that is shown next to the options. It will be further explained in PAGE.JS section.

2. Page.js

<2022/10/3> UPDATE 1

This file manages how each page will visually displayed to the user. It is where all positions and alignments of window/texts are shown. The page starts with preload() to load fonts and images that will be used through out the game.

function preload() {
  font = loadFont("assets/8Bit.ttf"); //load textfont to p5js
  blockImg = loadImage("assets/block.png");  //load single block unit image to p5js
}

Most of the codes in this page manages positions and alignments of the visual elements for each page (MAIN, GAME, INSTRUCTION, and INTTERUPTION).

//MAIN Page
function displayMain() {
  currentPageIndex = 0;

  //display main title of the game: TETRIS
  setFontStyle(titleFontSize);
  text("TETRIS", width / 2, 250);

  //display options
  setFontStyle(normalFontSize);
  text("START GAME", width / 2, 350);
  text("HOW TO PLAY", width / 2, 410);
}

//Instruction Page
function displayInstructions() {
  setFontStyle(titleFontSize - 40);
  text("HOW TO PLAY", width / 2, 95);

  createWindow(width / 2, 320, 530, 370);

  setFontStyle(normalFontSize);
  text(
    "↑ : ROTATE BLOCKS\n\n\n← : MOVE BLOCKS LEFT\n\n\n→ : MOVE BLOCKS RIGHT\n\n\n↓ : SOFT DROP\n\n\nSPACE : HARD DROP",
    width / 2,
    180
  );

  setFontStyle(normalFontSize - 7);

  if (millis() - currentMillis > 800) {
    currentMillis = millis();
    blink = !blink;
  }

  if (blink) {
    fill(0);
    stroke(0);
  } else {
    fill(255);
    stroke(255);
  }

  text("PRESS ESC TO RETURN", width / 2, 560);
}

//Game
function displayGameBackground(score, level, lines) {
  createWindow(width / 4 + 25, height / 2, width / 2 + 6, height - 60 + 6);

  setFontStyle(normalFontSize);
  text("——— NEXT ———", 462.5, 50);

  //Next blocks
  createWindow(400, 125, 106, 106);
  createWindow(525, 125, 106, 106);

  //Score, level, line cleared
  createWindow(462.5, 385, 231, 376);

  setFontStyle(normalFontSize);
  text("SCORE", 462.5, 245);
  text(score, 462.5, 290); //display score
  text("LEVEL", 462.5, 358.3);
  text(level, 462.5, 403.3); //display level of the round
  text("LINES", 462.5, 481.7);
  text(lines, 462.5, 526.7); //display total # of lines cleared in the round
}

//Return to Main Question Page
function displayReturn(_text) {
  //Create window
  createWindow(width / 2, height / 2, 400, 300);

  setFontStyle(normalFontSize);

  //Text Question
  text(_text, width / 2, 220, 350);

  //Options
  text("YES", width / 2, 320);
  text("NO", width / 2, 380);
}
//default setting of the font
function setFontStyle(size) {
  strokeWeight(1);
  textFont(font);  //set font style
  fill(255);
  textWrap(WORD);  //wrap text
  textAlign(CENTER);  //align text to center
  textSize(size);  //change text size
}

//create a rectangular window where texts will be displayed
function createWindow(x, y, w, h) {
  fill(0);
  stroke(255);  //white border
  strokeWeight(6);  //border weight of the rectangle
  rectMode(CENTER);  //rectangle is centered
  rect(x, y, w, h);
}

setFontStlye(size) and createWindow(x,y,w,h) are functions, where size is textSize, x and y are coordinates of the rectangle’s/window’s center, and w and h are width and height of the window.

3. Game.JS

<2022/10/3> UPDATE 1

This file contains all the game logics and runs Tetris game. The game consists of 2 main parts: block objects and game field array. Block objects are used to display blocks in motion. Game field array is what the program use to visualize the game. Once blocks cannot further be moved, it will be stored into game field array, so no further calculations will be needed in the future.

Game logic follow procedures listed below:

  • Create an empty game field array. (0: empty space, 1: something is present)
board = [];
for (let i = 0; i < boardHeight + 1; i++) {
  board[i] = [];
  for (let j = 0; j < boardWidth; j++) {
    board[i][j] = 0;
  }
}
  • User selects START GAME. Game Starts based on SCRIPT.JS
else if (currentPageIndex == 1) { 
//START GAME selected 
startGame(); 
}
  • Load background layout of the game (shapes and texts) based on PAGE.JS
function startGame() {
  displayGameBackground(0, 1, 0, 1);
  //Code is partially shown for demonstration
}
  • Generate, display, and move block object. Types of the block is randomly generated from the array that contains 7 different block types. Up until now, block will move only vertically down every time interval. When the block reaches bottom, or cannot be further moved, a new random block will be generated.
let blockTypeArr = ["I", "J", "L", "O", "S", "T", "Z"]; //Block Type Array

//GAME
function startGame() {
  displayGameBackground(0, 1, 0, 1); //display background interface

  if (generateBlock) {
    //If new block is needed, create a random shaped block
    myBlock = new block(int(random(0, 11)), 10, random(blockTypeArr), 4);
    generateBlock = false;
  }

  myBlock.drawBlock();
  myBlock.blockDown();
  displayBoard();
}

Most of the game logic is handled by block class below. For more, read the commented lines.

//block object for tetris blocks
class block {
  constructor(_x, _y, _type, speed) {
    this.x = _x;
    this.y = _y;
    this.type = _type;
    this.shapeArr = [];
    this.speed = 1;
  }
  
  /*this class method will fill shapeArr based on the
  type of the block. shapeArr is a 4*4 array, in which
  0: empty, 1: block*/
  shapeType(_type) {
    let shapeArr = [];
    /*example L block
      0 0 0 0
      0 1 0 0
      0 1 0 0
      0 1 1 0*/
    for (let i = 0; i < 4; i++) {
      shapeArr[i] = [0, 0, 0, 0];
    }
    if (_type == "I") {
      shapeArr[0][0] = 1;
      shapeArr[1][0] = 1;
      shapeArr[2][0] = 1;
      shapeArr[3][0] = 1;
    } else if (_type == "J") {
      shapeArr[1][2] = 1;
      shapeArr[2][2] = 1;
      shapeArr[3][1] = 1;
      shapeArr[3][2] = 1;
    } else if (_type == "L") {
      shapeArr[1][1] = 1;
      shapeArr[2][1] = 1;
      shapeArr[3][1] = 1;
      shapeArr[3][2] = 1;
    } else if (_type == "O") {
      shapeArr[2][1] = 1;
      shapeArr[2][2] = 1;
      shapeArr[3][1] = 1;
      shapeArr[3][2] = 1;
    } else if (_type == "S") {
      shapeArr[2][1] = 1;
      shapeArr[2][2] = 1;
      shapeArr[3][0] = 1;
      shapeArr[3][1] = 1;
    } else if (_type == "T") {
      shapeArr[2][1] = 1;
      shapeArr[3][0] = 1;
      shapeArr[3][1] = 1;
      shapeArr[3][2] = 1;
    } else if (_type == "Z") {
      shapeArr[2][1] = 1;
      shapeArr[2][2] = 1;
      shapeArr[3][2] = 1;
      shapeArr[3][3] = 1;
    }
    this.shapeArr = shapeArr;
  }

  //Checks if block can be moved in a given direction
  validMove(dX, dY) {
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) { 
if ( /*ignores all empty spaces. 1s must always be within the boundary of game field and must not overlap with non-empty, or 1s, when moved*/ this.shapeArr[i][j] == 1 && (board[this.y + i + 1][this.x + j] != 0 || this.y + i + dY >= boardHeight ||
            this.x + j + dX < 0 || this.x + j + dX >= boardWidth)
        ) {
          return false;
        }
      }
    }
    return true;
  }

  //Move block down for every time interval
  blockDown() {
    if (this.validMove(0, 1)) {
      if (millis() - counter > 400 / this.speed) {
        this.y++;
        counter = millis();
      }
    } else {
      //Once block cannot be moved down further, update game field
      for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
          if (this.shapeArr[i][j] == 1) board[this.y + i][this.x + j] = 1;
        }
      }
      //generate new block
      generateBlock = true;
    }
  }

  //Move Block left or right. left when direction is -1, right when direction is 1
  blockLeftRight(dX) {
    if (direction == -1) {
    }
  }

  //draw blocks. for each 1s in the shapeArr, block image will be placed
  drawBlock() {
    this.shapeType(this.type);
    blockImg = blockImg.get(0, 0, 20, 20);
    push();
    translate(25, 30);
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (this.shapeArr[i][j] == 1)
          image(blockImg, blockSize * (this.x + j), blockSize * (this.y + i));
      }
    }
    pop();
  }
}

//visually display the gameboard.
function displayBoard() {
  blockImg = blockImg.get(0, 0, 20, 20);
  push();
  translate(25, 30);
  for (let i = 0; i < boardHeight; i++) {
    for (let j = 0; j < boardWidth; j++) {
      if (board[i][j] == 1) image(blockImg, blockSize * j, blockSize * i);
    }
  }
  pop();
}

Future Improvements

There are tons of more things to implement in this game:

    1. Moving blocks horizontally using key inputs.
    2. Rotating blocks using key inputs.
    3. This means more logic must be added to the movement validation method.
    4. Add conditions that will check if game is over or not.
    5. Add conditions that will check if user had made a horizontal line using blocks. Then, the program must be able to remove that line and shift whole game filed down by the number of removed lines unit(s).
    6. The game will not reset even if user returns to the main page in the middle of the game. This can be fixed by resetting every variable at the start of each game.

Midterm Project: Design and Storyboarding

PURPOSE & GOALS 

The largest project I ever took on as an IMA student was a digital ethnography about Chinese adoption. The project involved conducting interviews and participant observation for 15+ individuals. Using the information I had gathered, I created a multipage interactive website with various p5 sketches embedded into it. With visual elements that complimented text and quotes from myself and other interviewees, the ethnography addressed 3 important aspects of the adoptee experience, family, culture, and self-identification. One of my goals for the site was to embed a game that helped show the user what it’s like dealing with biculturalism, but this was never completed. Thus, this game will be a continuation of my past project that addresses bicultural identity for Chinese adoptees.

 

But first, what is Biculturalism? 

Biculturalism is describes the mix of cultures that an individual comes to know, either being a person of multiple races, or growing up in a culture that is different from that of their family. In the case of adoptees, they were born into the culture of their motherland, but are often taken away from their birthplace at a young age and have to grow up in the culture of their family (usually Western). I note that the experience is quite different from a Chinese or Asian person growing up outside their home country, as the added layer of an interracial or multinational family complicates the child’s access to both cultures.

 

As a result, adoptees often grow up very distant from Chinese culture, yet feel like they can never be accepted by the Western culture they were brought up in either. Adoptees are often labelled “whitewashed” if they do not like Chinese food, or don’t know any Mandarin, or they are labelled “ungrateful” if they have more Chinese friends than they do White friends, or are eager to learn about their heritage. The duality of these two boxes that adoptees are meant to fit into creates a feeling of Otherness and “Alienness”, on a level that is far more nuanced than the traditional Asian American experience.

 

INSPIRATION 

Personally, I am not a gamer. I have never been one, and I don’t think I’ll ever become one. Most of the time I just don’t find the characters/plot that compelling, and rarely do they leave me with something to think about after the game is finished. Hence, if I were to play a game, I enjoy ones that are less focused on action and more on storytelling. One of my favorite games is an interactive roleplaying game called Dys4ia (Youtube video of gameplay can be found here). Dys4ia documents the experience of trans woman and video game designer Anna Anthropy. The game has multiple levels, each level deals with a different challenge of being a trans woman, such as buying new clothes, being misgendered, starting testosterone, etc. Her game is an example of how video games can be used as a method of digital storytelling, telling the story of marginalized identities. She also shows us the capabilities of media art being self-reflective, allowing the user to enter into a new perspective that is not their own and to learn about the struggles and experiences of others in a way that is vulnerable, intimate, and creative.

 

DESIGN

Inspired by Anthropy’s work, hoping to create an experience that not only educates the user about topics that are rarely represented, but also encourages them to question their understanding of what biculturalism is. In contrast to Anthropy’s game, my game will be much more text heavy, with some narration at the beginning of each “level”. In total, I plan to make 4 mini-games, or levels that symbolize aspects of my experience with Chinese and American culture as an adoptee.

To figure out exactly what I wanted to cover in the game, I began by creating a Mindmap that includes some of my thoughts and reflections about my own bicultural identity. The map is shown below:

After completing the map, the next step was to figure out what the game play will look like.

 

STORYBOARD 

I think figuring out how to represent the map into game form was the most difficult part. I knew that I didn’t need to create something super complicated to communicate the story, so the goal was to come up with games that while not novel in creativity, help demonstrate a complex metaphor. I also think it’s important to note that the “levels” are not an advancement of one another, but rather showcase the different phases of my journey as an adoptee. It’s really a cycle that is ongoing, and I find myself returning to these experiences at different moments in my life.  Hence, each mini-game, while has an objective, does not involve any “winning” per say. Some actions cause the game to restart, and yet the player has the option to replay or continue to the next game at any time they wish. A “scene by scene” representation of the game is shown below:

I realize that this project is very ambitious, and I don’t know if I will be able to accomplish four mini-games, but this is my vision as of now.

Midterm Progress

Project Idea

While I was tutoring as a coding instructor, I often used this game as a fun activity for beginners. In this game, we are supposed to move an object (Harvard’s logo) from one location to another while avoiding all the difficulties (other university’s logo). Thus, I decided to create a modified version of this game as my midterm project. 

In my adaptation of the game, the goal is to help the main character, who happens to be John Wick, survive as long as possible. However, the catch is there will be other characters who will be chasing him, and as soon as they get a hold of Wick, the game will be over. Thus, the theme of the game is to help Wick survive. 

Coding

For now, I have implemented “MyCharacter”, which is related to the main character, as well as “SuppCharacter” class, which is related to other characters who chase the main character. Each class is inherited from a primary class called “Character”. In the MyCharacter class, there are five methods (display, update, border_check, up_collision_check and movement), while the latter class contains three methods (display, update and border_check). As of now, when the primary character collides with other characters, no effect other than a piece of string is visible on the console. As per the necessity, I intend to implement more methods as well as modify existing methods to refine the game. 

In the MyCharacter class, the display method displays images loaded into the system, the update method updates (x, y) attributes of the class, the border_check method keeps the main character within the canvas while the up_collision_check and movement methods check if the main character has collided with other characters or not. In the same way, the methods in the SuppCharacter follow similar algorithms. 

The piece of code that I am particularly proud of is the up_collision_check method(), which contains nested if-conditionals. It is relatively short in length, but trying out different mathematical approaches took a while, and ultimately I came up with this algorithm. 

up_collision_check(other)
{
  // X coordinates verification
  if ( (this.x < (other.x + other.size)) && (this.x > other.x)) 
  {
    // Y coordinates verification
    if ((this.y < (other.y + other.size)) && ((this.y + this.char_h) > other.y))
    {
      print("Collision");
      return true;
    }      
  }   
}

Future Iteration

Over the weekend, I plan on adding the following functionalities to the game:

  1. Start screen that displays (a) instruction on how to play the game, (2) Start button and other setting features as deemed necessary 
  2. Implement a levels-based approach, where the level of difficulty goes on increasing. 
  3. Introduce more side characters to the game
  4. Include a variety of sound effects for different actions like collision, completion of a level and so forth
  5. Include a timer to determine the completion of a level 

Reflection

Overall, I am glad about the way the project is going on so far. The program is already 300 lines in length, and as I implement more methods, I may need to divide the project into multiple .js files. Also, I am expecting to make the project more efficient by reducing redundancies and changing algorithms if needed. 

Midterm Progress: Tanks

The original game

The inspiration came from Tanks, a game which user(s) can control tanks to destroy enemy tanks.

Although the game may look straightforward, it does have many complex in-game interactions such as choosing different weapons, shields, teleportation, shops, and so on. Since my intention is to create a much simpler game, many of the mentioned features will not be implemented. However, there are things which I would like to implement:

    1. Tanks that can move and launch shells to a desired direction.
    2. Exploded shells change landscape (map).
    3. Maps can be easily made (even be drawn with mspaint.exe).
    4. Dashboard of status
    5. Falling out of the map means death.
    6. Multiplayers with turns.
    7. etc.

There may be games that are more easier to make, but I already spent a lot of time creating the below result. I will probably continue to work on this.

So far the implemented features are the followings:

    1. Tank shape
    2. Tank follows gravity unless supported by surface.
    3. Tank can move, and will move slower when going uphill. Cannot go up when the hill is too steep. If tank falls out of the screen, it dies.
    4. Tank can aim.
    5. Tank can launch shells.
    6. Shell explodes when hitting a hard surface (ground, tank, etc.)
    7. Exploded shells permanently change landscape.
    8.  Maps are based on images (png). The images are uploaded.

So far there were no serious difficulties (meaning that I could somehow implement things if enough time is invested), but it took a lot of time. But there are more things that should be implemented to finish making the game.

    1. Sound effects
    2. Instructions page
    3. A button to start the game
    4. Functioning in-game dashboard
    5. Multiplayer
    6. Game end condition & restart option
    7. Limited fuel
    8. Controllable launch power.
    9. Health & health bar
    10. More maps
    11. etc.

I wonder how much struggle I will go through just to make this simple game.

Midterm Progress – Week 5

Concept

For my midterm project, I would like to work on a cool shooting game. However, I am yet to decide on the theme or path it should take. I was thinking about having a global warming theme where there could be say enemies to global warming spawning randomly and you need to take them down. As for the main character it could be say humans or plants. As far as the theme is concerned I would still like to keep myself flexible and see which ideas come on the way. As of now simple implementation of the objects have started being implemented using basic shapes, for example the circle drawn can move throughout the screen using AWSD keys.

Code

I have started implementing the logic of the game using basic shapes. As I progress, I shall incorporate images, sounds, and animations where possible to make the game more interesting and interactive. So far among the most difficult challenges I have faced were the logic to some parts of the game implementation such as the movement and restrictions of the shape within the canvas. I also faced a challenge with inheritance of classes for which I spent a considerable amount of time but haven’t figured out yet.

update() {
    this.y += this.vy;
    this.x += this.vx;
    
     //Input control for movement
    if (this.key_handler.a) {
      this.vx = -this.control_speed;
    } else if (this.key_handler.d) {
      this.vx = this.control_speed;
    } else {
      this.vx = 0;
    }

    if (this.key_handler.w) {
      this.vy = -this.control_speed;
    } else if (this.key_handler.s) {
      this.vy = this.control_speed;
    } else {
      this.vy = 0;
    }
    
    // print('x = ' + (this.x));
    // print('y = ' + (this.y));
    // print('r = ' + (this.radius));
    
    //Restricting movement to screen bounds
    if (this.x - this.radius < 0) {
      this.x = this.radius;
    }
    if (this.x + this.radius > SCREEN_WIDTH) {
      this.x = SCREEN_WIDTH - this.radius;
    }
    if (this.y - this.radius < 0) {
      this.y = this.radius;
    }
    if (this.y + this.radius > SCREEN_HEIGHT) {
      this.y = SCREEN_HEIGHT - this.radius;
    }
  }

Reflections / Improvements

I am looking forward to implementing a lot of things, from the start and end windows, to the score counter and display, audio and other visual effects. I am also looking forward to learning more about classes and inheritance of classes in p5js as it will make the code more efficient and easier to navigate.

Midterm Progress

Project idea – “Know your playlist”

The idea for this project came from my love for music, lately for rock music. My idea for the project would be a quiz type game, where I would play a song and the player would need to guess it correctly. I have some ideas for the design of it, however they are just rough sketches at the moment.

The game would work the following way:

  • A 5 to 10 second clip of the song would play and then the player would need to answer – The options would include: 4 different album images each with the name of the song and artist.
  • The player would need to answer correctly, if not the game will skip to the next question and take away a life (each play-through will have 3 lives)
  • After the game is completed (around 10 questions), the game will reveal the player’s score, and if they get all answers correctly a special message will appear (TBD)

coding

At the moment, I have no working code for the game, but I am thinking of using various arrays to keep songs from repeating themselves. Alongside that, in order to keep the design of the game tidy, I might need to use different object oriented functions for the picture + the name of the song. I am not fully sure on how will the project work and what exactly will be in the code, but I am working on finding it.

Midterm Progress: Where’s Waldo?

Concept

For my midterm, I’m planning on making a Where’s Waldo? game where the player has to search for the Waldo character on the canvas and click on him to win. Waldo is randomly generated on the canvas every time you play, and he’s in a crowded background that you have to navigate through and look closely in order to find him. It’s relatively simple; a digital version of one of my favorite books from childhood.

A highlight of some code that you’re particularly proud of

function setup() {
  createCanvas(512, 384);
  background(title);

  let red1 = color(237, 39, 36);
  startButton = createButton("START");
  startButton.mousePressed(drawInstructions);
  startButton.position(207, 299);
  startButton.style("font-family", "Optima bold");
  startButton.style("font-size", "30px");
  startButton.style("background-color", red1);
  
}

function drawInstructions() {
  background(237, 39, 36);
  startButton.remove();

This took way too long for me to figure out because I didn’t know how to use the remove syntax for startButton while also making sure it was a global variable that I could refer to in drawInstructions. Nevertheless, I’m glad I was able to eventually format it to do what I wanted in the end!

Embedded sketch

I have two separate sketches so far: one that contains the game itself and the win screen, and another that contains both the start screen and the instructions menu.

Try them out!

p.s. I haven’t yet inputted the reset sketch option, so you have to reset the program for it to work again.

Reflection and improvements

  • Trying to get the start button to not be displayed on the screen when function drawInstructions is called. Took me a hot second to figure it out, as I realized I was either formatting something wrong or not implementing a global variable when I needed to.
  • Possibly adding more characters to be found other than Waldo.
  • Still trying to figure out how to make it so that when your mouse is within the image of Waldo and you click on him, it takes you to the win screen. For now, it’s just when your mouse is pressed anywhere on the screen, you win.
  • I still have to embed the title screen and instructions into my game file, as well as a way to reset the game without having to restart p5js.

Welcome to you're "DOOM!"