#include <Adafruit_GFX.h> // 用于图形显示
#include <Adafruit_ILI9341.h> // ILI9341屏幕驱动库
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
int obstacleX;
int obstacleY;
int dinoX;
int dinoY;
int dinoHeight = 20;
int jumpState = 0;
int times = 0;
int speed;
int obState = 0;
const int buttonPin = 2;
int buttonState = 0;
int score=0;
void setup() {
Serial.begin(9600);
// 初始化屏幕
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_WHITE);
pinMode(buttonPin, INPUT_PULLUP);
dinoX = 50;
dinoY = tft.height() - 60;
obstacleX = tft.width() - 20;
obstacleY = tft.height() - 100;
speed = random(6,12);
score = 0;
drawGround();
// drawDino(dinoX, dinoY);
drawDino1(dinoX, dinoY);
}
void loop() {
tft.setTextColor(ILI9341_BLACK, ILI9341_WHITE);
tft.setTextSize(3);
tft.setCursor(10,10);
tft.print(score);
boolean crash = false;
// 碰撞检测
if(dinoX +25 > obstacleX && dinoX < obstacleX+20 ) {
if(dinoY > obstacleY) {
// Serial.println("crash!");
crash = true;
}
}
if(!crash && dinoX > obstacleX+20 && dinoX-10 < obstacleX+20 ) {
if(dinoY-10 > obstacleY) {
// Serial.println("crash!");
crash = true;
}
}
if(crash) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(10);
tft.setCursor(30, 30);
tft.print("Game over");
while(1){}
}
// 读取按钮状态
buttonState = digitalRead(buttonPin);
cleanDino1(dinoX, dinoY);
cleanObstacle(obstacleX, obstacleY);
switch(jumpState) {
case 0: //静止,检测距离,距离过小就切换状态1,且纵坐标改变
if(buttonState == LOW) {
dinoY -= 9;
jumpState = 1;
}
break;
case 1:
dinoY -= 9;
times++;
if(times == 8) {
times = 0;
jumpState = 2;
}
break;
case 2:
dinoY += 9;
times ++;
if(times == 9) {
times = 0;
jumpState = 3;
}
break;
case 3:
times++;
if(times==3) {
times = 0;
jumpState = 0;
}
break;
}
drawDino1(dinoX, dinoY);
switch(obState) {
case 0: //没有障碍物,绘制
speed = random(6,12);
obstacleX = tft.width();
obState = 1;
break;
case 1: //存在障碍物,每次往左移动,检测边界
obstacleX -= speed;
if (obstacleX < -20) {
obstacleX = tft.width(); // 重置到右边
score++;
obState = 0;
}
break;
}
drawObstacle(obstacleX, obstacleY);
delay(70);
}
void drawGround() {
tft.fillRect(0, tft.height()-60, tft.width(), 20, ILI9341_BLACK);
}
// 绘制小恐龙
void drawDino(int X, int Y) {
int dinoWidth = 20;
tft.fillRect(X, Y, dinoWidth, dinoHeight, ILI9341_BLACK);
}
void drawDino1(int X, int Y) {
int dinoX = X;
int groundY = Y;
// 身体
tft.fillRect(dinoX, groundY - 30, 20, 30, ILI9341_BLACK);
// 头部
tft.fillRect(dinoX + 10, groundY - 40, 15, 15, ILI9341_BLACK);
// 眼睛
tft.fillCircle(dinoX + 20, groundY - 35, 2, ILI9341_WHITE);
// 尾巴
tft.fillTriangle(dinoX, groundY - 20, dinoX - 10, groundY - 10, dinoX, groundY - 10, ILI9341_BLACK);
// 腿
tft.fillRect(dinoX + 5, groundY - 5, 5, 5, ILI9341_BLACK); // 左腿
tft.fillRect(dinoX + 15, groundY - 5, 5, 5, ILI9341_BLACK); // 右腿
}
void cleanDino(int X, int Y) {
int dinoWidth = 20;
tft.fillRect(X, Y, dinoWidth, dinoHeight, ILI9341_WHITE);
}
void cleanDino1(int X, int Y) {
int dinoX = X;
int groundY = Y;
// 身体
tft.fillRect(dinoX, groundY - 30, 20, 30, ILI9341_WHITE);
// 头部
tft.fillRect(dinoX + 10, groundY - 40, 15, 15, ILI9341_WHITE);
// 眼睛
tft.fillCircle(dinoX + 20, groundY - 35, 2, ILI9341_WHITE);
// 尾巴
tft.fillTriangle(dinoX, groundY - 20, dinoX - 10, groundY - 10, dinoX, groundY - 10, ILI9341_WHITE);
// 腿
tft.fillRect(dinoX + 5, groundY - 5, 5, 5, ILI9341_WHITE); // 左腿
tft.fillRect(dinoX + 15, groundY - 5, 5, 5, ILI9341_WHITE); // 右腿
}
void drawObstacle(int X, int Y) {
int obstacleWidth = 20; // 障碍物宽度
int obstacleHeight = 40; // 障碍物高度
tft.fillRect(X, Y, obstacleWidth, obstacleHeight, ILI9341_RED);
}
void cleanObstacle(int X, int Y) {
int obstacleWidth = 20; // 障碍物宽度
int obstacleHeight = 40; // 障碍物高度
tft.fillRect(X, Y, obstacleWidth, obstacleHeight, ILI9341_WHITE);
}