Final Project: Make, Present and Report

 

The New Game – Dana Zinchenko – Margaret Minsky

CONCEPTION AND DESIGN:

Two main goals of my project is interactivity and adaptivity. It is an interacticve game which connects computing world with the physical world. Person can see how the game is doing on on the computer, but instead of controlling the player he is a player himself. Second, adaptivity – for such a long period of time I was thinking about various inventions which are now making lives of disabled easier. I also think that fun should be affordable to everyone, so I created a physicall game which can be adapted to every person and bring some fun in their life. I want every game to be in the interaction with the real life, I started with the game which is very similar to Geometry Dash, which is quite popular among teenagers and young-adults. I made my game easier and more cute. Instead of triangle cute creature is jumping through the barriers. There are three different ways to play my  game. You can choose which part of your body will move the creature which is a player in my game – your arm, your leg or your head. You can jump like in the original version of game, you can use your arm to do some workout during playing, or you can wait or choose to use your head. The game has also two variations – easy level to nod forward and the harder one is to move your head backwards to make a jump. When you are moving backwards it is harder to see the barries, so the game is funnier.  All of the sensors are working separately, but on the one coding basis, so you can choose between apparatus. Imagine, someone broke the arm and too lazy to jump right now, but want some action and gameplay. You need just to wait 15 seconds, not even press any buttons or something like it, and the game will start itself. These pretty things which are holding sensors are also adaptive to everyone, even kids, because they can change size. During the User Testing Session I heard many valuable constructive suggestions. And also I got some self-confidence, because I was able to see that people really like my project and enjoy the game. After this session I added more clarified losing part, some time in the beginning, moved score count so it is more easy to see it while playing the game, and also add more concrete instuctions. These adaptations very very effective. I later tested the project on my friends, and they even not knowing what is the project about were faster to understand how to play and what is going on.

FABRICATION AND PRODUCTION:

I wanted the design to be simple and working, so the users will intuitevely know how to play. I started my production with circuit. I soldered tilt sensors – they are easy to use and they provide exactly this type of values which I needed to make my project. I could’ve use distance sensor, I was thinking about it, but I decided to make game more physical and more understandable. My first trouble was that I wasn’t able to find capacitors – they were not in the equipment room and not in the lab, but Professor Minsky saved me and gave me some of the capacitors for my project. At first I made the project just for the one sensor – head and only after the experiments with it added other two sensors. After circuit building I worked with coding – made serial communication and modified the code from open resourse to finish my game. I changed some visual interpretations – colors, sizes, texts, positions, and added some bigger modifications – serial communication for three values, losing part, reset, and introductory part with choosing the apparatus with which you want to play this particular time. For the digital fabrication part I founded the basic sketch of headband and adapted it to the needs of my project. I decided to make it flexible, but in our fabrication lab there is only non-flexible plastic, so I came up with the idea to make it smaller and thinner, so it would become flexible enough. I made the first one, tested it and after printed two others. Also, theis design have special holes in the end of two unconnected parts of the headbands whic gaves me the opportunity to use special laces which are working to udjust sizzes. This holes hold these laces. For the packaging part I wanted to maake it minimalistic, so I printed white small box both for Arduino and breadboart and connected two parts of the box with wood stickes. I decided not to glue them together to have the opportunity to check and modify my circuit when I need it. It was a very good decision, I was able to fix any problem in a matter of seconds, because the box was easy to open and close. 

CONCLUSIONS:

