NeoPixel Matrix Pong на Arduino Nano: неоновая игра Pong на матрице 15×10
Компоненты и материалы
| Лента NeoPixel (WS2812B), 30 LED/m, 5 м | 1 |
| Arduino Nano R3 | 1 |
| Перемычки | 1 |
| Разъем PLS-8 (female header 8 pin) | 1 |
| Перфоплата half-size | 1 |
| Аналоговый джойстик (или потенциометр) | 1 |
| Потенциометр (для управления ракеткой) | 1 |
Инструменты
- Паяльник
Программное обеспечение
- Arduino IDE + библиотеки Adafruit_GFX, Adafruit_NeoMatrix, Adafruit_NeoPixel
О проекте
Матрица из ленты NeoPixel
Покупаем ленту, разрезаем на отрезки по 10 LED (у меня 15 столбцов = 150 LED). Важно: стрелки на ленте задают направление — паять строго в одну сторону, иначе сгорит!
Выкладываем полоски на картоне в зигзаге (чередование направления), паяем перемычки. 14 соединений — и матрица 15×10 готова. Проверяем мультиметром на КЗ (КЗ убьет Nano, матрицу и USB-порт — проверено на себе). Заливаем тестовый скетч neomatrix с параметрами NEO_BOTTOM + NEO_LEFT + NEO_COLUMNS + NEO_ZIGZAG. Если пробегает «howdy» — дисплей работает.
Логика игры
Объекты: ракетка, стены, мяч. Координаты мяча ballX, ballY; направление — ±1. Ракетка (ширина 4 пикселя) управляется потенциометром (маппинг 0–1023 → 0–12). Y ракетки фиксирован (8). Игра начинается с мяча в (1,1) — нужно отбить один раз. Физика учитывает, в какую часть ракетки попал мяч.
Запуск и игра
Подключаем: матрица → Nano (DIN на D6, питание 5V/GND), джойстик/потенциометр → A0. Включаем — играем! Можно добавить второго игрока, улучшить физику.
Полный скетч
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#define PIN 6
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(15, 10, PIN,
NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
NEO_GRB + NEO_KHZ800);
int paddleX = 0, paddleY = 8;
int oldPaddleX, oldPaddleY;
int ballDirectionX = 1, ballDirectionY = 1;
int score = 0;
int ballSpeed = 10; // меньше = быстрее
int ballX, ballY, oldBallX, oldBallY;
void setup() {
Serial.begin(9600);
matrix.begin();
matrix.fillScreen(0);
matrix.setTextColor(matrix.Color(0,255,0));
matrix.print("GO");
matrix.show();
delay(2000);
matrix.fillScreen(0);
matrix.show();
}
void loop() {
int myWidth = matrix.width();
int myHeight = matrix.height();
paddleX = map(analogRead(A0), 0, 1023, 0, 12);
paddleY = 8;
if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
matrix.fillRect(oldPaddleX, oldPaddleY, 4, 1, matrix.Color(0,0,0));
}
matrix.fillRect(paddleX, paddleY, 4, 1, matrix.Color(0,0,255));
oldPaddleX = paddleX; oldPaddleY = paddleY;
matrix.show();
if (millis() % ballSpeed < 2) moveBall();
matrix.show();
// Геймоверишн: мяч ушел за нижнюю границу (y>8) и прошло >10 сек
if (ballY > 8 && millis() > 10000) {
score++;
matrix.fillScreen(0);
matrix.setTextColor(matrix.Color(255,0,0));
matrix.setCursor(0,2);
matrix.print(String(score));
matrix.show();
delay(4000);
ballX = random(3,11);
ballY = random(1,1);
matrix.fillScreen(0);
matrix.show();
delay(1000);
}
delay(5);
}
void moveBall() {
if (ballX > matrix.width()-1 || ballX < 0) ballDirectionX = -ballDirectionX;
if (ballY > matrix.height() || ballY < 0) ballDirectionY = -ballDirectionY;
if (inPaddle(ballX, ballY, paddleX, paddleY, 4, 1)) {
if (ballX == paddleX && ballY == paddleY) { ballDirectionX = -ballDirectionX; ballDirectionY = -ballDirectionY; }
else if (ballX == paddleX+3 && ballY == paddleY) { ballDirectionY = -ballDirectionY; }
else if (ballX == paddleX+1 && ballY == paddleY) { ballDirectionX = -ballDirectionX; ballDirectionY = -ballDirectionY; }
else if (ballX == paddleX+2 && ballY == paddleY) { ballDirectionY = -ballDirectionY; }
}
ballX += ballDirectionX;
ballY += ballDirectionY;
if (oldBallX != ballX || oldBallY != ballY)
matrix.drawPixel(oldBallX, oldBallY, matrix.Color(0,0,0));
matrix.drawPixel(ballX, ballY, matrix.Color(150,150,0));
oldBallX = ballX; oldBallY = ballY;
}
bool inPaddle(int x, int y, int rx, int ry, int rw, int rh) {
return (x >= rx && x <= rx+rw && y >= ry && y <= ry+rh);
}
Схема подключения
См. раздел Schematics: NeoPixel DIN → D6, VCC/GND → 5V/GND Nano, потенциометр → A0, GND, 5V.
Производственный процесс
- TinyML-детектор языка на Arduino Nano 33 BLE Sense с Edge Impulse
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- Строим Iron Man на Arduino: компоненты, сенсоры и пошаговый гайд
- Find Me: Умный поисковик вещей на Arduino и Bluetooth
- DIY-контроллер увлажнителя на Arduino с реле: безопасная работа с высоким напряжением
- Измерение расстояния в реальном времени: Ардуино-сонар с визуализацией в Processing
- MobBob: Самостоятельная сборка Arduino-робота под управлением Android-смартфона
- Сборка аудиореактивной настольной лампы на Arduino Nano
- Своё рулевое управление (джойстик) для игр на Arduino