求助
  • 板块灌水区
  • 楼主_zhaosihan_qwq_
  • 当前回复2
  • 已保存回复2
  • 发布时间2025/2/8 17:27
  • 上次更新2025/2/8 18:05:50
查看原帖
求助
1287887
_zhaosihan_qwq_楼主2025/2/8 17:27
#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一直亮不了,哪里有问题,悬关

2025/2/8 17:27
加载中...