#include <Adafruit_GFX.h> // Core graphics library
#include <TouchScreen_kbv.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#define YP A2 // must be an analog pin, use "An" notation!
#define XM A3 // must be an analog pin, use "An" notation!
#define YM 8 // can be a digital pin
#define XP 9 // can be a digital pin
#define TS_MINX 130
#define TS_MAXX 905
#define TS_MINY 75
#define TS_MAXY 930
#define MINPRESSURE 20
TouchScreen_kbv ts = TouchScreen_kbv(XP, YP, XM, YM, 300);
TSPoint_kbv p;
bool win = false, dir, paddle, ballLost, dirBlock;
uint8_t lop, lop2, level, ball;
uint16_t xPaddle = 105;
uint16_t score;
bool blocks[10][5];
float ballXdir, ballYdir, ballX, ballY, paddleLoop;
const uint16_t colorBlock[7] = {TFT_YELLOW, TFT_RED, TFT_PINK, TFT_GREEN, TFT_PURPLE, TFT_BLUE, TFT_ORANGE};
#define left 0
#define right 1
#define Ball(x,y,color) tft.fillRect(x, y, 7, 7, color);
void setup() {
Serial.begin(9600);
tft.reset();
tft.begin(tft.readID());
tft.setRotation(0);
randomSeed(A5);
}
void loop() {
gameStart();
gamePlay();
}
void gamePlay() {
printScore();
ballX = random(20, 301);
ballY = 220;
ballXdir = random(0, 2);
if (ballXdir == 0) ballXdir = -0.2;
else ballXdir = +0.2;
ballYdir = 0.2;
Ball(ballX, ballY, TFT_WHITE);
do {
if (ballX < 21 || ballX > 291)ballXdir *= -1;
if (ballY >= 420 && ballLost == false) {
if (ballX + 6 >= xPaddle - 21 && ballX <= xPaddle + 21) {
ballLost = false;
paddle = true;
if (ballX >= xPaddle - 3 && ballX <= xPaddle + 3) {
ballXdir = 0.2;
paddle = false;
}
if (ballX >= xPaddle - 7 && ballX <= xPaddle + 7) {
ballXdir = 0.3;
paddle = false;
}
if (paddle && ballX >= xPaddle && ballX <= xPaddle + 10) {
ballXdir = 0.4;
paddle = false;
}
if (paddle && ballX >= xPaddle - 10 && ballX <= xPaddle) {
ballXdir = -0.4;
paddle = false;
}
if (paddle && ballX >= xPaddle && ballX <= xPaddle + 13) {
ballXdir = 0.5;
paddle = false;
}
if (paddle && ballX >= xPaddle - 13 && ballX <= xPaddle) {
ballXdir = -0.5;
paddle = false;
}
if (paddle && ballX >= xPaddle && ballX <= xPaddle + 17) {
ballXdir = 0.6;
paddle = false;
}
if (paddle && ballX >= xPaddle - 17 && ballX <= xPaddle) {
ballXdir = -0.6;
paddle = false;
}
if (paddle && ballX >= xPaddle && ballX <= xPaddle + 20) {
ballXdir = 0.7;
paddle = false;
}
if (paddle && ballX >= xPaddle - 20 && ballX <= xPaddle) {
ballXdir = -0.7;
paddle = false;
}
paddleLoop -= 0.02;
if (paddleLoop == -0.8) paddleLoop = 0;
ballYdir = -0.2 + paddleLoop;
dirBlock = false;
} else ballLost = true;
}
if (ballY < 91) {
ballYdir *= -1;
dirBlock = false;
}
Ball(ballX, ballY, TFT_BLACK);
tft.fillRect(xPaddle -19, 430, 40, 5, TFT_WHITE);
ballX += ballXdir;
ballY += ballYdir;
Ball(ballX, ballY, TFT_WHITE);
if (ballY > 453 && ballLost == true) win = true;
readTouch();
if (p.z > MINPRESSURE) {
// shift right
if (p.x > xPaddle) {
if (dir == left)xPaddle -= 1;
xPaddle += 1;
if (xPaddle > 279)xPaddle -= 1;
else {
tft.drawFastVLine(xPaddle - 20, 430, 5, TFT_BLACK);
dir = right;
}
}
// shift left
if (p.x < xPaddle) {
if (dir == right)xPaddle += 1;
xPaddle -= 1;
if (xPaddle < 40)xPaddle += 1;
else {
tft.drawFastVLine(xPaddle + 21, 430, 5, TFT_BLACK);
dir = left;
}
}
}
check();
} while (!win);
ball -= 1;
if (ball == 0)loop();
else {
win = false;
ballLost = false;
paddleLoop = 0;
Ball(ballX, ballY, TFT_BLACK);
gamePlay();
}
}
void gameStart() {
ballLost = false;
win = false;
score = 0;
level = 1;
ball = 3;
tft.fillScreen(TFT_BLUE);
tft.setTextSize(4);
tft.setCursor(62, 12);
tft.setTextColor(TFT_BLACK);
tft.print("BreakOut");
tft.setCursor(64, 15);
tft.setTextColor(TFT_WHITE);
tft.print("BreakOut");
tft.fillRect(20, 90, 280, 370, TFT_BLACK);
tft.setTextSize(2);
tft.setCursor(30, 60);
tft.print("Score");
tft.setCursor(200, 50);
tft.print("Level");
tft.setCursor(200, 70);
tft.print("Balls");
tft.setCursor(50, 180);
tft.print("Tap Screen to begin");
printScore();
do {
readTouch();
delay(100);
} while (p.z < MINPRESSURE);
tft.fillRect(50, 180, 230, 17, TFT_BLACK);
tft.fillRect(xPaddle - 20, 430, 40, 5, TFT_WHITE);
drawField();
}
void drawField() {
for (lop = 0; lop < 10; lop++) {
for (lop2 = 0; lop2 < 5; lop2++) {
tft.fillRect(lop * 28 + 23, lop2 * 15 + 131, 22, 8, colorBlock[lop2]);
tft.drawRect(lop * 28 + 22, lop2 * 15 + 130, 24, 10, TFT_WHITE);
blocks[lop][lop2] = 1;
}
}
}
void check() {
for (lop = 0; lop < 10; lop++) {
for (lop2 = 0; lop2 < 5; lop2++) {
if (blocks[lop][lop2] == 1) {
if (lop * 28 + 22 <= ballX + 6 && lop * 28 + 46 >= ballX && lop2 * 15 + 130 <= ballY + 6 && lop2 * 15 + 140 >= ballY) {
tft.fillRect(lop * 28 + 22, lop2 * 15 + 130, 24, 10, TFT_BLACK);
blocks[lop][lop2] = 0;
if (dirBlock == false) {
ballYdir *= - 1;
dirBlock = true;
} else ballXdir *= -1;
score += 10;
if (score == level * 500) {
level += 1;
Ball(ballX, ballY, TFT_BLACK);
drawField();
gamePlay();
}
printScore();
}
}
}
}
}
void printScore() {
tft.fillRect(100, 60, 60, 14, TFT_BLUE);
tft.setCursor(100, 60);
if (score < 100) tft.print("000" + String(score));
if (score < 1000 && score > 99) tft.print("00" + String(score));
if (score < 10000 && score > 999) tft.print("0" + String(score));
if (score < 100000 && score > 9999) tft.print(score);
tft.fillRect(270, 50, 24, 14, TFT_BLUE);
tft.setCursor(270, 50);
if (level < 10) tft.print("0" + String(level));
if (level < 100 && level > 9) tft.print(level);
tft.fillRect(270, 70, 14, 14, TFT_BLUE);
tft.setCursor(270, 70);
tft.print(ball);
}
void readTouch() {
p = ts.getPoint();
p.x = p.x + p.y;
p.y = p.x - p.y;
p.x = p.x - p.y;
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
p.y = tft.height() - (map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
}
Comments
Please log in or sign up to comment.