Saturday, January 10, 2015


Electronics Class Final Project


/*
 - This code creates a remake of the video game "Pong".
 The code creates a title screen, a menu screen, and four
 levels of difficulty of gameplay(Easy, Medium, Hard, Impossible).

 -This code was written for a system based around the
 An Arduino Uno and an Adafruit 1.8" TFT Sheild w/ microSD and Joystick

 -The whole physical system (as originally built) was made from the following materials:
 1 Arduino Uno
 1 Adafruit 1.8" TFT Sheild w/ microSD and Joystick
 1 Speaker (soldered to ground and digital pin 6 in this case)
 28 Male Conn headers (male pin extenders) *(They will fit into the outer pins of the TFT sheild)

 -The code will require these arduino libraries to be downloaded to function or to be edited:
 "Adafruit_ST7735.h" @ https://github.com/adafruit/Adafruit-ST7735-Library
 "Adafruit_GFX.h" @ https://github.com/adafruit/Adafruit-GFX-Library

-Here is a link to a video briefly explaining the code and its algorithms:
 http://youtu.be/zWp7gQaBFWY

 -This code will also need defenitions of notes so as to work as originally intended.
 -Here are the note definitions. Create a new tab in the sketch, and copy the defenitions into it.
 ///////////////////////////////////////
 //Public Constants (Note Definitions)//
 ///////////////////////////////////////
 #define NOTE_B0  31
 #define NOTE_C1  33
 #define NOTE_CS1 35
 #define NOTE_D1  37
 #define NOTE_DS1 39
 #define NOTE_E1  41
 #define NOTE_F1  44
 #define NOTE_FS1 46
 #define NOTE_G1  49
 #define NOTE_GS1 52
 #define NOTE_A1  55
 #define NOTE_AS1 58
 #define NOTE_B1  62
 #define NOTE_C2  65
 #define NOTE_CS2 69
 #define NOTE_D2  73
 #define NOTE_DS2 78
 #define NOTE_E2  82
 #define NOTE_F2  87
 #define NOTE_FS2 93
 #define NOTE_G2  98
 #define NOTE_GS2 104
 #define NOTE_A2  110
 #define NOTE_AS2 117
 #define NOTE_B2  123
 #define NOTE_C3  131
 #define NOTE_CS3 139
 #define NOTE_D3  147
 #define NOTE_DS3 156
 #define NOTE_E3  165
 #define NOTE_F3  175
 #define NOTE_FS3 185
 #define NOTE_G3  196
 #define NOTE_GS3 208
 #define NOTE_A3  220
 #define NOTE_AS3 233
 #define NOTE_B3  247
 #define NOTE_C4  262
 #define NOTE_CS4 277
 #define NOTE_D4  294
 #define NOTE_DS4 311
 #define NOTE_E4  330
 #define NOTE_F4  349
 #define NOTE_FS4 370
 #define NOTE_G4  392
 #define NOTE_GS4 415
 #define NOTE_A4  440
 #define NOTE_AS4 466
 #define NOTE_B4  494
 #define NOTE_C5  523
 #define NOTE_CS5 554
 #define NOTE_D5  587
 #define NOTE_DS5 622
 #define NOTE_E5  659
 #define NOTE_F5  698
 #define NOTE_FS5 740
 #define NOTE_G5  784
 #define NOTE_GS5 831
 #define NOTE_A5  880
 #define NOTE_AS5 932
 #define NOTE_B5  988
 #define NOTE_C6  1047
 #define NOTE_CS6 1109
 #define NOTE_D6  1175
 #define NOTE_DS6 1245
 #define NOTE_E6  1319
 #define NOTE_F6  1397
 #define NOTE_FS6 1480
 #define NOTE_G6  1568
 #define NOTE_GS6 1661
 #define NOTE_A6  1760
 #define NOTE_AS6 1865
 #define NOTE_B6  1976
 #define NOTE_C7  2093
 #define NOTE_CS7 2217
 #define NOTE_D7  2349
 #define NOTE_DS7 2489
 #define NOTE_E7  2637
 #define NOTE_F7  2794
 #define NOTE_FS7 2960
 #define NOTE_G7  3136
 #define NOTE_GS7 3322
 #define NOTE_A7  3520
 #define NOTE_AS7 3729
 #define NOTE_B7  3951
 #define NOTE_C8  4186
 #define NOTE_CS8 4435
 #define NOTE_D8  4699
 #define NOTE_DS8 4978

 Original Code is 26.942 kb, last modified on Jan 9, 2015
 Composed by Alex Nakhleh
 */


