#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define JOYSTICK_X A0
#define JOYSTICK_Y A1
#define JOYSTICK_BUTTON 2
// 游戏区域大小
#define GAME_WIDTH 10
#define GAME_HEIGHT 20
// 方块大小
#define BLOCK_SIZE 3
// 方块形状
const byte shapes[7][4][4] = {
// I 形
{
{1, 1, 1, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// J 形
{
{1, 0, 0, 0},
{1, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// L 形
{
{0, 0, 1, 0},
{1, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// O 形
{
{1, 1, 0, 0},
{1, 1, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// S 形
{
{0, 1, 1, 0},
{1, 1, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// T 形
{
{0, 1, 0, 0},
{1, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
},
// Z 形
{
{1, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}
};
// 游戏区域
byte gameArea[GAME_HEIGHT][GAME_WIDTH] = {0};
// 当前方块
byte currentShape[4][4];
int currentX, currentY;
// 随机选择方块形状
int currentShapeIndex;
// 初始化游戏
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.display();
pinMode(JOYSTICK_BUTTON, INPUT_PULLUP);
newPiece();
}
// 生成新方块
void newPiece() {
currentShapeIndex = random(7);
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
currentShape[y][x] = shapes[currentShapeIndex][y][x];
}
}
currentX = GAME_WIDTH / 2 - 2;
currentY = 0;
}
// 绘制方块
void drawBlock(int x, int y) {
display.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, SSD1306_WHITE);
}
// 绘制游戏区域
void drawGameArea() {
display.clearDisplay();
for (int y = 0; y < GAME_HEIGHT; y++) {
for (int x = 0; x < GAME_WIDTH; x++) {
if (gameArea[y][x]) {
drawBlock(x, y);
}
}
}
// 绘制当前方块
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (currentShape[y][x]) {
drawBlock(currentX + x, currentY + y);
}
}
}
display.display();
}
// 检查方块是否可以移动到指定位置
bool canMove(int newX, int newY) {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (currentShape[y][x]) {
int targetX = newX + x;
int targetY = newY + y;
if (targetX < 0 || targetX >= GAME_WIDTH || targetY >= GAME_HEIGHT || (targetY >= 0 && gameArea[targetY][targetX])) {
return false;
}
}
}
}
return true;
}
// 旋转方块
void rotatePiece() {
byte newShape[4][4];
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
newShape[x][3 - y] = currentShape[y][x];
}
}
// 保存当前形状
byte tempShape[4][4];
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
tempShape[y][x] = currentShape[y][x];
}
}
// 尝试旋转
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
currentShape[y][x] = newShape[y][x];
}
}
if (!canMove(currentX, currentY)) {
// 旋转失败,恢复原来的形状
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
currentShape[y][x] = tempShape[y][x];
}
}
}
}
// 合并方块到游戏区域
void mergePiece() {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (currentShape[y][x]) {
gameArea[currentY + y][currentX + x] = 1;
}
}
}
}
// 检查并清除满行
void checkLines() {
for (int y = GAME_HEIGHT - 1; y >= 0; y--) {
bool isFull = true;
for (int x = 0; x < GAME_WIDTH; x++) {
if (!gameArea[y][x]) {
isFull = false;
break;
}
}
if (isFull) {
// 清除满行
for (int yy = y; yy > 0; yy--) {
for (int x = 0; x < GAME_WIDTH; x++) {
gameArea[yy][x] = gameArea[yy - 1][x];
}
}
y++; // 再次检查当前行
}
}
}
// 主循环
void loop() {
// 读取摇杆输入
int xValue = analogRead(JOYSTICK_X);
int yValue = analogRead(JOYSTICK_Y);
bool buttonPressed = digitalRead(JOYSTICK_BUTTON) == LOW;
if (xValue < 100 && canMove(currentX - 1, currentY)) {
currentX--;
} else if (xValue > 900 && canMove(currentX + 1, currentY)) {
currentX++;
}
if (yValue < 100) {
if (canMove(currentX, currentY + 1)) {
currentY++;
}
}
if (buttonPressed) {
rotatePiece();
}
// 自动下落
static unsigned long lastFallTime = 0;
if (millis() - lastFallTime > 500) {
if (canMove(currentX, currentY + 1)) {
currentY++;
} else {
mergePiece();
checkLines();
newPiece();
if (!canMove(currentX, currentY)) {
// 游戏结束
while (true);
}
}
lastFallTime = millis();
}
drawGameArea();
delay(10);
}
写的代码,OLED一直亮不了,哪里有问题,悬关