#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED显示宽度,单位为像素
#define SCREEN_HEIGHT 64 // OLED显示高度,单位为像素
// 创建SSD1306对象,使用SPI接口
#define OLED_RESET 9 // RES引脚连接到D9
#define OLED_DC 8 // DC引脚连接到D8
#define OLED_CS 10 // CS引脚连接到D10(如果有的话)
// 使用 SPI 接口创建 Adafruit_SSD1306 对象
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RESET, OLED_CS);
// 贪吃蛇参数
int snakeLength = 3;
int snakeX[100] = {20, 19, 18}; // 蛇身坐标数组,初始位置为(20,19),(19,19),(18,19)
int snakeY[100] = {10, 10, 10};
int foodX = 5 * 4; // 食物随机位置,确保与4对齐
int foodY = 5 * 4;
char direction = 'R'; // 初始方向为右
// 摇杆引脚定义
const int joyXPin = A0; // X轴引脚连接到A0
const int joyYPin = A1; // Y轴引脚连接到A1
const int buttonPin = 2; // 按钮引脚连接到D2
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // 设置按钮引脚为输入并启用内部上拉电阻
display.begin(SSD1306_SWITCHCAPVCC); // 初始化显示屏,不再需要I2C地址
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
randomSeed(analogRead(A3)); // 用于生成随机数种子
drawFood(); // 绘制食物初始位置
}
void loop() {
readJoystick(); // 检测摇杆状态
if (checkCollision()) {
gameOver();
return;
}
moveSnake();
if (checkCollision()) {
gameOver();
return;
}
display.clearDisplay();
drawBorder(); // 绘制边框
drawSnake(); // 绘制蛇身
if ((snakeX[0]-foodX > -4 && snakeX[0]-foodX < 4) && (snakeY[0] - foodY > -4 )&&(snakeY[0] - foodY > 4 )) {
growSnake(); // 吃到食物时增长蛇身并重新生成食物
drawFood();
} else {
drawFood(); // 始终绘制食物,即使没有被吃掉
}
display.display();
delay(500); // 控制游戏速度,可以根据需要调整延迟时间
}
void readJoystick() {
int xValue = analogRead(joyXPin);
int yValue = analogRead(joyYPin);
if (xValue < 400) {
direction = 'R';
} else if (xValue > 600) {
direction = 'L';
} else if (yValue < 400) {
direction = 'U';
} else if (yValue > 600) {
direction = 'D';
}
}
void moveSnake() {
for (int i = snakeLength; i > 0; i--) {
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
switch(direction) {
case 'U': snakeY[0] -= 4; break; // 蛇头移动距离改为4像素
case 'D': snakeY[0] += 4; break;
case 'L': snakeX[0] -= 4; break;
case 'R': snakeX[0] += 4; break;
}
// 边界检查:如果蛇头超出屏幕边界,则游戏结束。
if (snakeX[0] < 0 || snakeX[0] >= SCREEN_WIDTH || snakeY[0] < 0 || snakeY[0] >= SCREEN_HEIGHT) {
gameOver();
}
}
void drawSnake() {
for(int i=0; i<snakeLength; i++) {
display.fillRect(snakeX[i], snakeY[i], 4, 4, WHITE); // 绘制蛇身,每节占用4x4像素区域。
}
}
void drawFood() {
display.fillRect(foodX, foodY, 4, 4, WHITE); // 绘制食物,每个食物占用4x4像素区域。
}
bool checkCollision() {
for(int i=1; i<snakeLength; i++) {
if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) return true;
}
return false;
}
void growSnake() {
if(snakeLength < sizeof(snakeX)/sizeof(snakeX[0])) {
snakeLength++;
foodX = random(0,(SCREEN_WIDTH/4))*4;
foodY = random(0,(SCREEN_HEIGHT/4))*4;
}
}
void gameOver() {
display.clearDisplay();
display.setCursor(30,30);
display.print('Game Over!');
display.display();
while(true); // 游戏结束后停止程序运行,可以重启或重置。
}
// 新增函数:绘制边框
void drawBorder() {
for(int x=0; x<SCREEN_WIDTH; x++) {
display.drawPixel(x, 0, WHITE); // 上边框
display.drawPixel(x, SCREEN_HEIGHT-1, WHITE); // 下边框
}
for(int y=1; y<SCREEN_HEIGHT-1; y++) {
display.drawPixel(0,y , WHITE); // 左边框
display.drawPixel(SCREEN_WIDTH-1,y , WHITE); //右边框
}
}
ardunio-snake
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- Spring Boot 默认使用 jackson进行请求参数转换的。针对请求参数为snake_case格式,例如{...
- 图形移动方法优化 前面我们图形移动是通过move_level或move_direct方法得到最新的4个坐标数据更新...
- Statistical Shape Models (SSMs) The shape of an object is...