#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SD.h>
#include <SPI.h>
#include "pitches.h"

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

// TFT display and SD card will share the hardware SPI interface.
// Hardware SPI pins are specific to the Arduino board type and
// cannot be remapped to alternate pins.  For Arduino Uno,
// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
#define SD_CS    4  // Chip select line for SD card
#define TFT_CS  10  // Chip select line for TFT display
#define TFT_DC   8  // Data/command line for TFT
#define TFT_RST  -1  // Reset line for TFT (or connect to +5V)

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

//Defenitions For Joystick Inputs.
//These interract with the command function "uint8_t readButton(void)" and "readButton()"
#define BUTTON_NONE 0
#define BUTTON_DOWN 1
#define BUTTON_RIGHT 2
#define BUTTON_SELECT 3
#define BUTTON_UP 4
#define BUTTON_LEFT 5

int NoteDuration=100;
int note=0;

int RocketSong[]={
  NOTE_GS4,NOTE_DS4,NOTE_F4,NOTE_GS4,NOTE_AS4, //Song Played when Player wins
  NOTE_DS4,NOTE_GS4,NOTE_AS4,NOTE_C5,NOTE_DS4,NOTE_GS4,NOTE_C5,
  NOTE_CS5,NOTE_F4,NOTE_GS4,NOTE_CS5,NOTE_AS4,NOTE_CS4,NOTE_F4,
  NOTE_AS4,NOTE_G4,NOTE_CS4,NOTE_F4,NOTE_GS4};

int failsong[]={
  NOTE_B4,NOTE_GS4,NOTE_F4,NOTE_A4,NOTE_FS4,NOTE_DS4,NOTE_E4}; //Song Played when player loses


int www=0; //used later to make sure rng is only used to determine whether ball is thrown left or right at the start of a point
int xxx=0; //stores random number for x-velocity
int ppp=0;//Makes sure The title, two walls, and "press joystick" are only printed once when the game resets from a loss or win
int yyy=0;//used later to make sure rng is used to deternime the angle of the balls starting movement at the start of a point
int zzz=0;//stores random number for y-velocity

int noteval=0;//will be used to begin the songs from their first note

int RocketSongNoteDuration=300;//Duration of notes of the winning song

int STAGE=0;//Level Identifier
int S1=60; //Original title screen ball coordinates and x and y speeds
int S2=105;
int p1=1;
int p2=1;

int menuX=100; //
int menuY=50;
int menuA=0;
int menuB=0;

int playerScore=0;//Player's score
int compScore=0;//AI's score

int pX=157;//Coordinates for the Player paddle and its movement speeds
int pY=50;
int pA=0;
int pB=6;

int cX=0; //Coordinates for the AI paddle and its movement speeds
float cY=50;
int cA;
float cB;

int ballX=78;//Coordinates for the ball and its speed
int ballY=61;
int ballA=3;
float ballB=0;




void setup()
{
  Serial.begin(9600);
  // Initialize 1.8" TFT
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);
  Serial.println("OK!");
  //Prints the Title, the two walls, and "press joystick" on the title screen
  tft.setTextSize(5);//Prints "PONG"
  tft.setCursor(6,30);
  tft.print("PONG");

  tft.setTextSize(0);//Prints "Press Joystick"
  tft.setCursor(20,140);
  tft.print("Press Joystick");

  tft.drawLine(20,90,20,120,ST7735_WHITE); //Prints the 2 walls in the title screen
  tft.drawLine(21,90,21,120,ST7735_WHITE);
  tft.drawLine(100,90,100,120,ST7735_WHITE);
  tft.drawLine(99,90,99,120,ST7735_WHITE);

  randomSeed(analogRead(0));//Set up for future uses of "RNG"
}

