Search code examples
carduinogame-physicspong

Arduino Esplora Pong Game


Over the last couple of days I've been working on a Pong game for Arduino Esplora with Arduino's TFT display. Everything in the game works except that, when the player scores the ball gets deleted from it's last location and reappears in the center (as it should), while when the computer scores the ball doesn't get deleted (or overwritten would be a better word) but reappears in the center. I have tried some changes on this area of the code with no success, particularly since I have no idea where it comes from. Goal detection goes from line 161 to 187.

#include <Esplora.h>
#include <TFT.h>  // Arduino LCD library
#include <SPI.h>

float BPX;
float BPY;
int byx;
int bx;
int A;
int by = 1;
int playerScore;
int computerScore;
#define WINSCORE 5
int CPaddlePlus;
int CPaddleMinus;
int R, L, D, U;
int playerPaddle;
int computerPaddle;
int Random;
void setup() {

  // initialize the screen
  EsploraTFT.begin();
  EsploraTFT.background(0, 0, 0);
  EsploraTFT.setTextColor(ST7735_YELLOW, ST7735_BLACK);
  EsploraTFT.setTextSize(5);
  EsploraTFT.setCursor(22, 15);
  EsploraTFT.print("PONG");
  EsploraTFT.setTextSize(1);
  EsploraTFT.println("");
  EsploraTFT.println("   By: David Rutherford");
  EsploraTFT.println("");
  EsploraTFT.println("   Esplora port by:");
  EsploraTFT.println("          -Mike Barela");
  EsploraTFT.println("          -Bernardo Meurer");
  EsploraTFT.setTextColor(ST7735_WHITE, ST7735_BLACK);
  EsploraTFT.println(" ");
  EsploraTFT.println(" Press Switch 4 To Start");
  while (Esplora.readButton(SWITCH_RIGHT) == HIGH)
    ;
  EsploraTFT.fillScreen(ST7735_BLACK);
  EsploraTFT.setRotation(0);
  DrawCourt(0);

  playerScore = 0;
  computerScore = 0;
  DisplayScore(playerScore, computerScore);
  BPX = 15;
  BPY = 15;
  byx = 15;
  bx = 1;
  A = 1;
  playerPaddle = 48;
  computerPaddle = 48;


  long seed = Esplora.readLightSensor() * Esplora.readMicrophone() / Esplora.readTemperature(DEGREES_F);
  randomSeed(seed);
}

