This article is the first article, with which I would like to begin a story about the unique TFT shield designed for the Arduino Uno platform, which makes it possible to significantly expand the capabilities of Arduino Uno. Despite the fact that this TFT shield is still under development, at the moment there is already a working device.
HardwareBrief characteristics of TFT shield:
- Size 3.5 " diagonal,
- Resolution 320x240,
- Number of colors 65536 (16-bit),
- Resistive touch screen (XPT2046 controller),
- 5 buttons,
- RTC IC DS1307 with 3V lithium battery CR1220,
- Slot for connecting a micro SD card,
- 4-pin (2.54 mm) connector for connecting the Bluetooth module HC-05 (-06),
- 20-pin (2.54 mm) connector for camera (OV7670).
At the moment, the following library functions are implemented for working with graphics: drawing points, lines, circles, rectangles.The most popular library from Adafruit Industries was adapted for working with fonts. Additionally, work with the touch screen and buttons is implemented.Demo sketch to demonstrate the work with graphics and fonts:
#include <YATFT.h> // Hardware-specific library
#include <Adafruit_GFX.h> // Include Adafruit-GFX library
#include <Fonts/FreeSerif9pt7b.h> // Include Adafruit fonts
#include <Fonts/FreeSerifItalic24pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
YATFT tft(0);
uint32_t total_time;
uint16_t Color[4] = {BRIGHTBLUE, BRIGHTGREEN, BRIGHTRED, BRIGHTYELLOW};
uint16_t Gray[7] = {GRAY0, GRAY1, GRAY2, GRAY3, GRAY4, GRAY5, GRAY6};
/*************************************************************************************************/
void ClearScreen (void)
{
tft.SetColor(BLACK); // Set fone color
tft.ClearDevice(); // Fill all screen
}
void setup()
{
Serial.begin(115200); // initialize the serial port
Serial.println("Arduino TFT_shield Example 1!");
tft.begin(); // initialize the display
}
void loop()
{
uint16_t x, y, x2, y2, mask_gray;
uint16_t i;
ClearScreen();
// Fonts
Serial.print("1) View Fonts (");
total_time = millis();
tft.SetColor(BRIGHTBLUE);
tft.SetFont(NULL);
tft.OutTextXY(5, 5, "Demonstration of work with the TFT display.");
tft.SetColor(BRIGHTGREEN);
tft.SetFont(&FreeSerif9pt7b);
tft.OutTextXY(5, 20, "The example uses fonts from Adafruit.");
tft.SetFont(&FreeSerifItalic24pt7b);
tft.SetColor(BRIGHTCYAN);
tft.OutTextXY(5, 45, "3,5''");
tft.SetColor(BRIGHTRED);
tft.OutTextXY(90, 45, "QVGA");
tft.SetColor(BRIGHTMAGENTA);
tft.OutTextXY(230, 45, "disp.");
tft.SetColor(BRIGHTYELLOW);
tft.SetFont(&FreeSans24pt7b);
tft.OutTextXY(5, 100, "A R D U I N O + T F T");
tft.SetFont(NULL);
for (i = 0; i < 7; i++)
{
tft.SetColor(Gray[i]);
tft.OutTextXY(5, 170+10*i, "Demonstration of work with the TFT display.");
}
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(3000);
ClearScreen();
// Circle
Serial.print("2) Draw circle (");
total_time = millis();
tft.SetColor(BRIGHTRED);
for (i = 10; i < GetMaxY()>>1; i += 10) {
tft.DrawCirc(GetMaxX()>>1, GetMaxY()>>1, i);
}
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
// DrawFillCircle & DrawFillRect
Serial.print("3) Draw FillCircle and FillRect (");
total_time = millis();
tft.SetColor(BRIGHTRED);
tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,110);
tft.SetColor(BRIGHTCYAN);
tft.DrawFillRect(GetMaxX()/2-77,GetMaxY()/2-77, GetMaxX()/2+77,GetMaxY()/2+77);
tft.SetColor(BRIGHTGREEN);
tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,77);
tft.SetColor(BRIGHTMAGENTA);
tft.DrawFillRect(GetMaxX()/2-54,GetMaxY()/2-54, GetMaxX()/2+54,GetMaxY()/2+54);
tft.SetColor(BRIGHTBLUE);
tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,54);
tft.SetColor(BRIGHTYELLOW);
tft.DrawFillRect(GetMaxX()/2-37,GetMaxY()/2-37, GetMaxX()/2+37,GetMaxY()/2+37);
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
ClearScreen();
// Arc
Serial.print("4) Draw Arc (");
total_time = millis();
ClearScreen();
tft.SetColor(BRIGHTBLUE);
tft.DrawArc((GetMaxX()>>1)-60,(GetMaxY()>>1)-60,(GetMaxX()>>1)+60,(GetMaxY()>>1)+60,20,30,0xFF);
tft.SetColor(BRIGHTGREEN);
tft.DrawArc((GetMaxX()>>1)-40,(GetMaxY()>>1)-40,(GetMaxX()>>1)+40,(GetMaxY()>>1)+40,20,30,0xFF);
tft.SetColor(BRIGHTRED);
tft.DrawArc((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,20,30,0xFF);
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
Serial.print("5) Draw FillBevel (");
total_time = millis();
tft.SetColor(BRIGHTBLUE);
tft.DrawFillBevel((GetMaxX()>>1)-60,(GetMaxY()>>1)-60,(GetMaxX()>>1)+60,(GetMaxY()>>1)+60,30);
tft.SetColor(BRIGHTGREEN);
tft.DrawFillBevel((GetMaxX()>>1)-40,(GetMaxY()>>1)-40,(GetMaxX()>>1)+40,(GetMaxY()>>1)+40,30);
tft.SetColor(BRIGHTRED);
tft.DrawFillBevel((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,30);
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
ClearScreen();
Serial.print("6) Draw Arc (");
total_time = millis();
for (i = 0; i < 4; i++) {
tft.SetColor(Color[i]);
tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1)-50,(GetMaxX()>>1),(GetMaxY()>>1)+50,50,60,0x11<<i);
}
for (i = 0; i < 4; i++) {
tft.SetColor(Color[i]);
tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1)-30,(GetMaxX()>>1),(GetMaxY()>>1)+30,35,45,0x11<<i);
}
for (i = 0; i < 4; i++) {
tft.SetColor(Color[i]);
tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1),(GetMaxX()>>1),(GetMaxY()>>1),20,30,0x11<<i);
}
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
ClearScreen();
// Draw 1000 random lines
Serial.print("7) Draw 1000 random lines (");
total_time = millis();
for (i = 0; i < 1000; i++) {
tft.SetColor(random(65535));
x = random(GetMaxX());
y = random(GetMaxY());
x2 = random(GetMaxX());
y2 = random(GetMaxY());
tft.DrawLine(x, y, x2, y2);
}
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
// Draw 1000 random lines
Serial.print("8) ReDraw 10 Fill Screen (");
total_time = millis();
tft.SetColor(BLACK); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTBLUE); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(YELLOW); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTGREEN); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTRED); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTCYAN); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(GREEN); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTYELLOW); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BRIGHTCYAN); // Set fone color
tft.ClearDevice(); // Fill all screen
tft.SetColor(BLACK); // Set fone color
tft.ClearDevice(); // Fill all screen
total_time = millis() - total_time;
Serial.print(total_time);
Serial.println(" ms)");
delay(1000);
}
A demo sketch to demonstrate how to work with fonts and a touch screen:
#include <YATFT.h> // Hardware-specific library
#include <SPI.h> // Include SPI library
#include <XPT2046_Touchscreen.h> // Include Touchscreen library
#include <Adafruit_GFX.h> // Include Adafruit-GFX library
#include <Fonts/FreeSerif9pt7b.h> // Include Adafruit fonts
#include <Fonts/FreeSerifItalic24pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
// Touchscreen: MOSI=11, MISO=12, SCK=13, CS=2
#define CS_PIN 2
XPT2046_Touchscreen ts(CS_PIN, 255);
YATFT tft(0);
#define Y_BAR_TOP (GetMaxY()-50)
#define Y_BAR_BOT GetMaxY()
#define BUTTON1_MASK 0x01
#define BUTTON2_MASK 0x02
#define BUTTON3_MASK 0x04
#define BUTTON4_MASK 0x08
#define BUTTON5_MASK 0x10
/*
If using the shield, all control and data lines are fixed, and
a simpler declaration can optionally be used:
*/
//uint32_t total_time;
uint16_t pos_x[] = {0,0,0,0};
uint16_t pos_y[] = {0,0,0,0};
uint8_t pos_x_cnt = 0;
uint8_t pos_y_cnt = 0;
uint16_t pos_x_mid = 0;
uint16_t pos_y_mid = 0;
uint16_t color_paint = WHITE;
uint8_t buttons = 0;
uint16_t Color[4] = {BRIGHTBLUE, BRIGHTGREEN, BRIGHTRED, BRIGHTYELLOW};
uint16_t Gray[7] = {GRAY0, GRAY1, GRAY2, GRAY3, GRAY4, GRAY5, GRAY6};
/*************************************************************************************************/
void ClearScreen (void)
{
tft.SetColor(BLACK); // Set fone color
tft.ClearDevice(); // Fill all screen
}
void setup()
{
Serial.begin(115200); // initialize the serial port
Serial.println("Arduino TFT_shield Example1!");
ts.begin(); // Init Touchscreen
SPI.end(); // Disable SPI for correct work DB2 (SS) pin
tft.begin(); // initialize the display
RefreshWindow();
}
void loop()
{
uint16_t x, y;
// Touch
// When the SS pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
SPI.begin();
if (ts.touched())
{
TS_Point p = ts.getPoint();
Serial.print(F("Pressure = "));
Serial.print(p.z);
Serial.print(F(", x = "));
Serial.print(p.x);
Serial.print(F(", y = "));
Serial.print(p.y);
Serial.println();
delay(3); // Delay for filtering
SPI.end(); // Disable SPI for correct work DB2 (SS) pin
// Calculate coordinates x, y from code ADC
if (p.x < 200) p.x = 200;
if (p.y < 250) p.y = 250;
#if 0
x = (uint16_t)(320L - ((uint32_t)p.x - 200L)*10L/115L);
y = (uint16_t)(((uint32_t)p.y - 250L)/15L);
#else
x = (uint16_t)(0 + ((uint32_t)p.y - 200L)*10L/115L);
y = (uint16_t)(((uint32_t)p.x - 250L)/15L);
#endif
// Filtering
pos_x_mid = (pos_x[0] + pos_x[1] + pos_x[2] + pos_x[3])/4;
pos_y_mid = (pos_y[0] + pos_y[1] + pos_y[2] + pos_y[3])/4;
pos_x[pos_x_cnt++] = x;
pos_y[pos_y_cnt++] = y;
pos_x_cnt &= 0x03;
pos_y_cnt &= 0x03;
if (x > (pos_x_mid - 10) && x < (pos_x_mid + 10) && y > (pos_y_mid - 10) && y < (pos_y_mid + 10 )) {
if (y > Y_BAR_TOP && y < Y_BAR_BOT) {
if (x < 1*(GetMaxX()+1)/5) { // Touch Bar 1
color_paint = Color[0];
RefreshTitle();
} else
if (x < 2*(GetMaxX()+1)/5) { // Touch Bar 2
color_paint = Color[1];
RefreshTitle();
} else
if (x < 3*(GetMaxX()+1)/5) { // Touch Bar 3
color_paint = Color[2];
RefreshTitle();
} else
if (x < 4*(GetMaxX()+1)/5) { // Touch Bar 4
color_paint = Color[3];
RefreshTitle();
} else { // Clear screen
RefreshWindow();
}
} else {
tft.SetColor(color_paint);
tft.DrawFillRect(x-1, y-1, x+1, y+1);
}
}
}
SPI.end(); // Disable SPI for correct work DB2 (SS) pin
ScanKey();
}
void RefreshWindow(void)
{
color_paint = WHITE;
ClearScreen();
for (uint8_t i = 0; i < 4; i++) {
tft.SetColor(Color[i]);
tft.DrawFillRect((i+1)*((GetMaxX()+1)/5), Y_BAR_TOP, (i)*((GetMaxX()+1)/5), Y_BAR_BOT);
}
RefreshTitle();
tft.SetColor(WHITE);
tft.OutTextXY(GetMaxX() - 50, GetMaxY() - 45, "Clear");
tft.OutTextXY(GetMaxX() - 55, GetMaxY() - 25, "screen");
}
void RefreshTitle(void)
{
tft.SetColor(color_paint);
tft.SetFont(&FreeSerif9pt7b);
tft.OutTextXY(3, 20, "Touch color bar and screen or press key.");
}
void ScanKey(void)
{
static uint8_t buttons_last = 0;
buttons = tft.scanButtons();
if (buttons != buttons_last) {
if (buttons & BUTTON1_MASK) { // Bar 1
color_paint = Color[0];
RefreshTitle();
}
if (buttons & BUTTON2_MASK) { // Bar 2
color_paint = Color[1];
RefreshTitle();
}
if (buttons & BUTTON3_MASK) { // Bar 3
color_paint = Color[2];
RefreshTitle();
}
if (buttons & BUTTON4_MASK) { // Bar 4
color_paint = Color[3];
RefreshTitle();
}
if (buttons & BUTTON5_MASK) { // Clear screen
RefreshWindow();
}
}
buttons_last = buttons;
}
Demo sketch of the logical game "Columns" for demonstration of work with graphics, text and buttons:
#include <YATFT.h>
#include <XPT2046_Touchscreen.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>
YATFT tft(0);
long randNumber;
#define KEY_EMPTY 0
#define KEY_SWAP 1
#define KEY_FALL 2
#define KEY_LEFT 3
#define KEY_RIGHT 4
#define DISPLAY_MAX_X 320
#define DISPLAY_MAX_Y 240
#define MaxCol 8
#define MaxRow 17
#define SmeX 3
#define SmeY 3
#define razmer 15
#define LL 250
#define NumCol 6
#define MaxLevel 8
#define PeriodLevel 80
#define DISP_LEFT ((DISPLAY_MAX_X - MaxCol*razmer)/2 - 2)
#define DISP_RIGHT ((DISPLAY_MAX_X + MaxCol*razmer)/2 + 2)
#define DISP_TOP ((DISPLAY_MAX_Y - (MaxRow-4)*razmer)/2 - 2 - 10)
#define DISP_BOT ((DISPLAY_MAX_Y + (MaxRow-4)*razmer)/2 + 2 - 10)
uint8_t MasSt[MaxCol][MaxRow], MasTmp[MaxCol][MaxRow], MasOld[MaxCol][MaxRow], fignext[3];
uint8_t Level=1, OldLevel, tr, flfirst=1;
uint16_t MasCol[]={WHITE, BLACK, BRIGHTRED, BRIGHTBLUE, BRIGHTGREEN, BRIGHTYELLOW, BRIGHTMAGENTA, BRIGHTCYAN};
unsigned long Counter,Score=0, TScore=0, Record=0, OldRecord, OldScore, myrecord;
uint16_t tempspeed;
bool fl, Demo=true, myfl=false, Arbeiten=false, FlNew, FlZ=false;
int8_t VAL, Mp, x,y;
int8_t mmm [4][2]={{-1,0},{0,-1},{1,0},{0,1}};
uint16_t MasSpeed[MaxLevel]={500,450,400,350,300,250,200,100};
/*********************************************************************/
void setup(void)
{
// initialize the serial port
Serial.begin(115200);
Serial.println("TFT_shield_Game1 example!");
tft.begin(); // initialize the display
randomSeed(analogRead(5));
tft.SetColor(WHITE);
tft.ClearDevice();
tft.SetColor(RED);
tft.SetFont(&FreeSerif9pt7b);
tft.OutTextXY( 20, 20, "LEVEL");
tft.OutTextXY(240, 20, "NEXT");
tft.OutTextXY( 20, 75, "SCORE");
tft.OutTextXY( 25, 130, "TOP");
FlNew = true;
ViewStacan();
GetNext();
delay(100);
tft.SetColor(BLACK);
tft.DrawLine(DISP_LEFT + 1, DISP_TOP + 0, DISP_LEFT + 1, DISP_BOT - 1);
tft.DrawLine(DISP_LEFT + razmer*MaxCol+5-MaxCol,DISP_TOP + 0,DISP_LEFT + razmer*MaxCol+5-MaxCol, DISP_BOT - 1);
tft.DrawLine(DISP_LEFT + 1, DISP_BOT - 1, DISP_LEFT + 1+razmer*MaxCol+5-MaxCol-1, DISP_BOT - 1);
// Key
tft.SetColor(BRIGHTBLUE);
tft.DrawCirc( 32,228, 8); // ROTATE
tft.DrawLine( 88,220, 96,236); tft.DrawLine( 88,220,104,220); tft.DrawLine( 96,236,104,220); // DROP
tft.DrawRect(152,220,157,236); tft.DrawRect(163,220,168,236); // PAUSE
tft.DrawLine(232,220,232,236); tft.DrawLine(232,220,216,228); tft.DrawLine(232,236,216,228); // LEFT
tft.DrawLine(280,220,280,236); tft.DrawLine(280,220,296,228); tft.DrawLine(280,236,296,228); // RIGHT
}
void loop(void)
{
if (Demo) ProcDemo();
else {
if (Arbeiten) {
mydelay(tempspeed);
figmove(0,1);
} else if (mypush()==KEY_SWAP/*ShortPush*/) NewGame();
}
}
uint8_t mypush(void)
{
unsigned long tpr = millis();
uint8_t res = KEY_EMPTY;//NotPush;
uint8_t button = 0;
static uint8_t button_old;
static uint8_t cnt = 0;
button = tft.scanButtons();
if (button) {
cnt = 5;
Serial.print("Scan Button: ");
Serial.print(button, HEX);
Serial.println();
if (button != button_old) {
if (button & 0x01) res = KEY_SWAP;
if (button & 0x02) res = KEY_FALL;
if (button & 0x04) {};
if (button & 0x08) res = KEY_LEFT;
if (button & 0x10) res = KEY_RIGHT;
button_old = button;
}
}
if (!cnt) {
button_old = button;
} else {
cnt--;
}
return(res);
}
void ViewQuad(uint8_t i,uint8_t j,uint8_t mycolor)
{
if (j<3) return;
uint16_t wy = DISP_TOP + SmeY + (j-3)*razmer - j;
uint16_t wx = DISP_LEFT + SmeX + i*razmer - i;
if (mycolor!=0) {
tft.SetColor(BLACK);
tft.DrawRect(wx, wy, wx+razmer-1, wy+razmer-1);
tft.SetColor(MasCol[mycolor]);
tft.DrawFillRect(wx+1, wy+1, wx+1+razmer-3, wy+1+razmer-3);
} else {
tft.SetColor(WHITE);
tft.DrawFillRect(wx+1, wy+0, wx+1+razmer-3, wy+1+razmer-3);
}
}
void ViewStacan(void)
{
char myStr2[5];
uint8_t h = tft.GetTextHeight(&FreeMonoBoldOblique12pt7b);
tft.SetFont(&FreeMonoBoldOblique12pt7b);
if (OldScore!=Score || FlNew) {
sprintf(myStr2,"%05d",Score);
int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
tft.SetColor(WHITE);
tft.DrawFillRect(20,100,20+w+5,100+h);
tft.SetColor(GREEN);
tft.OutTextXY(20,100,myStr2);
OldScore=Score;
}
if (OldRecord!=Record || FlNew) {
sprintf(myStr2,"%05d",Record );
int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
tft.SetColor(WHITE);
tft.DrawFillRect(20,155,20+w+5,155+h);
tft.SetColor(GREEN);
tft.OutTextXY(20,155,myStr2);
OldRecord=Record;
}
if (OldLevel!=Level || FlNew) {
sprintf(myStr2,"%01d",Level );
int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
tft.SetColor(WHITE);
tft.DrawFillRect(25,45,25+w+5,45+h);
tft.SetColor(GREEN);
tft.OutTextXY(25,45,myStr2);
OldLevel=Level;
}
FlNew=false;
for (byte j=3;j<MaxRow;j++)
for (byte i=0;i<MaxCol;i++)
if (MasSt[i][j]!=MasOld[i][j]) ViewQuad(i,j,MasSt[i][j]);
for (byte j=3;j<MaxRow;j++)
for (byte i=0;i<MaxCol;i++)
MasOld[i][j]=MasSt[i][j];
}
void ClearMas(byte MasStx[MaxCol][MaxRow])
{
for (byte j=0;j<MaxRow;j++)
for (byte i=0;i<MaxCol;i++)
(MasStx[i][j]=0);
}
void Sosed (int i,int j,int dx,int dy, byte mode)
{
int nx=i+dx;
int ny=j+dy;
if (nx>=0 && ny>=0 && nx<MaxCol && ny<MaxRow && MasSt[nx][ny]==MasSt[i][j]) {
if (mode==1) MasTmp[i][j]++;
else
if (mode==2 && (MasTmp[nx][ny]>1 || MasTmp[i][j]>2 )) {
MasTmp[nx][ny]=3;
MasTmp[i][j]=3;
} else
if (mode==3 && MasTmp[nx][ny]==3) {
if (MasTmp[i][j]!=3) {
MasTmp[i][j]=3;
fl=true;
}
}
}
}
void Sos(int i,int j, byte mode)
{
for (byte k=0;k<4;k++) Sosed(i,j,mmm[k][0],mmm[k][1],mode);
}
bool FindFull(void)
{
byte i,j,k; bool res;
res = false;
for (byte k=2;k<8;k++) {
ClearMas(MasTmp);
for (j=3;j<MaxRow;j++)
for (i=0;i<MaxCol;i++)
if (MasSt[i][j]==k) Sos(i,j,1);
for (j=3;j<MaxRow;j++)
for (i=0;i<MaxCol;i++)
if (MasTmp[i][j]>1) Sos(i,j,2);
do {
fl=false;
for (j=3;j<MaxRow;j++)
for (i=0;i<MaxCol;i++)
if (MasTmp[i][j]>0) Sos(i,j,3);
} while (fl);
for (j=3;j<MaxRow;j++)
for (i=0;i<MaxCol;i++)
if (MasTmp[i][j]==3) {
MasSt[i][j]=1;
TScore++;
}
}
if (TScore>0) {
ViewStacan();
FlZ=true;
mydelay(500);
}
for (j=0;j<MaxRow;j++)
for (i=0;i<MaxCol;i++) {
while (MasSt[i][MaxRow-1-j]==1) {
for (k=0;k<MaxRow-2-j;k++) MasSt[i][MaxRow-1-k-j]= MasSt[i][MaxRow-2-k-j];
res=true;
}
}
return(res);
}
void GetNext(void)
{
byte dx=255;
byte dy=60;
x=3;
y=0;
for (byte i=0;i<3;i++) {
//fig[i]=fignext[i];
if (!Demo) MasSt[x][i]=fignext[i];
fignext[i]=random(NumCol)+2;
tft.SetColor(BLACK);
tft.DrawRect(dx,dy+(razmer-1)*i,dx+razmer, dy+(razmer-1)*(i+1)+1);
tft.SetColor(MasCol[fignext[i]]);
tft.DrawFillRect(dx+1,dy+(razmer-1)*i+1, dx+razmer-1, dy+(razmer-1)*(i+1));
}
if (!Demo) {
Counter++;
if (Counter==PeriodLevel) {
Counter=0;
Level++;
if (Level>MaxLevel) Level=MaxLevel;
}
tempspeed=MasSpeed[Level-1];
}
}
void MyScore(void)
{
TScore=0;
while(FindFull()) {
if (TScore>7) Score=Score+TScore+(TScore-8)*2;
else Score=Score+TScore;
ViewStacan();
FlZ=true;
mydelay(1000);
}
FlZ=false;
}
void ProcDemo(void)
{
Score=0;
GetNext();
for (byte j=3;j<MaxRow;j++)
for (byte i=0;i<MaxCol;i++)
MasSt[i][j]=random(6)+2;
ViewStacan();
mydelay(1000);
if (!Demo) return;
MyScore();
if (Record<Score) Record=Score;
}
void mydelay(int md)
{
unsigned long starttime=millis();
while (millis()-starttime < md) {
VAL=0;
Mp=mypush();
if (Mp==KEY_RIGHT) {
VAL=1;
} else
if (Mp==KEY_LEFT) {
VAL=-1;
}
if ((VAL!=0 || Mp!=KEY_EMPTY/*NotPush*/) && Demo) {
Demo=false;
NewGame();
}
if (VAL!=0 && figmove(VAL, 0) && !FlZ) {
for (byte i=0;i<3;i++) {
MasSt[x+VAL][y+i]=MasSt[x][y+i];
MasSt[x][y+i]=0;
}
ViewStacan();
if (MasSt[x][y+3]==0) {
tft.SetColor(WHITE);
tft.DrawLine(DISP_LEFT+SmeX+x*(razmer-1)+1, DISP_TOP+SmeY+y*(razmer-1)-3, DISP_LEFT+SmeX+(x+1)*(razmer-1)-1, DISP_TOP+SmeY+y*(razmer-1)-3);
}
x=x+VAL;
}
if (Mp==KEY_SWAP/*ShortPush*/ && !FlZ) {
byte aa=MasSt[x][y];
MasSt[x][y]=MasSt[x][y+2];
MasSt[x][y+2]=MasSt[x][y+1];
MasSt[x][y+1]=aa;
ViewStacan();
}
if (Mp==KEY_FALL && !FlZ) tempspeed=50;
}
}
void NewGame(void)
{
for (byte i=0; i<(MaxCol+1); i++) {
tft.SetColor(BLACK);
tft.DrawLine(DISP_LEFT+3+(razmer-1)*i, DISP_TOP, DISP_LEFT+3+(razmer-1)*i, DISP_BOT-3);
}
for (byte j=3;j<MaxRow;j++)
for (byte i=0;i<MaxCol;i++)
MasOld[i][j]=255;
Score=0;
FlNew=true;
OldScore=Score;
ClearMas(MasSt);
Arbeiten=true;
GetNext();
Counter=0;
Level=1;
tempspeed=MasSpeed[0];
Record=myrecord;
ViewStacan();
}
void gameover(void)
{
Arbeiten=false;
tft.SetColor(BLACK);
tft.DrawRect(112,90,202,145);
tft.SetColor(RED);
tft.DrawFillRect(113,91,201,144);
tft.SetFont(&FreeSerif9pt7b);
tft.SetColor(WHITE);
tft.OutTextXY(132, 100, "GAME");
tft.OutTextXY(135, 120, "OVER");
}
bool figmove(int dx, int dy)
{
bool fff=false;
if (x+dx<0 || x+dx>MaxCol-1) return(false);
if (dx!=0) if (MasSt[x+dx][y+dy+2]==0) return(true); else return(false);
if (dy>0) {
if (y+dy+2>MaxRow-1 || MasSt[x+dx][y+dy+2]>0) {
if (y<3) gameover();
else fff=true;
} else {
for (byte i=0;i<3;i++) MasSt[x][y+2-i+dy]=MasSt[x][y+2-i];
MasSt[x][y]=0;
y=y+dy;
}
if (fff) {
MyScore();
GetNext();
}
ViewStacan();
}
return(true);
}
DemonstrationBelow is added a video demonstrating the work of sketches.
Thanks for attention. To be continued.
Next articles:
1) Unique Arduino TFT Shield - OV7670 Cam,
2) Arduino Bluetooth Camera (ABC),
3) TFT shield for Arduino Nano - Start,
4) Photos and RGB video on TFT SPI display.
Update 01.04.2021:
Hello again! There is an updated library for a series of screens, which currently consists of two shields and two breakout boards. The sketch is compiled depending on the selected version (from 1 to 4) and the type of microcontroller (MegaAVR or ESP-32). Added photos, examples. More information can be found in the https://github.com/Ekaburg/EkaTFT.
Comments