Did my project achive the main goals of it? I think yes. It is interactive and adaptable to everyone. You can not just to control the creature on the screen, but to be the actual player. This project connects virtual reality in my computer to the physical world of human-computer interaction. And also it makes people to somehow interact with each other. I think that all games should have adaptations for everyone. All of us can be in different life situations, so the fun should be affordable. I want my project to make people think – what they can do? So, in this project we can see not only human-machine interaction, but also person-person interaction. It is valuable for me. If we will think deeper, we can make this kind of adaptations not only for gaming environtment, but also for various computer using movements. For example, my mum is a disabled person, and mostly every time her arm is in pain and she cannot really use it for many hours. But she is an artist, she needs to use it. I was thinking that if it is possible to make her life easier to make maybe her head to control computer? What if she will be able to draw with the use of her head? It will make her life much less dangerous and her arm conditions better. I would definetely did this if I had more time.  I learned a lot from this process of project making. For instance, learned that I always should think deeper. I further developed my knoweledge in coding, got to know some digital fabrication basics, learned how to apply my ideas to the real life, I practiced circuit building and idea’s developing. Also, during the whole project I had much problems with my computer, and all of these technical issues made it really hard for me to do the project and to present it properly. However, working together with my professor, I learned how to solve different problems, how not to lose hope, how to have a backup plan everytime, how to save sketches in all the places you can and how to find exits even from the worst situations. This knoweledge is very valuable for me, because it will help me not only in my future projects and classes, but in my life. This course gave me broad sphere of knoweledge. I learned basics of many different techniches. It is impossible to overestimate the usefullness of this course. You are learning how to make projects from the zero to the final presentation. How to research, how to create ideas, how to prepare for the start of work drawing sketches or making mindmaps and brainstorming, how to work on a project together with someone else, how to make circuits, how to code, how to connect all the parts of your work, how to use digital fabrication tools- both physical and computing, how to solder, how to us cardboard, how to make prototypes, how to decorate projects and how to present them. All of these is very interesting and beneficial knoweledge. I am so grateful that I had opportunity to learn all of these, and the final project was an opportunity to combine all together and to really make something. Overall, this project had special value for me, for my family, for my learning process. I want to emphasize the importance of the problem of adaptations and to use creativity in creating interactivity. I have very much on what to work with further, but also I have much enthusiasm to develop myself, to push my isead further. And now I know how to apply my knoweledge to make my ideas alive, to make them make some influence on others.

About the more practical part, I was working for a long time, however, there still seems to be some problems with the coding part. Reset is one of the most questionable parts for many of this year Interaction Lab students. And I am not an exception. Game is doing reset very well, but if I am adding losing slide, then after the reset you can make only one jump. I need to further explore it and fix this detail.

In the following section you will be able to see my working process, arduino and breadboard 3d printed box, sketches, troubles with my laptop at the most important moments, user testing session, final presentation. Also when semester finished, I still wanted to show my project, so I myself made a small event for some people from the university and gave them the opportunity to try out my project in the dorms. You can also see some recaps from this self-made presentation:) I apologize for the lack of some video parts, because when I understood that I didn’t film enough, it was actually too late to do this. Winter break started and I haven’t got access to my Arduino kit to finish the documentation process. However, in the video from user testing section, even if it is too short, it can be seen how values from the sensor and my hand moving the sensor controls the jumping of the creature in the game. When I will be back from winter break I will definitely film everything more transparent and clear, so I would be able to include this project in my portfolio as my first experience of using such techniques and coding. I learned a lot, and I need to learn more. I will strive to achieve my goals and now you can see my first steps in these pieces of documentation.  

Processing code:

//THE CODE IS ADAPTED FROM OPENGENIUS FOUNDATION 
import processing.serial.*; 
import osteele.processing.SerialRecord.*; 
 
Serial serialPort; 
SerialRecord serialRecord; 
 
boolean gameLost = false; 

class Barrier 
{ 
  float bottom; //This contains height of barriers 
  float w = 40; //This contains width of barriers 
  float x; //This contains x location of the barrier 
  float barrier_speed = 3; //This is the rate of change in position of barrier 
 
  Barrier() 
  { 
    bottom = random(150, 160); //Set value of height of barrier 
    x = wid + w; //Increase the x location by with 
  } 
  void update () 
  { 
    //if the game is going on modify barrier x-locations if the game is going on 
    if (start) 
    { 
      x -= barrier_speed; 
    } 
  } 
 