void loop() {
  if ((BPY == 80) || (BPY == 20)) {
    Random = random(1, 10);
  }
  CPaddlePlus = computerPaddle + 16;
  CPaddleMinus = computerPaddle - 16;
  if (Random <= 8) {
    if ((A == 1) || ((BPY > 100) && (A == -1))) {
      if ((bx == -1) && (BPX < (CPaddlePlus))) {
        U = 1;
        D = 0;
      }
      if ((bx == 1) && (BPX > (CPaddlePlus))) {
        D = 1;
        U = 0;
      }
    }
    else {
      D = 0;
      U = 0;
    }
  }
  if ((Random > 8) && (Random <= 9)) {
    if ((A == 1) || ((BPY > 100) && (A == -1))) {
      if ((bx == -1) && (BPX < (CPaddlePlus))) {
        U = 0;
        D = 1;
      }
      if ((bx == 1) && (BPX > (CPaddlePlus))) {
        D = 0;
        U = 1;
      }
    }
    else {
      D = 0;
      U = 0;
    }
  }
  if (Random > 9) {
    if ((A == 1) || ((BPY > 100) && (A == -1))) {
      if ((bx == -1) && (BPX < (CPaddleMinus))) {
        U = 1;
        D = 0;
      }
      if ((bx == 1) && (BPX > (CPaddleMinus))) {
        D = 1;
        U = 0;
      }
    }
    else {
      D = 0;
      U = 0;
    }
  }
  DrawCourt(0);
  R = Esplora.readButton(SWITCH_DOWN);
  L = Esplora.readButton(SWITCH_UP);
  playerPaddle = playerPaddle + R;
  playerPaddle = playerPaddle - L;
  computerPaddle = computerPaddle + D;
  computerPaddle = computerPaddle - U;

  EsploraTFT.fillRect(playerPaddle - 1, 3, 2, 3, ST7735_BLACK);
  EsploraTFT.fillRect(playerPaddle + 33, 3, 2, 3, ST7735_BLACK);
  EsploraTFT.fillRect(playerPaddle, 3, 32, 3, ST7735_GREEN);
  if (playerPaddle == 1) {
    playerPaddle = 2;
  }
  if (playerPaddle == 95) {
    playerPaddle = 94;
  }

  EsploraTFT.fillRect(computerPaddle, 154, 32, 3, ST7735_GREEN);
  EsploraTFT.fillRect(computerPaddle - 1, 154, 2, 3, ST7735_BLACK);
  EsploraTFT.fillRect(computerPaddle + 33, 154, 2, 3, ST7735_BLACK);
  if (computerPaddle == 1) {
    computerPaddle = 2;
  }
  if (computerPaddle == 95) {
    computerPaddle = 94;
  }
  byx += A;
  BPY = byx;
  BPX += bx ;
  if ((BPX == 127) || (BPX == 2)) {
    (bx = (-1 * bx));
  }
  else {
  };
  if ((BPX <= (computerPaddle + 38)) && (BPX >= (computerPaddle - 6)) && (BPY == 149)) {
    (A = (-1 * A));
  }
  else {
  };
  if ((BPX <= (playerPaddle + 38) && (BPX >= (playerPaddle - 6)) && (BPY == 11))) {
    (A = (-1 * A));
  }
  else {
  };
  if (BPY >= 160 || BPY <= 0) {//Goal Detection
    if (BPY >= 160) {  
      playerScore = playerScore + 1;
      DisplayScore(playerScore, computerScore);
      DrawCourt(0);
      EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
      BPX = 64;
      BPY = 80;
      EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
      delay(3000);
      EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
      byx = 80;
    }
    else {
      computerScore = computerScore + 1;
      DisplayScore(playerScore, computerScore);
      DrawCourt(0);
      EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
      BPX = 64;
      BPY = 80;
      EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
      delay(3000);
      EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
      byx = 80;
    }

  }
  DisplayScore(playerScore, computerScore);
  if (playerScore == WINSCORE || computerScore == WINSCORE) {
    EsploraTFT.setRotation(1);
    EsploraTFT.setTextColor(ST7735_WHITE, ST7735_BLACK);
    EsploraTFT.setCursor(8, 50);
    EsploraTFT.setTextSize(2);
    if (playerScore == WINSCORE) {
      EsploraTFT.print("YOU WIN");
    }
    else {
      EsploraTFT.print("ESPLORA WINS");
    }

    EsploraTFT.setTextSize(1);
    EsploraTFT.setTextColor(ST7735_YELLOW, ST7735_BLACK);
    EsploraTFT.setCursor(8, 90);
    EsploraTFT.print("Press Switch 4 To Restart");
    while (Esplora.readButton(SWITCH_RIGHT) == HIGH)
      ;
    EsploraTFT.setRotation(0);
    EsploraTFT.fillScreen(ST7735_BLACK);
    EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
    BPX = 15;
    BPY = 15;
    byx = 15;
    bx = 1;
    A = 1;
    EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
    EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
    //EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
    //EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
    computerScore = 0;
    playerScore = 0;
    DrawCourt(0);
    DisplayScore(playerScore, computerScore);
    delay(2000);
  }
  EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
  EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
}
void DrawCourt(boolean onlycenter) {
  if (!onlycenter) {
    EsploraTFT.drawFastVLine(0, 0, 160, ST7735_GREEN);
    EsploraTFT.drawFastVLine(127, 0, 160, ST7735_GREEN);
  }
  EsploraTFT.drawFastHLine(0, 80, 127, ST7735_GREEN);
}
void DisplayScore(int playerScore, int computerScore) {
  EsploraTFT.setRotation(1);
  EsploraTFT.setTextColor(ST7735_GREEN, ST7735_BLACK);
  EsploraTFT.setCursor(65, 5);
  EsploraTFT.setTextSize(2);
  EsploraTFT.print(playerScore);
  EsploraTFT.setCursor(85, 5);
  EsploraTFT.print(computerScore);
  EsploraTFT.setRotation(0);
}

A visualization of what's happening: Bug Picture


Solution

  • So following @PaulOgilvie's idea I fixed the problem with the following code:

    if (BPY >= 160 || BPY <= 0) {//Goal Detection
        if (BPY >= 160) {  
          playerScore = playerScore + 1;
        }
        else {
          computerScore = computerScore + 1;
        }
        DrawCourt(0);
        EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
        EsploraTFT.fillRect(computerPaddle, 154, 32, 3, ST7735_GREEN);
        EsploraTFT.fillRect(1,0,126,15,ST7735_BLACK);
        EsploraTFT.fillRect(playerPaddle, 3, 32, 3, ST7735_GREEN);
        DisplayScore(playerScore, computerScore);
        BPX = 64;
        BPY = 80;
        EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
        delay(3000);
        EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
        byx = 80;
      }
    

    Basically I just made a workaround drawing a big black rectangle on top of the whole thing.