Interactive Final Project Proposal

Art Project Proposal

For my final interactive project, I have decided to incorporate a previous design I have conducted which is the LED die with a motion sensor. Although I do not incorporate the motion sensor into my new project, I am creating a game which can be played directly on the LED matrix with the use of a potentiometer as a “game controller.” My initial plan for a project was to create a game in which the die that I had created from my previous project could some how be used as the main focus of the game, yet I could not conjure up any ideas where the die itself could be used as the basis of the game. Therefore, I had decided to stray away from the use of the entirety of my previous design, and instead decide to use a major component—the LED matrix—and somehow incorporate that into my new, interactive project. I knew in order for this project to classify as a new media arts project, I needed to include an interactive aspect to the piece itself. I had decided that I will be expanding the previously used 7-digit segment, into a 8X8 LED matrix instead, creating an overall larger design. In addition to creating a larger LED matrix, I have decided to use a potentiometer as the main interactive portion of the project, creating a connection between the visual media—or the matrix itself—and the person interacting with the project. In terms of purpose, I am combining the use of the LED matrix and the potentiometer to create a 2-player ping-pong game in which the opponents use the potentiometer to control the small LED lights on the programmed LED matrix, which will display the game of ping-pong on the LED matrix itself mimicking the original game itself. I had chosen this project, for I admire it’s complexity amongst what seems to be such a simplistic concept, bringing back an almost nostalgic feel to the piece, for it’s incorporation of modern technology and original gaming are brought together to form a unique and equally simple, yet fun gaming system. 

Questions:
-Is there any way my design can be improved in order for it to be more visually appealing? 
-Is the incorporation of a potentiometer a viable substitution for a game controller?
-Are there any ways that I could possibly improve the display of the design? (Ex: larger LED matrix, larger screen, LCD screen vs LED, etc.).