  //Check for collision, if locations of the player and the pipe is overla 
  boolean hits(Player b) 
  { 
    return ((b.pos.x > x) && (b.pos.x < (x + wid))) && (b.pos.y > (height - bottom - b.r)); 
  } 
  void show(boolean hit) 
  { 
 
    if (start) //display barriers if game is in progress 
    { 
      if (hit) 
      { 
        gameLost = true; 
      } else 
      { 
        //fill green normally 
        fill(65, 224, 129, 127); 
      } 
      stroke(0, 0, 0); 
      strokeWeight(2); 
      rect(x, height - bottom, w, bottom-110); 
    } 
  } 
} 
class Player { 
 
  PVector pos; //This contains position of player 
  PVector acc; //This contains acceleration of player 
  PVector vel;  //This contains velocity of player 
 
  float r=40; ////This contains radius of player object 
 
  Player() 
  { 
    //initialise the player data members 
    pos = new PVector(50, (height-200)); 
    vel = new PVector(0, 20); 
    acc = new PVector(); 
  } 
 
 
  void applyForce(PVector force) 
  { 
    acc.add(force); 
  } 
 
  void update() 
  { 
    applyForce(gravity); //applies downward gravity 
    pos.add(vel); // in order to update pos wrt velocity 
    if (pos.y >=height-170) 
    { 
      pos.y=height-170; 
      vel.mult(0); 
    } 
 
    vel.add(acc); //in order to update the vel as per acc 
    vel.limit(4); // in order to cap the vel for a smooth run 
 
    acc.mult(0); 
  } 
 
