Arduino 8×8 LED 矩阵贪吃蛇游戏机
项目简介
基于 Arduino UNO、MAX7219 驱动的 8×8 LED 点阵模块与模拟摇杆,复刻经典贪吃蛇游戏。蛇身随吃食增长、加速,撞墙或咬到自身游戏结束,按摇杆按键重启。代码基于 Sergey Royz 开源版本优化,增加平滑移动与游戏结束滚动字幕。
硬件清单
| 元件 | 数量 | 接线说明 |
|---|---|---|
| Arduino UNO | 1 | 主控 |
| MAX7219 8×8 LED 点阵模块 | 1 | VCC→5V, GND→GND, DIN→D10, CS→D9, CLK→D8 |
| 模拟摇杆 | 1 | VCC→5V, GND→GND, VRX→A0, VRY→A1, SW→D2 |
| Arduino Proto Shield | 1 | 扩展 5V/GND 接口,免面包板 |
| 公母杜邦线 | 若干 | 连接模块 |
接线图
LED矩阵 (MAX7219) 摇杆 VCC ────── 5V VCC ────── 5V GND ────── GND GND ────── GND DIN ────── D10 VRX ────── A0 CS ────── D9 VRY ────── A1 CLK ────── D8 SW ────── D2
核心代码逻辑
init_game():初始化蛇身位置(中间 3 格)、食物随机坐标、初始方向向左advance():计算新头部坐标,边界/自碰撞判定,吃食增长并重置食物readControls():读取摇杆 ADC 值映射为 -1/0/1,防止 180° 掉头showGameOverMessage():从 PROGMEM 读取 8×90 点阵字模滚动显示 "GAME OVER"- 主循环
loop()每ADVANCE_DELAY=20ms推进一帧,约 50 FPS
完整代码
/** Snake - 经典贪吃蛇 on 8x8 LED Matrix
* 23 Jun 2016 by Sergey Royz & hunter Buzzell */
#include <LedControl.h>
#define VRX A0
#define VRY A1
#define SW 2
#define CLK 8
#define CS 9
#define DIN 10
#define SIZE 8
#define ADVANCE_DELAY 20
int snake[SIZE*SIZE][2];
int length;
int food[2], v[2];
bool is_game_over = false;
long current_time, prev_advance;
int blink_count;
const short messageSpeed = 5;
LedControl lc = LedControl(DIN, CLK, CS, 1);
void init_game() {
prev_advance = current_time = 0;
blink_count = 3;
int half = SIZE / 2;
length = SIZE / 3;
for (int i = 0; i < length; i++) {
snake[i][0] = half - 1;
snake[i][1] = half + i;
}
food[0] = half + 1; food[1] = half - 1;
v[0] = 0; v[1] = -1;
}
void render() {
for (int i = 0; i < length; i++)
lc.setLed(0, snake[i][0], snake[i][1], 1);
lc.setLed(0, food[0], food[1], 1);
}
void clearScreen() {
for (int x = 0; x < SIZE; x++)
for (int y = 0; y < SIZE; y++)
lc.setLed(0, x, y, 0);
}
bool advance() {
int head[2] = {snake[0][0] + v[0], snake[0][1] + v[1]};
if (head[0] < 0 || head[0] >= SIZE || head[1] < 0 || head[1] >= SIZE) {
delay(1000); showGameOverMessage(); return true;
}
for (int i = 0; i < length; i++)
if (snake[i][0] == head[0] && snake[i][1] == head[1]) {
delay(1000); showGameOverMessage(); return true;
}
bool grow = (head[0] == food[0] && head[1] == food[1]);
if (grow) {
length++;
randomSeed(current_time);
food[0] = random(SIZE); food[1] = random(SIZE);
}
for (int i = length - 1; i >= 0; i--) {
snake[i+1][0] = snake[i][0];
snake[i+1][1] = snake[i][1];
}
snake[0][0] += v[0]; snake[0][1] += v[1];
return false;
}
void setup() {
pinMode(SW, INPUT_PULLUP);
pinMode(VRX, INPUT); pinMode(VRY, INPUT);
attachInterrupt(digitalPinToInterrupt(SW), restart, RISING);
lc.shutdown(0, false);
lc.setIntensity(0, 8);
init_game(); render();
}
void loop() {
if (!is_game_over) {
clearScreen(); render();
if (current_time - prev_advance > ADVANCE_DELAY) {
is_game_over = advance();
prev_advance = current_time;
}
} else {
while (blink_count-- > 0) {
clearScreen(); delay(300);
render(); delay(300);
}
}
readControls();
current_time++;
}
void restart() { init_game(); is_game_over = false; }
void readControls() {
int dx = map(analogRead(VRX), 0, 906, 2, -2);
int dy = map(analogRead(VRY), 0, 906, -2, 2);
if (dx != 0) dx = dx / abs(dx);
if (dy != 0) dy = dy / abs(dy);
if (dy != 0 && v[0] != 0) { v[0] = 0; v[1] = dy; }
if (dx != 0 && v[1] != 0) { v[0] = dx; v[1] = 0; }
}
// PROGMEM 存储 "GAME OVER" 滚动字模 (8x90)
const PROGMEM bool gameOverMessage[8][90] = { ... };
void showGameOverMessage() {
for (int d = 0; d < sizeof(gameOverMessage[0]) - 7; d++) {
for (int col = 0; col < 8; col++) {
delay(messageSpeed);
for (int row = 0; row < 8; row++)
lc.setLed(0, row, col, pgm_read_byte(&gameOverMessage[row][col+d]));
}
}
}
扩展玩法
- 外壳:用美高美/乐高搭建手持游戏机外壳
- 加装蜂鸣器播放音效
- 增加 OLED 显示分数
- 移植至 Arduino Nano + 电池做便携版
制造工艺
- DIY Arduino USB 游戏手柄 — 自制高性能游戏手柄
- 用 Arduino Nano 与 MAX7219 制作 24×16 LED Pong 游戏机
- 自制 16×8 LED 矩阵俄罗斯方块游戏机:Arduino Nano + 74HC595 驱动
- Arduino + HC-05 蓝牙控制 LED:MIT App Inventor 手机 App 开发全攻略
- 互动 LED 矩阵门显:PIR 触发节日问候 + 待机特效
- 从零构建智能 Arduino 四足机器人:完整指南
- Pixel Chaser:Arduino Nano 单键 NeoPixel 追逐小游戏
- Arduino 8×8 LED 矩阵翻页时钟 - DIY 实时时钟项目
- Arduino RGB LED调色器:三电位器混色入门项目
- Arduino Uno驱动MAX7219级联8×8 LED矩阵:从入门到动画显示
- Arduino Nano 与 WS2812 灯带打造 1D 乒乓球游戏——分步 DIY 教程
- 户外DMX控制RGB投光灯:低成本高性能舞台灯光DIY方案