Sample Code: (Pong Game-revised) 
  1. /********
  2.  * Arduino Pong
  3.  * By Pete Lamonica
  4.  *  modified by duboisvb
  5.  *  updated by James Bruce (http://www.makeuseof.com/tag/author/jbruce
  6.  * A simple implementation of Pong on the Arduino using a TV for output.
  7.  *
  8.  */
  9.  
  10.  
  11. #include <TVout.h>
  12. #include <fontALL.h>
  13.  
  14. #define WHEEL_ONE_PIN 0 //analog
  15. #define WHEEL_TWO_PIN 1 //analog
  16. #define BUTTON_ONE_PIN 2 //digital to start game
  17. // #define BUTTON_TWO_PIN 3 //digital to reset and go back to main menu
  18.  
  19. #define PADDLE_HEIGHT 14
  20. #define PADDLE_WIDTH 1
  21.  
  22. #define RIGHT_PADDLE_X (TV.hres()-4)
  23. #define LEFT_PADDLE_X 2
  24.  
  25. #define IN_GAMEA 0 //in game state – draw constants of the game box
  26. #define IN_GAMEB 0 //in game state – draw the dynamic part of the game
  27.  
  28. #define IN_MENU 1 //in menu state
  29. #define GAME_OVER 2 //game over state
  30.  
  31. #define LEFT_SCORE_X (TV.hres()/2-15)
  32. #define RIGHT_SCORE_X (TV.hres()/2+10)
  33. #define SCORE_Y 4
  34.  
  35. #define MAX_Y_VELOCITY 6
  36. #define PLAY_TO 7
  37.  
  38. #define LEFT 0
  39. #define RIGHT 1
  40.  
  41. TVout TV;
  42. unsigned char x,y;
  43.  
  44. boolean button1Status = false;
  45. // boolean button2Status = false;
  46.  
  47. int wheelOnePosition = 0;
  48. int wheelTwoPosition = 0;
  49. int rightPaddleY = 0;
  50. int leftPaddleY = 0;
  51. unsigned char ballX = 0;
  52. unsigned char ballY = 0;
  53. char ballVolX = 2;
  54. char ballVolY = 2;
  55.  
  56. int leftPlayerScore = 0;
  57. int rightPlayerScore = 0;
  58.  
  59. int frame = 0;
  60. int state = IN_MENU;
  61.  
  62. void processInputs() {
  63.   wheelOnePosition = analogRead(WHEEL_ONE_PIN);
  64.   // delay(50);
  65.   wheelTwoPosition = analogRead(WHEEL_TWO_PIN);
  66.  // delay(50);
  67.    button1Status = (digitalRead(BUTTON_ONE_PIN));
  68.   
  69.  //  button2Status = (digitalRead(BUTTON_TWO_PIN) == LOW);
  70.    if ((button1Status == 0)&& (state == GAME_OVER))
  71.    {
  72.      Serial.println(“game over, drawing menu”);
  73.      drawMenu ();
  74.    }
  75.   
  76.  
  77.    delay(50);
  78.   //Serial.println(button1Status);
  79.   //Serial.println(state);
  80.   //Serial.println(button2Status);
  81.   //Serial.println(wheelOnePosition);
  82.    //Serial.println(wheelTwoPosition);
  83.  
  84.  
  85. }
  86.  
  87. void drawGameScreen() {
  88.  //  TV.clear_screen();
  89.   //draw right paddle
  90.   rightPaddleY = ((wheelOnePosition /8) * (TV.vres()-PADDLE_HEIGHT))/ 128;
  91.   x = RIGHT_PADDLE_X;
  92.   for(int i=0; i<PADDLE_WIDTH; i++) {
  93.     TV.draw_line(x+i,rightPaddleY,x+i,rightPaddleY+PADDLE_HEIGHT,1);
  94.   }
  95.  
  96.   //draw left paddle
  97.   leftPaddleY = ((wheelTwoPosition /8) * (TV.vres()-PADDLE_HEIGHT))/ 128;
  98.   x = LEFT_PADDLE_X;
  99.   for(int i=0; i<PADDLE_WIDTH; i++) {
  100.     TV.draw_line(x+i,leftPaddleY,x+i,leftPaddleY+PADDLE_HEIGHT,1);
  101.   }
  102.  
  103.   //draw score
  104.   TV.print_char(LEFT_SCORE_X,SCORE_Y,’0’+leftPlayerScore);
  105.   TV.print_char(RIGHT_SCORE_X,SCORE_Y,’0’+rightPlayerScore);
  106.  
  107.   
  108.   
  109.  
  110.  
  111.   
  112.   //draw ball
  113.   TV.set_pixel(ballX, ballY, 2);
  114. }
  115.  
  116. //player == LEFT or RIGHT
  117. void playerScored(byte player) {
  118.   if(player == LEFT) leftPlayerScore++;
  119.   if(player == RIGHT) rightPlayerScore++;
  120.  
  121.   //check for win
  122.   if(leftPlayerScore == PLAY_TO || rightPlayerScore == PLAY_TO) {
  123.     state = GAME_OVER;
  124.   }
  125.  
  126.   ballVolX = -ballVolX;
  127. }
  128.  
  129.  
  130.  
  131.  void drawBox() {
  132.       TV.clear_screen();
  133.       
  134.    //draw net
  135.   for(int i=1; i<TV.vres() – 4; i+=6) {
  136.     TV.draw_line(TV.hres()/2,i,TV.hres()/2,i+3,1);
  137.   }
  138.   // had to make box a bit smaller to fit tv 
  139.     TV.draw_line(0, 0, 0,95,1 );  // left
  140.    TV.draw_line(0, 0, 126,0,1 ); // top
  141.     TV.draw_line(126, 0, 126,95,1 ); // right
  142.      TV.draw_line(0, 95, 126,95,1 ); // bottom
  143.   
  144.   
  145.   state = IN_GAMEB;
  146. }
  147.  
  148.  
  149. void drawMenu() {
  150.   x = 0;
  151.   y = 0;
  152.   char volX =3;
  153.   char volY = 3;
  154.   TV.clear_screen();
  155.   TV.select_font(font8x8);
  156.   TV.print(10, 5, “Arduino Pong”);
  157.   TV.select_font(font4x6);
  158.   TV.print(22, 35, “Press Button”);
  159.   TV.print(30, 45, “To Start”);
  160.   
  161.   
  162.   delay(1000);
  163.   while(!button1Status) {
  164.     Serial.println(“menu”);
  165.   Serial.println(button1Status);
  166.   
  167.     processInputs();
  168.     TV.delay_frame(3);
  169.     if(x + volX < 1 || x + volX > TV.hres() – 1) volX = -volX;
  170.     if(y + volY < 1 || y + volY > TV.vres() – 1) volY = -volY;
  171.     if(TV.get_pixel(x + volX, y + volY)) {
  172.       TV.set_pixel(x + volX, y + volY, 0);
  173.     
  174.       if(TV.get_pixel(x + volX, y – volY) == 0) {
  175.         volY = -volY;
  176.       }
  177.       else if(TV.get_pixel(x – volX, y + volY) == 0) {
  178.         volX = -volX;
  179.       }
  180.       else {
  181.         volX = -volX;
  182.         volY = -volY;
  183.       }
  184.     }
  185.     TV.set_pixel(x, y, 0);
  186.     x += volX;
  187.     y += volY;
  188.     TV.set_pixel(x, y, 1);
  189.   }
  190.  
  191.  
  192.  
  193.   TV.select_font(font4x6);
  194.   state = IN_GAMEA;
  195. }
  196.  
  197. void setup()  {
  198.     //Serial.begin(9600);
  199.   x=0;
  200.   y=0;
  201.   TV.begin(_NTSC);       //for devices with only 1k sram(m168) use TV.begin(_NTSC,128,56)
  202.  
  203.   ballX = TV.hres() / 2;
  204.   ballY = TV.vres() / 2;
  205.  
  206. //  pinMode(BUTTON_ONE_PIN, INPUT);      // sets the digital pin as output
  207. }
  208.  
  209. void loop() {
  210.   processInputs();
  211.  
  212.  
  213.  
  214.  
  215.   if(state == IN_MENU) {
  216.     drawMenu();
  217.   }
  218.  if(state == IN_GAMEA) {
  219.     //Serial.println(“gamA”);
  220.   //Serial.println(button1Status);
  221.   
  222.     drawBox();
  223.   }
  224.  
  225.   if(state == IN_GAMEB) {
  226.     if(frame % 3 == 0) { //every third frame
  227.       ballX += ballVolX;
  228.       ballY += ballVolY;
  229.  
  230.  // change if hit top or bottom
  231.       if(ballY <= 1 || ballY >= TV.vres()-1)
  232.      { ballVolY = -ballVolY;
  233.                  delay(100);
  234.   TV.tone( 2000,30  );   
  235.      }
  236.       
  237.   // test left side for wall hit    
  238.       if(ballVolX < 0 && ballX == LEFT_PADDLE_X+PADDLE_WIDTH-1 && ballY >= leftPaddleY && ballY <= leftPaddleY + PADDLE_HEIGHT){
  239.         ballVolX = -ballVolX;
  240.         ballVolY += 2 * ((ballY – leftPaddleY) – (PADDLE_HEIGHT / 2)) / (PADDLE_HEIGHT / 2);
  241.             delay(100);
  242.   TV.tone(2000,30 );   
  243.       }
  244.       
  245.  // test right side for wall hit     
  246.       if(ballVolX > 0 && ballX == RIGHT_PADDLE_X && ballY >= rightPaddleY && ballY <= rightPaddleY + PADDLE_HEIGHT) {
  247.         ballVolX = -ballVolX;
  248.         ballVolY += 2 * ((ballY – rightPaddleY) – (PADDLE_HEIGHT / 2)) / (PADDLE_HEIGHT / 2);
  249.             delay(100);
  250.   TV.tone( 2000,30  );   
  251.       }
  252.  
  253.       //limit vertical speed
  254.       if(ballVolY > MAX_Y_VELOCITY) ballVolY = MAX_Y_VELOCITY;
  255.       if(ballVolY < -MAX_Y_VELOCITY) ballVolY = -MAX_Y_VELOCITY;
  256.   
  257.  // Scoring
  258.       if(ballX <= 1) {
  259.         playerScored(RIGHT);
  260.      // sound 
  261.      delay(100);
  262.   TV.tone( 500,300 );   
  263.       }
  264.       if(ballX >= TV.hres() – 1) {
  265.         playerScored(LEFT);
  266.         // sound 
  267.         delay(100);
  268.  TV.tone(  500,300 );
  269.       }
  270.     }
  271.    
  272.    
  273. //    if(button1Status) Serial.println((int)ballVolX);
  274.  
  275.     drawGameScreen();
  276.   }
  277.   
  278.   if(state == GAME_OVER) {
  279.     drawGameScreen();
  280.     TV.select_font(font8x8);
  281.     TV.print(29,25,”GAME”);
  282.     TV.print(68,25,”OVER”);
  283.     while(!button1Status) {
  284.       processInputs();
  285.       delay(50);
  286.     }
  287.     TV.select_font(font4x6); //reset the font
  288.     //reset the scores
  289.     leftPlayerScore = 0;
  290.     rightPlayerScore = 0;
  291.     state = IN_MENU;
  292.   }
  293.  
  294.  
  295.   TV.delay_frame(1);
  296.   if(++frame == 60) frame = 0; //increment and/or reset frame counter
  297. }