  void show() 
  { 
    fill(#DF9DF7); 
    stroke(0, 0, 0); 
    strokeWeight(2); 
    imageMode(CORNER); 
    image(pl, pos.x, pos.y, r*2, r*2); 
  } 
} 
 
 
 
Player b; //The object that jumps the barriers 
PImage pl; //Image for the player object 
 
int score=0; // keeps track of current game score 
int highScore=0; //Keeps track of High Score 
boolean safe=true; // Keeps track of whether the player hit an obstruction 
boolean start=false; //Keeps track of whether the game is going on 
 
PVector gravity = new PVector(0, 0.1); //Pushes the player down on the ground (when it jumps) 
ArrayList barriers = new ArrayList(); //List of Obstructions 
int wid = 1100; //The width of our screen 
 
int tilt = 0; 
int bodypart = 0; 
boolean startGame = false; 
float t = 0; 
 
void setup() { 
  fullScreen(); 
 // size(1100,400); //Initialise a canvas 
  b = new Player(); //initialise a player 
  pl = loadImage("snowball.png"); //Load the image in the variable 
 
 
  String serialPortName = SerialUtils.findArduinoPort(); 
  serialPort = new Serial(this, serialPortName, 9600); 
  serialRecord = new SerialRecord(this, serialPort, 3); 
} 
 
void draw() { 
  t = millis(); 
  if (t > 15000) { 
    startGame = true; 
  } 
  if (startGame == true && gameLost == false) { 
    if (serialRecord.read()) { 
      tilt = serialRecord.values[bodypart]; 
    } 
 
 
    if (start) 
    { 
      //Add barriers at random distances such that 
      //minimum distance is 60 frames to make the 
      //game playable only if th game is in progress. 
      if (random(1)<0.5&&frameCount % 60 == 0) { barriers.add(new Barrier()); } } if (tilt==1) { start = true; //Start the game on pressing the key if (b.pos.y == height-170) //Jump only if the player is already on the ground { PVector up = new PVector(0, -100); //Defining an appropriate upward force b.applyForce(up); //Applying the upward force just defined } } background(#9DF7CC); //Set background to the yellow colour b.update(); //Update the player's position and speed b.show(); //Display the player //traverse and display the obstructions for (int i=barriers.size()-1; i>=0; i--) 
    { 
      Barrier p = barriers.get(i); 
      p.update(); 
 
      if (p.hits(b)) 
      { 
        p.show(true); 
        safe=false; 
      } else 
      { 
        p.show(false); 
        safe=true; 
      } 
 
      //Remove the barriers that went out of frame 
      if (p.x < -p.w) 
      { 
        barriers.remove(i); 
      } 
    } 
 
    if (safe&&start) //Increment the score if game is going on smoothly 
    { 
      score++; 
    } else 
    { 
      //Restart the game 
      score=0; 
      text("MOVE TO START", width/2-500, 50); 
      start=false; 
    } 
 
    fill(16, 53, 201); //fill the text with colour for score 
    textSize(32); //Set size for the score 
 
    //Display score 
    text("Score", 100, 300); 
    text(score, 250, 300); 
 
    //Set and display high score 
    if (highScore < score) { 
      highScore = score; 
    } 
 
    text(highScore, 280, 50); 
    text("High Score", 100, 50); 
  } else if (gameLost == false && startGame == false){ 
    background(0, 255, 255); 
  textSize(100); 
  fill(0); 
  text("Press 'l' for leg", 0, height/2-100); 
  text("Press 'a' for arm", 0, height/2); 
  text("Wait or press 'h' for head", 0, height/2+100); 
} 
else if (gameLost == true && startGame == true){ 
  background(255, 0, 0); 
  textSize(100); 
  fill(0); 
  text("You Lost!", 0, height/2); 
} 
}
 
 
void keyPressed() { 
  if (key=='s') { 
  startGame = true; 
  } 
  if (key == 'l' || key == 'L') { 
    bodypart = 1; 
  } if (key == 'a' || key == 'A') { 
    bodypart = 2; 
  } if (key == 'h' || key == 'H') { 
    bodypart = 0; 
    startGame = true; 
  } 
  if (key == 'r' || key == 'R'){ 
    gameLost = false; 
    startGame = false; 
    safe=true; 
  } 
}

Arduino code:

#include "SerialRecord.h"


SerialRecord writer(1);


void setup() {
  Serial.begin(9600);
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode (2, INPUt);
}

void loop() {
  int tilt1 = digitalRead(0);
  int tilt2 = digitalRead(1);
  int tilt3 = digitalRead(2);
 writer[0] = tilt1;
writer[1]=tilt2;
writer[2]=tilt3;
  writer.send();

  delay(20);
} 

Recitation 10: Media Controller

 

For this recitation at first I chose to use the button as the media controller, however, later I understood that it is better to use potentiometer. I spent a lot of time working with button, so I needed to change all the code and circuit very fast. I made the second circuit and changed digital to analog read. For the media part I chose video from one of the examples we didn’t covered in class. I most love to work with filters, so I decided to do the coding using the filter. Also, as I first wanted to work with digital values I made the potentiometer working just by providing digital values (not the range of them, but just two positions). However, outside of the recitation time just for myself I changed it to analog values and mapped it with the tint function.

First trouble was that my video wasn’t working. I put it with the same folder with code, but later Professor helped me realize that I need to create a new folder with the name “data” into the existing one and put my code into it.  

for not to get such messages:

Later we tried to put my whole processing programm folder out of drive and unexpectedly it died. I get a message like this, so I needed to install processing and all of the libraries again and write the code from the very beggining. 

The result was that potentiometer at some value changed the filter to the grey one. It looks simple, but knoweledge that I know have after this recitation provides many opportunities of how to change video and images using physicall media controllers like this one. You can use digital or analog values, change sizes, colors, tints, the range of all of these. It is a broad topic and I am enthusiastic to experiment with it further.

Arduino Code and Processing Code:

#include "SerialRecord.h"


SerialRecord writer(1);

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);
}

void loop() {
  int sensorValue = analogRead(A0);

writer[0] = sensorValue;
  writer.send();
  delay(20);
} 
import processing.serial.*;
import osteele.processing.SerialRecord.*;

Serial serialPort;
SerialRecord serialRecord;
import processing.video.*;

int numPixelsWide, numPixelsHigh;
int blockSize = 10;
Movie mov;
color movColors[];

void setup() {
 

  String serialPortName = SerialUtils.findArduinoPort();
  serialPort = new Serial(this, serialPortName, 9600);
  serialRecord = new SerialRecord(this, serialPort, 1);
  
   size(560, 406);
   
  noStroke();
  mov = new Movie(this, "launch2.mp4");
  mov.loop();}