#define TFT_CS 10 // Chip select line for TFT display
#define TFT_RST 8 // Reset line for TFT (or see below...)
#define TFT_DC 9 // Data/command line for TFT
#define SD_CS 6 // Chip select line for SD card
...
bmpDraw("333.bmp", 0, 0);
// © Klop 2018
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <TimerOne.h>
#include <Encod_er.h>
#include <EEPROM2.h>
// пин LED+ дисплея подключаем к +5V через резистор 150 ом
#define TFT_CS 10 // пин 10 подключаем к CS дисплея
#define TFT_RST 8 // пин 8 подключаем к RST дисплея
#define TFT_DC 9 // пин 9 подключаем к DS дисплея
#define pin_DT 4 // пин 4 подключаем к DT энкодера
#define pin_CLK 2 // пин 2 подключаем к CLK энкодера
#define pin_SW 3 // пин 3 подключаем к SW энкодера
#define pin_Speaker 5 // пин 5 подключаем к + пищалки ( - пищалки на землю)
#define NotPush 0
#define ShortPush 1
#define LongPush 2
#define DurationOfLongPush 350 // длительность длинного нажатия
// Color definitions
#define BLACK 0x0000
#define RED 0x001F
#define BLUE 0xF800
#define GREEN 0x07E0
#define YELLOW 0x07FF
#define MAGENTA 0xF81F
#define CYAN 0xFFE0
#define WHITE 0xFFFF
#define MaxX 8
#define MaxY 17
#define SmeX 3
#define SmeY 5
#define LL 97
#define interval 250
#define razmer 12 // размер квадратика
#define NumCol 6 // количество цветов квадратиков
#define MaxLevel 8 // макс. кол-во уровней
#define NextLevel 80 // через сколько столбиков повышать уровень
byte MasSt[MaxX][MaxY], MasTmp[MaxX][MaxY], MasOld[MaxX][MaxY], fignext[3];
byte Level=1, dx, dy, OldLevel, tr, flfirst=1; // flfirst=? сменить для обнуления рекорда
uint16_t MasCol[]={WHITE, BLACK, RED, BLUE, GREEN, YELLOW, MAGENTA, CYAN};
unsigned long TimeOfPush, Counter,Score=0, TScore=0, Record=0, OldRecord, OldScore, myrecord;
word 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}};
word MasSpeed[MaxLevel]={500,450,400,350,300,250,200,100}; // задержки уровней
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
Encod_er encoder(pin_CLK, pin_DT, pin_SW);
//==================================================
void setup()
{
randomSeed(analogRead(0));
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
tft.fillScreen(WHITE);
tft.setCursor(LL, 61);
tft.setTextColor(BLACK);
tft.setTextWrap(true);
tft.setTextSize(1);
tft.print("LEVEL");
tft.setCursor(100, SmeY);
tft.print("NEXT");
tft.setCursor(LL,100);
tft.print("SCORE");
tft.setCursor(LL+5,135);
tft.print("TOP");
FlNew=true;
ViewStacan();
GetNext();
Timer1.initialize(interval); // инициализация таймера 1, период interval мкс
Timer1.attachInterrupt(timerInterrupt, interval); // задаем обработчик прерываний
pinMode (pin_DT,INPUT);
pinMode (pin_CLK,INPUT);
pinMode (pin_SW,INPUT);
digitalWrite(pin_SW, HIGH); // подтягиваем к 5V
delay(100);
encoder.timeLeft= 0;
encoder.timeRight= 0;
tft.drawFastVLine(1,2,157,BLACK);
tft.drawFastVLine(razmer*MaxX+5-MaxX,2,157,BLACK);
tft.drawFastHLine(1,158,razmer*MaxX+5-MaxX,BLACK);
EEPROM_read(0, tr);
if (tr==flfirst) EEPROM_read(1, myrecord);
else { myrecord=0;
EEPROM_write(1, myrecord);
EEPROM_write(0, flfirst);
}
}
//==================================================
// обработчик прерывания
void timerInterrupt()
{ encoder.scanState();
}
//==================================================
byte mypush() // возвращает длинное-2, короткое-1 или осутствие нажатия-0
{ unsigned long tpr=millis();
byte res=NotPush;
if (!digitalRead(pin_SW))
{ if (TimeOfPush==0) TimeOfPush=tpr; else
if (tpr-TimeOfPush>DurationOfLongPush && !myfl)
{ TimeOfPush=0;
myfl=true;
return(LongPush);
}
} else
{ if (TimeOfPush>0 && !myfl) res=ShortPush;
TimeOfPush=0;
myfl=false;
}
return(res);
}
//==================================================
void ViewQuad(byte i,byte j,byte mycolor) // отрисовка 1-го квадрата
{if (j<3) return;
byte wy=SmeY+(j-3)*razmer-j;
byte wx=SmeX+i*razmer-i;
if (mycolor!=0)
{ tft.drawRect(wx,wy,razmer, razmer, BLACK);
tft.fillRect(wx+1, wy+1, razmer-2 , razmer-2, MasCol[mycolor]);
} else
tft.fillRect(wx+1, wy-1, razmer-2 , razmer, WHITE);
}
//==================================================
void ViewStacan()
{ char myStr2[5];
tft.setTextColor(RED);
tft.setTextSize(1);
if (OldScore!=Score || FlNew) { tft.fillRect(LL,113,30,8,WHITE);
tft.setCursor(LL, 113);
sprintf(myStr2,"%05d",Score );
tft.print(myStr2);
OldScore=Score;
}
if (OldRecord!=Record || FlNew) { tft.setCursor(LL, 148);
sprintf(myStr2,"%05d",Record );
tft.fillRect(LL,148,30,8,WHITE);
tft.print(myStr2);
OldRecord=Record;
}
if (OldLevel!=Level || FlNew) { tft.fillRect(107,73,30,20,WHITE);
tft.setCursor(107, 73);
tft.setTextSize(2);
tft.print(Level);
OldLevel=Level;
}
FlNew=false;
for (byte j=3;j<MaxY;j++)
for (byte i=0;i<MaxX;i++)
if (MasSt[i][j]!=MasOld[i][j]) ViewQuad(i,j,MasSt[i][j]);
tft.drawFastHLine(3,156,razmer*MaxX-MaxX,BLACK);
for (byte j=3;j<MaxY;j++)
for (byte i=0;i<MaxX;i++)
MasOld[i][j]=MasSt[i][j];
}
//==================================================
void ClearMas(byte MasStx[MaxX][MaxY])
{
for (byte j=0;j<MaxY;j++)
for (byte i=0;i<MaxX;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<MaxX && ny<MaxY && 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() // ищем одноцветные цепочки
{ byte i,j,k; bool res;
res=false;
for (byte k=2;k<8;k++) // по каждому цвету
{ ClearMas(MasTmp);
for (j=3;j<MaxY;j++)
for (i=0;i<MaxX;i++)
if (MasSt[i][j]==k) Sos(i,j,1);
for (j=3;j<MaxY;j++)
for (i=0;i<MaxX;i++)
if (MasTmp[i][j]>1) Sos(i,j,2);
do
{ fl=false;
for (j=3;j<MaxY;j++)
for (i=0;i<MaxX;i++)
if (MasTmp[i][j]>0) Sos(i,j,3);
} while (fl);
for (j=3;j<MaxY;j++)
for (i=0;i<MaxX;i++)
if (MasTmp[i][j]==3) { MasSt[i][j]=1;
TScore++;
}
}
if (TScore>0)
{ ViewStacan();
FlZ=true;
mydelay(500);
}
for (j=0;j<MaxY;j++)
for (i=0;i<MaxX;i++)
{ while (MasSt[i][MaxY-1-j]==1)
{ for (k=0;k<MaxY-2-j;k++) MasSt[i][MaxY-1-k-j]= MasSt[i][MaxY-2-k-j];
res=true;
}
}
return(res);
}
//==================================================
void GetNext()
{ byte dx=106; byte dy=16;
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.drawRect(dx,dy+razmer*i-i,razmer, razmer, BLACK);
tft.fillRect(dx+1,dy+razmer*i-i+1, razmer-2, razmer-2,MasCol[fignext[i]]);
}
if (!Demo){ Counter++;
if (Counter==NextLevel) { Counter=0;
Level++;
if (Level>MaxLevel) Level=MaxLevel;
}
tempspeed=MasSpeed[Level-1];
}
}
//==================================================
void MyScore()
{
TScore=0;
while(FindFull())
{if (TScore>7) Score=Score+TScore+(TScore-8)*2;
else Score=Score+TScore;
if (!Demo) analogWrite(pin_Speaker,5); // издаем звук
ViewStacan();
analogWrite(pin_Speaker,0);
FlZ=true;
mydelay(1000);
}
FlZ=false;
}
//==================================================
void ProcDemo()
{ Score=0;
GetNext();
for (byte j=3;j<MaxY;j++)
for (byte i=0;i<MaxX;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 (encoder.timeRight!=0) // обрабатываем повороты энкодера
{ VAL=1;
encoder.timeRight=0;
} else
if (encoder.timeLeft!=0)
{ VAL=-1;
encoder.timeLeft=0;
}
if (!digitalRead(pin_SW)) VAL=0;
if ((VAL!=0 || Mp!=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.drawFastHLine(SmeX+x*razmer-x+1,SmeY+y*razmer-y-3,razmer-2,WHITE);
x=x+VAL;
}
if (Mp==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==LongPush && !FlZ) tempspeed=50; // падение
}
}
//================================================
void NewGame()
{
for (byte i=0;i<8;i++)
tft.drawFastVLine(3+razmer*i-i,2,155,BLACK); // направляющие
for (byte j=3;j<MaxY;j++) // заполним буфер сравнения значением, которого нет
for (byte i=0;i<MaxX;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();
if (tr==flfirst) EEPROM_read(1, myrecord);
else { myrecord=0;
EEPROM_write(1, myrecord);
EEPROM_write(0, flfirst);
}
}
//================================================
void gameover()
{
Arbeiten=false;
tft.drawRect(7,40,81,50, BLACK);
tft.fillRect(8,41,79,48,WHITE);
tft.setCursor(25, 47);
tft.setTextSize(2);
tft.setTextColor(RED);
tft.print("GAME");
tft.setCursor(25, 67);
tft.print("OVER");
if (Score>myrecord)
{ myrecord=Score;
EEPROM_write(1, myrecord);
}
}
//================================================
bool figmove(int dx, int dy)
{ bool fff=false;
if (x+dx<0 || x+dx>MaxX-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>MaxY-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);
}
//================================================
void loop()
{
if (Demo) ProcDemo();
else
{ if (Arbeiten)
{ mydelay(tempspeed);
figmove(0,1);
} else
if (mypush()==ShortPush) NewGame();
}
}
+51 |
1942
65
|
+28 |
2195
40
|
Ну то что цветные классно, но то что не читаются… ну углы обзора ни о чем. И контрастности. Вот помогал тут товарищу… так после того как вспомнил по Oled… Вышло так что по читаемости 1.3'' Oled оказался в разы бодрее 2.4'' TFT. Есть еще кста 2.8'' экранчики.
как это сделал один чел с esp8266
Цветные для меги это, на мой взгляд, перебор.
Цветные дисплеи на али продаются еще и с 8бит и 16бит шиной. Можно взять 8бит и STM32F103. А кому нужна максимальная плавность берут 16 бит и STM32 с FSMC.
Еще, кстати, на скорость влияет адафрутовская библиотека — если заливки, вертикальные и горизонтальные линии там оптимизированы, то шрифты рисуются попиксельно с установкой координат каждый раз (а это 12 байт и 4 смены A0). Это дает возможность рисовать текст поверх фона, но если нужно весь экран заполнить текстом, то блочное рисование раза в 3 быстрее.
на профильных форумах совсем ничего не нашлось?
Новые ревизии кстати постоянно выходят, снижают потребление в основном.
Недавно сравнительно вышел ATtiny44, на борту множество инструментов для снижения потребления…
p.s.
ZX у меня не было, но глянул в Вики. Проц Z80 работал на частоте 3,5 МГц. Супротив 16 у Atmega 328? Так, что… А сравнивать тогдашние цены на Spectrum и нынешние на ардуину будем? )
Персона́льный компью́тер, ПК (англ. personal computer, PC), ПЭВМ (персональная электронно-вычислительная машина) — настольная микро-ЭВМ, имеющая эксплуатационные характеристики бытового прибора и универсальные функциональные возможности.
Микроконтро́ллер(англ. Micro Controller Unit, MCU) — микросхема, предназначенная для управления электронными устройствами
Но в жизни грани между ними уже весьма эфемеры. Так, что я с Вами соглашусь.
Просто надоело уже перебирать эти дисплеи (( сколько не брал ни на одном не работает либо без ШИМ либо нет вообще хотя заявлен.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.