帮我写一个esp8266 贪吃蛇使用OLED显示的代码 arduino
时间: 2023-08-20 16:30:18 浏览: 65
好的,以下是一个简单的 ESP8266 贪吃蛇游戏代码,使用 OLED 显示屏显示:
```arduino
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED屏幕尺寸
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// OLED屏幕I2C地址
#define OLED_ADDR 0x3C
// OLED屏幕实例
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// 贪吃蛇游戏区域尺寸
#define BOARD_WIDTH 64
#define BOARD_HEIGHT 32
// 贪吃蛇方块尺寸
#define BLOCK_SIZE 4
// 贪吃蛇方向
enum Direction {
LEFT,
RIGHT,
UP,
DOWN
};
// 贪吃蛇节点
struct Node {
int x;
int y;
Node *next;
};
// 贪吃蛇实例
class Snake {
private:
Node *head;
Node *tail;
int length;
Direction direction;
int food_x;
int food_y;
public:
// 初始化贪吃蛇
void init() {
// 初始化贪吃蛇头
head = new Node;
head->x = BOARD_WIDTH / 2;
head->y = BOARD_HEIGHT / 2;
head->next = NULL;
// 初始化贪吃蛇尾
tail = head;
// 初始化贪吃蛇长度
length = 1;
// 初始化贪吃蛇方向
direction = RIGHT;
// 初始化食物位置
generate_food();
}
// 生成食物位置
void generate_food() {
food_x = random(0, BOARD_WIDTH / BLOCK_SIZE) * BLOCK_SIZE;
food_y = random(0, BOARD_HEIGHT / BLOCK_SIZE) * BLOCK_SIZE;
}
// 移动贪吃蛇
void move() {
// 添加新头节点
Node *new_head = new Node;
switch (direction) {
case LEFT:
new_head->x = head->x - BLOCK_SIZE;
new_head->y = head->y;
break;
case RIGHT:
new_head->x = head->x + BLOCK_SIZE;
new_head->y = head->y;
break;
case UP:
new_head->x = head->x;
new_head->y = head->y - BLOCK_SIZE;
break;
case DOWN:
new_head->x = head->x;
new_head->y = head->y + BLOCK_SIZE;
break;
}
new_head->next = head;
head = new_head;
// 如果吃到了食物,增加长度并重新生成食物
if (head->x == food_x && head->y == food_y) {
length++;
generate_food();
} else {
// 否则移动尾节点
Node *current = head;
for (int i = 0; i < length - 1; i++) {
current = current->next;
}
tail = current;
tail->next = NULL;
}
}
// 改变贪吃蛇方向
void change_direction(Direction new_direction) {
if (new_direction != direction) {
switch (new_direction) {
case LEFT:
if (direction != RIGHT) {
direction = new_direction;
}
break;
case RIGHT:
if (direction != LEFT) {
direction = new_direction;
}
break;
case UP:
if (direction != DOWN) {
direction = new_direction;
}
break;
case DOWN:
if (direction != UP) {
direction = new_direction;
}
break;
}
}
}
// 绘制贪吃蛇和食物
void draw() {
// 清空屏幕
display.clearDisplay();
// 绘制贪吃蛇
Node *current = head;
while (current != NULL) {
display.fillRect(current->x, current->y, BLOCK_SIZE, BLOCK_SIZE, WHITE);
current = current->next;
}
// 绘制食物
display.fillRect(food_x, food_y, BLOCK_SIZE, BLOCK_SIZE, WHITE);
// 更新屏幕
display.display();
}
// 判断是否游戏结束
bool is_game_over() {
// 判断是否碰到边界
if (head->x < 0 || head->x >= BOARD_WIDTH || head->y < 0 || head->y >= BOARD_HEIGHT) {
return true;
}
// 判断是否碰到自己
Node *current = head->next;
while (current != NULL) {
if (head->x == current->x && head->y == current->y) {
return true;
}
current = current->next;
}
return false;
}
};
// 贪吃蛇实例
Snake snake;
// 初始化函数
void setup() {
// 初始化串口
Serial.begin(9600);
// 初始化随机数种子
randomSeed(analogRead(0));
// 初始化屏幕
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
display.display();
// 初始化贪吃蛇
snake.init();
}
// 主循环
void loop() {
// 处理输入
if (Serial.available() > 0) {
char c = Serial.read();
switch (c) {
case 'a':
snake.change_direction(LEFT);
break;
case 'd':
snake.change_direction(RIGHT);
break;
case 'w':
snake.change_direction(UP);
break;
case 's':
snake.change_direction(DOWN);
break;
}
}
// 移动贪吃蛇
snake.move();
// 绘制贪吃蛇和食物
snake.draw();
// 判断是否游戏结束
if (snake.is_game_over()) {
Serial.println("Game over!");
while (true);
}
// 等待一段时间
delay(100);
}
```
以上代码中使用了 `Adafruit_SSD1306` 库来控制 OLED 屏幕显示,使用 `Serial` 来接收用户输入,使用 `random()` 来生成随机数种子。在 `setup()` 函数中初始化了屏幕和贪吃蛇实例,在 `loop()` 函数中处理输入、移动贪吃蛇、绘制贪吃蛇和食物以及判断是否游戏结束。注意在游戏结束时需要用 `while (true)` 使程序陷入死循环,否则程序会继续运行下去。