//READ JOYSTICK FUNCTION
////////////////////////////////////////////////////////////////////////////////////////
uint8_t readButton(void) {
  float a = analogRead(3);

  a *= 5.0;
  a /= 1024.0;

  //Serial.print("Button read analog = ");
  ///Serial.println(a);
  if (a < 0.2) return BUTTON_DOWN;
  if (a < 1.0) return BUTTON_RIGHT;
  if (a < 1.5) return BUTTON_SELECT;
  if (a < 2.0) return BUTTON_UP;
  if (a < 3.45) return BUTTON_LEFT;// a<3.2 if joystick will read left with no input, use a<3.45 if arduino is not sensing the joystick being moved left
  else return BUTTON_NONE;
}
uint8_t buttonhistory = 0;


void loop()
{
  while(STAGE==0)//Level 0 = Title Screen
  {
    uint8_t b=readButton();//Reads button
    Serial.println(b);
    if(ppp==0)
    {
      tft.setTextColor(ST7735_WHITE);
      tft.setTextSize(5);
      tft.setCursor(6,30);
      tft.print("PONG");

      tft.setTextSize(0);
      tft.setCursor(20,140);
      tft.print("Press Joystick");

      tft.drawLine(20,90,20,120,ST7735_WHITE);
      tft.drawLine(21,90,21,120,ST7735_WHITE);
      tft.drawLine(100,90,100,120,ST7735_WHITE);
      tft.drawLine(99,90,99,120,ST7735_WHITE);
      ppp++; //makes that "Pong", "press joystick" and the 2 walls are only printed once the game resets
      delay(1000);//to give the user a time to release the joystick when the game resets after a win/loss.
    }

    tft.fillRect(S1,S2,4,4,ST7735_WHITE);//Code to print and move the ball on the title screen
    delay(20);
    tft.fillRect(S1,S2,4,4,ST7735_BLACK);
    S1=S1+p1;
    S2=S2+p2;
 
    if(S1+4>=99 || S1<=22)//Wall Physics for title screen
    {
      p1=-p1;
    }
    if(S2<=90 || S2+4>=120)//Wall Physics for title screen
    {
      p2=-p2;
    }
    if(b==BUTTON_SELECT)//Press joystick to add 1 to level identifier
    {
      STAGE=STAGE+1;
    }
  }

  if(STAGE==1)//Clear screen when Level Identifier==1 (menu screen)
  {
    Serial.println("STAGE_1 INITIATED");
    tft.fillScreen(ST7735_BLACK);
    delay(250);
  }
  while(STAGE==1)
  {
    uint8_t b=readButton();//read joystick
 
    //Print the names of the level difficulties
    tft.setTextSize(2);
    tft.setTextColor(ST7735_MAGENTA);
    tft.setCursor(5,10);
    tft.print("IMPOSSIBLE");
    tft.setTextSize(3);
    tft.setTextColor(ST7735_RED);
    tft.setCursor(5, 43);
    tft.print("HARD");
    tft.setTextColor(ST7735_YELLOW);
    tft.setCursor(5, 88);
    tft.setTextSize(3);
    tft.print("MEDIUM");
    tft.setTextColor(ST7735_GREEN);
    tft.setTextSize(3);
    tft.setCursor(5, 130);
    tft.print("EASY");

    tft.fillRect(menuX,menuY,10,10,ST7735_BLACK);//Printing and movement of the selecting cursor
    menuX=menuX+menuA;//movement
    menuY=menuY+menuB;
    delay(10);
    tft.fillRect(menuX,menuY,10,10,ST7735_WHITE);
 
    if(b==BUTTON_UP)//Movement fo the Cursor based on joystick readings
    {
      menuA=0;
      menuB=-6;
    }
    if(b==BUTTON_DOWN)
    {
      menuA=0;
      menuB=6;
    }
    if(b==BUTTON_RIGHT)
    {
      menuA=6;
      menuB=0;
    }
    if(b==BUTTON_LEFT)
    {
      menuA=-6;
      menuB=0;
    }
    if(b==BUTTON_NONE)
    {
      menuA=0;
      menuB=0;
    }
//MENU SELECTIONS
/////////////////////////////////////////////////////////////////////////////////////
    if(menuY>=0 && menuY<=35)
    {
      tft.drawRect(0,0,128,35,ST7735_WHITE);//Draw a rectangle around the box and cover adjacent selection rectangles
      tft.drawRect(0,36,128,39,ST7735_BLACK);

      if(b==BUTTON_SELECT)
      {
        tft.fillScreen(ST7735_BLACK);
        delay(100);
        tft.setTextSize(2);
        tft.setTextColor(ST7735_MAGENTA);
        tft.setCursor(2,50);
        tft.print("IMPOSSIBLE");
        tft.setTextSize(0);
        tft.setTextColor(ST7735_WHITE);
        tft.setCursor(5,100);
        tft.print("Turn the device Sideways");
        delay(500);
        tft.fillScreen(ST7735_BLACK);
        tft.setRotation(tft.getRotation()+1);
        STAGE=STAGE+1;//Increase level identifier to "impossible" difficulty
      }
    }


    if(menuY>=36 && menuY<=75)
    {
      tft.drawRect(0,0,128,35,ST7735_BLACK);//Draw a rectangle around the box and cover adjacent selection rectangles
      tft.drawRect(0,76,128,43,ST7735_BLACK);
      tft.drawRect(0,36,128,39,ST7735_WHITE);

      if(b==BUTTON_SELECT)
      {
        tft.fillScreen(ST7735_BLACK);//Selection Restatement
        delay(100);
        tft.setTextSize(4);
        tft.setTextColor(ST7735_RED);
        tft.setCursor(15,50);
        tft.print("HARD");
        tft.setTextSize(0);
        tft.setTextColor(ST7735_WHITE);
        tft.setCursor(5,100);
        tft.print("Turn the device sideways.");
        delay(500);
        STAGE=STAGE+2;//Increase level identifier to "hard" difficulty
        tft.fillScreen(ST7735_BLACK);
        tft.setRotation(tft.getRotation()+1);//Alter Orientation to Landscape
     
      }

    }
    if(menuY>=76 && menuY<=116)
    {
      tft.drawRect(0,118,128,40,ST7735_BLACK);//Draw a rectangle around the box and cover adjacent selection rectangles
      tft.drawRect(0,36,128,39,ST7735_BLACK);
      tft.drawRect(0,76,128,43,ST7735_WHITE);

      if(b==BUTTON_SELECT)
      {
        tft.fillScreen(ST7735_BLACK);//Selection Restatement
        delay(100);
        tft.setTextSize(3);
        tft.setTextColor(ST7735_YELLOW);
        tft.setCursor(10,50);
        tft.print("MEDIUM");
        tft.setTextSize(0);
        tft.setTextColor(ST7735_WHITE);
        tft.setCursor(5,100);
        tft.print("Turn the device sideways");
        delay(5000);
        tft.fillScreen(ST7735_BLACK);
        tft.setRotation(tft.getRotation()+1);//Alter orientation to landscape
        STAGE=STAGE+3;//Increase level identifier to "medium" difficulty
      }
    }
    if(menuY>=118 && menuY<=160)
    {
      tft.drawRect(0,76,128,43,ST7735_BLACK);//Draw a rectangle around the box and cover adjacent selection rectangles
      tft.drawRect(0,118,128,40,ST7735_WHITE);

      if(b==BUTTON_SELECT)
      {
        tft.fillScreen(ST7735_BLACK);//Selection Restatement
        delay(100);
        tft.setTextSize(3);
        tft.setTextColor(ST7735_GREEN);
        tft.setCursor(29,50);
        tft.print("EASY");
        tft.setTextSize(0);
        tft.setTextColor(ST7735_WHITE);
        tft.setCursor(5,100);
        tft.print("Turn the device sideways.");
        delay(1500);
        tft.fillScreen(ST7735_BLACK);
        tft.setRotation(tft.getRotation()+1);//Alter screen orientation to landscape, where the joystick is on the right side of the board
        STAGE=STAGE+4;//Increase level identifier to "easy" difficulty
      }
    }
  }//Menu(Stage1) ends
  //DRAW PONG MAP, COLORS BASED ON DIFFICULTY SELECTED
  ///////////////////////////////////////////////////////////////////////////////////////////////////
  if(STAGE==2)
  {
    tft.fillRect(0,0,tft.width(),2,ST7735_MAGENTA);
    tft.fillRect(0,126,tft.width(),2,ST7735_MAGENTA);
    tft.drawLine(tft.width()/2,2,tft.width()/2,126,ST7735_WHITE);
  }
  if(STAGE==3)
  {
    tft.fillRect(0,0,tft.width(),2,ST7735_RED);
    tft.fillRect(0,126,tft.width(),2,ST7735_RED);
    tft.drawLine(tft.width()/2,2,tft.width()/2,126,ST7735_WHITE);
  }
  if(STAGE==4)
  {
    tft.fillRect(0,0,tft.width(),2,ST7735_YELLOW);
    tft.fillRect(0,126,tft.width(),2,ST7735_YELLOW);
    tft.drawLine(tft.width()/2,2,tft.width()/2,126,ST7735_WHITE);
  }
  if(STAGE==5)
  {
    tft.fillRect(0,0,tft.width(),2,ST7735_GREEN);
    tft.fillRect(0,126,tft.width(),2,ST7735_GREEN);
    tft.drawLine(tft.width()/2,2,tft.width()/2,126,ST7735_WHITE);
  }

  while(STAGE>=2)
  {
    Serial.println("AAA");
    uint8_t b=readButton();//Reads Joystick
    //AI
    ///////////////////////////////////////////////////////////////////////////////////////////////
    if(STAGE==2)//For Impossible
    {
      cY=ballY-12;
    }
    if(STAGE==3)//For Hard
    {
      float cB=5;
      if(ballY==cY+12)
      {
        cY=cY;//Paddle movement
      }
      if(ballY<cY+12)
      {
        cY=cY-cB;//Paddle movement
      }
      if(ballY>cY+12)
      {
        cY=cY+cB;//Paddle movement
      }

    }
    if(STAGE==4)//For Medium
    {
      float cB=4.4;
      if(ballY==cY+12)//Initiation of motion
      {
        cY=cY;
      }
      if(ballY<=cY+8)//Initiation of motion
      {
        cB=-cB;

        cY=cY+cB;//Paddle movement
        if(ballX<=cX+3)
        {
       
          cB=cB*1.4;
        }

      }
      if(ballY>=cY+16)//Initiation of motion
      {
        cB=cB;
        cY=cY+cB;//Paddle movement
        if(ballX<=cX+3)
        {
          cB=cB*1.4;
        }
   
      }
   
    }
    if(STAGE==5)//For Easy
    {
      float cB=3.01;
      if(ballY==cY+12)//Initiation of motion
      {
        cY=cY;
      }
      if(ballY<=cY+10)//Initiation of motion
      {
        cB=-cB;
        cY=cY+cB;//Paddle movement
        if(ballX<=cX+3)
        {

          cB=cB*1.43;
        }
      }
      if(ballY>=cY+14)//Initiation of motion
      {
        cB=cB;
        cY=cY+cB;
        if(ballX<=cX+3)
        {

          cB=cB*1.43;
        }
      }
    }

//SET SCOREBOARD COLORS AND SCORE
//////////////////////////////////////////////////////////////////////////
    tft.setTextSize(2);
    if(STAGE==2)
    {
      tft.setTextColor(ST7735_MAGENTA);
    }
    if(STAGE==3)
    {
      tft.setTextColor(ST7735_RED);
    }
    if(STAGE==4)
    {
      tft.setTextColor(ST7735_YELLOW);
    }
    if(STAGE==5)
    {
      tft.setTextColor(ST7735_GREEN);
    }
    tft.setCursor(50,5);//position of ai score
    tft.print(compScore);
    tft.setCursor(90,5);//position of player score
    tft.print(playerScore);
 
 
 
    //PLAYER PADDLE MOVEMENT
    ////////////////////////////////////////////////////////////////////////////////////////////
    if(b==BUTTON_LEFT)//Joystick Down
    {
      pY=pY+pB;
    }
    if(b==BUTTON_RIGHT)//Joystick Up
    {
      pY=pY-pB;
    }
 
    //PLAYER PADDLE PHYSICS & BALL START RNG'S
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(www==0)//BALL START X-Velocity RNG
    {
      xxx=random(2);//
      //If xxx=0, the ball moves right at start, if xxx=1, then it moves left
      www++;//Makes sure this is done only once per point
      if(xxx==1)
      {
        ballA=-ballA;//reverses velocity of ball
      }
    }
    if(yyy==0)
    {
      zzz=random(5);
      yyy++;
      if(zzz==0)
      {
        ballB=-1;
      }
      if(zzz==1)
      {
        ballB=-0.5;
      }
      if(zzz==2)
      {
        ballB=0;
      }
      if(zzz==3)
      {
        ballB=0.5;
      }
      if(zzz==4)
      {
        ballB=1;
      }
    }
    //DRAW PLAYER AND AI PADDLES
    ////////////////////////////////////////////////////////////////////////////////////////////
    tft.fillRect(cX,cY,3,24,ST7735_WHITE);
    tft.fillRect(pX,pY,3,24,ST7735_WHITE);
    tft.fillRect(ballX,ballY,4,4,ST7735_WHITE);
    delay(30);
    tft.fillRect(cX,cY,3,24,ST7735_BLACK);
    tft.fillRect(pX,pY,3,24,ST7735_BLACK);
    tft.fillRect(ballX,ballY,4,4,ST7735_BLACK);
    tft.drawLine(tft.width()/2,2,tft.width()/2,126,ST7735_WHITE);//middle-court line
   
//PLAYER PADDLE PHYSICS & BALL SPEED INCREASE
//////////////////////////////////////////////////////////////////////////////////////////////////
    if(ballX+4>=pX && ballY+4<=pY+4 && ballY>=pY-3)
    {
      ballX=pX-5;//realign ball
      ballB=ballB-5;
      ballA=ballA*1.36;//ball speed increase
      ballA=-ballA;//reverse ball velocity
      tone(6,NOTE_B4,NoteDuration);
    }
    if(ballX+4>=pX && ballY>=pY+1 && ballY+4<=pY+14)
    {
      ballX=pX-5;//realign ball
      ballB=ballB-2;
      ballA=ballA*1.36;//ball speed increase
      ballA=-ballA;//reverse ball velocity
      tone(6,NOTE_B4,NoteDuration);

    }
    if(ballX+4>=pX && ballY>=pY+10 && ballY+4<=pY+18)
    {
      ballX=pX-5;//realign ball
      ballA=ballA*1.36;//ball speed increase
       ballA=-ballA;//reverse ball velocity
      tone(6,NOTE_B4,NoteDuration);
    }
    if(ballX+4>=pX && ballY+4<=pY+23 && ballY>=pY+14)
    {
      ballX=pX-5;//realign ball
      ballB=ballB+2;
      ballA=ballA*1.36;//ball speed increase
      ballA=-ballA;//reverse ball velocity
      tone(6,NOTE_B4,NoteDuration);
    }
    if(ballX+4>=pX && ballY>=pY+20 && ballY+4<=pY+27)
    {
      ballX=pX-5;//realign ball
      ballB=ballB+4;
      ballA=ballA*1.36;//ball speed increase
      ballA=-ballA;
      tone(6,NOTE_B4,NoteDuration);
    }
 
    //COMPUTER PADDLE PHYSICS
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(STAGE==2)//FOR IMPOSSIBLE
    {
      if(ballX<=cX+3)
      {
        ballA=-ballA;
        ballA=ballA*1.36;
        tone(6,NOTE_B4,NoteDuration);
      }
      //BALL SPEED CAP FOR IMPOSSIBLE
      if(ballA>=16.176||ballA<=-16.176)
      {
        if(ballA>0)
        {
          ballA=22;
        }
        if(ballA<0)
        {
          ballA=-22;
        }
        if(ballX<=cX+3 && ballX>=cX-20)
        {
          ballX=cX+3;
        }
      }
    }
    if(STAGE>=3)//FOR ALL OTHER LEVELS
    {
      if(ballX<=cX+3 && ballY+4<=cY+4 && ballY>=cY-3)
      {

        ballX=cX+4;
        ballB=ballB-4;
        ballA=ballA*1.36;
        ballA=-ballA;
        tone(6,NOTE_B4,NoteDuration);
      }
      if(ballX<=cX+3 && ballY>=cY+1 && ballY+4<=cY+14)
      {

        ballX=cX+4;
        ballB=ballB-2;
        ballA=ballA*1.36;
        ballA=-ballA;
        tone(6,NOTE_B4,NoteDuration);
      }
      if(ballX<=cX+3 && ballY>=cY+10 && ballY+4<=cY+18)
      {

        ballX=cX+4;
        ballA=ballA*1.36;
        ballA=-ballA;
        tone(6,NOTE_B4,NoteDuration);
      }
      if(ballX<=cX+3 && ballY+4<=cY+23 && ballY>=cY+14)
      {
        ballX=cX+4;
        ballB=ballB+2;
        ballA=ballA*1.36;
        ballA=-ballA;
        tone(6,NOTE_B4,NoteDuration);
      }
      if(ballX<=cX+3 && ballY>=cY+20 && ballY+4<=cY+27)
      {

        ballX=cX+4;
        ballB=ballB+4;
        ballA=ballA*1.36;
        ballA=-ballA;
        tone(6,NOTE_B4,NoteDuration);
      }
      Serial.println("BallA=");
      Serial.println(ballA);
    //BALL TO WALL REPAIR CODE
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(ballY<=4)
    {
      ballB=-ballB;
      tone(6,NOTE_B2,NoteDuration);
      if(STAGE==2)
      {
        tft.fillRect(0,0,tft.width(),2,ST7735_MAGENTA);
      }
      if(STAGE==3)
      {

        tft.fillRect(0,0,tft.width(),2,ST7735_RED);
      }
      if(STAGE==4)
      {

        tft.fillRect(0,0,tft.width(),2,ST7735_YELLOW);
      }
      if(STAGE==5)
      {

        tft.fillRect(0,0,tft.width(),2,ST7735_GREEN);
      }
    }
    if(ballY+4>=124)
    {
      ballB=-ballB;
      tone(6,NOTE_B2,NoteDuration);//Noise denotes that a wall has been hit
      if(STAGE==2)
      {
        tft.fillRect(0,126,tft.width(),2,ST7735_MAGENTA);
      }
      if(STAGE==3)
      {

        tft.fillRect(0,126,tft.width(),2,ST7735_RED);
      }
      if(STAGE==4)
      {

        tft.fillRect(0,126,tft.width(),2,ST7735_YELLOW);
      }
      if(STAGE==5)
      {

        tft.fillRect(0,126,tft.width(),2,ST7735_GREEN);
      }
    }
    //Paddle Interraction with wall
    /////////////////////////////////////////////////////////////////////////////////////////////
    if(pY<=0)
    {
      pY=pY+6;
    }
    if(pY+24>=128)
    {
      pY=pY-pB;
    }
    if(cY<=0)
    {
      cY=cY+4;
    }
    if(cY+24>=128)
    {
      cY=cY-6;
    }
    //MAX BALL SPEEDS FOR ALL LEVELS OTHER THAN IMPOSSIBLE
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      if(STAGE==3)
      {
        if(ballA>=12.5||ballA<=-12.5)
        {
          if(ballA>0)
          {
            ballA=16;
          }
          if(ballA<0)
          {
            ballA=-16;
          }
        }
      }
      if(STAGE==4)
      {
        if(ballA>=8.088||ballA<=-8.088)
        {


          if(ballA>0)
          {
            ballA=11;
          }
          if(ballA<0)
          {
            ballA=-11;
          }
        }
      }
      if(STAGE==5)
      {
        if(ballA>=5.147||ballA<=-5.147)
        {


          if(ballA>0)
          {
            ballA=7;
          }
          if(ballA<0)
          {
            ballA=-7;
          }
        }
      }
    }


    //WIN AND LOSS OF POINT
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(ballX<=-1)//IF POINT iS WON
    {
      www=0;//So that rng can be used in the next point to determine ball's starting velocity
      yyy=0;
      tft.setTextSize(2);//BLACK OUT SCORE FOR REPRINT
      tft.setTextColor(ST7735_BLACK);
      tft.setCursor(90,5);
      tft.print(playerScore);
      playerScore=playerScore+1;//ADD 1 TO SCORE
   
      tft.fillRect(pX,pY,3,24,ST7735_WHITE);
      tft.fillRect(cX,cY,3,24,ST7735_WHITE);
      ballX=0;
      tft.fillRect(ballX,ballY,4,4,ST7735_CYAN);
      delay(250);
      tft.fillRect(ballX,ballY,4,4,ST7735_BLACK);
      delay(250);
      tft.fillRect(ballX,ballY,4,4,ST7735_CYAN);
      delay(250);
      tft.fillRect(ballX,ballY,4,4,ST7735_BLACK);
      delay(250);
      tft.fillRect(ballX,ballY,4,4,ST7735_CYAN);
      delay(500);
      tft.fillRect(ballX,ballY,4,4,ST7735_BLACK);
      tft.fillRect(pX,pY,3,24,ST7735_BLACK);
      tft.fillRect(cX,cY,3,24,ST7735_BLACK);
      delay(700);

      ballB=0;//RESET PADDLE AND BALL POSITIONS
      ballX=78;
      ballY=61;
      ballA=3;
      pY=50;
      cY=50;
      delay(2000);


    }
    if(ballX+4>=tft.width()+1)//IF POINT IS LOST
    {
      www=0;//So that rng can be used in the next point to determine ball's starting velocity
      yyy=0;
      tft.setTextSize(2);
      tft.setTextColor(ST7735_BLACK);
      tft.setCursor(50,5);
      tft.print(compScore);
      compScore=compScore+1;
   
      tft.fillRect(pX,pY,3,24,ST7735_WHITE);
      tft.fillRect(cX,cY,3,24,ST7735_WHITE);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_CYAN);
      delay(250);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_BLACK);
      delay(250);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_CYAN);
      delay(250);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_BLACK);
      delay(250);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_CYAN);
      delay(500);
      tft.fillRect(ballX-3,ballY,4,4,ST7735_BLACK);
      tft.fillRect(pX,pY,3,24,ST7735_BLACK);
      tft.fillRect(cX,cY,3,24,ST7735_BLACK);
      delay(400);
   
      ballB=0;
      ballX=78;
      ballY=61;
      ballA=3;
      pY=50;
      cY=50;
      //delay(2000);
    }
    //BALL TO WALL REPOSITION
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if(ballY<=4)
    {
      ballY=6;
    }
    if(ballY>=124)
    {
      ballY=122;
    }
    /////////////////////////////ACTUAL MOVEMENT
    ballX=ballX+ballA;
    ballY=ballY+ballB;
    Serial.println("BALLA=");
    Serial.print(ballA);
    //WIN AND LOSS TITLE
    ///////////////////////////////////////////////////////////////////////////WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW///////////////////////
    while(playerScore==7)
    {
      int qqq=1;
      tft.fillScreen(ST7735_BLACK);
      tft.setTextSize(4);
      while(qqq<=2)
      {
        if(STAGE==2)
        {
          tft.setTextColor(ST7735_MAGENTA);
        }
        if(STAGE==3)
        {
          tft.setTextColor(ST7735_RED);
        }
        if(STAGE==4)0
        {
          tft.setTextColor(ST7735_YELLOW);
        }
        if(STAGE==5)
        {
          tft.setTextColor(ST7735_GREEN);
        }
        tft.setCursor(10,40);
        tft.print("PLAYER WINS!");

        if(note<24)//Plays the song loop for win
        {
          tone(6,RocketSong[note],240);
          delay(246);
          note++;
        }
        if(note>=24)
        {
          note=0;
        }
        uint8_t b=readButton();//Read joystick
        if(b==BUTTON_SELECT)//Return to title screen
        {
          tft.fillScreen(ST7735_BLACK);
          qqq=3;
          playerScore=0;
          ppp=0;
          tft.setRotation(tft.getRotation()-1);
          STAGE=0;
        }
      }
    }
//If player loses
    while(compScore==7)
    {
      int qqq=1;
      tft.fillScreen(ST7735_BLACK);
      tft.setTextSize(4);
      while(qqq<=2)
      {
        if(STAGE==2)
        {
          tft.setTextColor(ST7735_MAGENTA);
        }
        if(STAGE==3)
        {
          tft.setTextColor(ST7735_RED);
        }
        if(STAGE==4)
        {
          tft.setTextColor(ST7735_YELLOW);
        }
        if(STAGE==5)
        {
          tft.setTextColor(ST7735_GREEN);
        }
        tft.setCursor(10,40);
        tft.print("PLAYER LOSES");
        delay(300);
        //Losing song is played once
        while (noteval<=6)
        {
          tone(6,failsong[noteval],240);
          delay(260);
          noteval++;
        }
        uint8_t b=readButton();//Read joystick
        if(b==BUTTON_SELECT)//Return to title screen
        {
          tft.fillScreen(ST7735_BLACK);
          qqq=3;
          compScore=0;
          ppp=0;
          tft.setRotation(tft.getRotation()-1);
          STAGE=0;
        }
      }
    }
  }
}
//Pictures of the system used





No comments:

Post a Comment