Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

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

Инструменты

Программное обеспечение

О проекте

Матрица из ленты 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.

Производственный процесс

  1. TinyML-детектор языка на Arduino Nano 33 BLE Sense с Edge Impulse
  2. Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
  3. Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
  4. Строим Iron Man на Arduino: компоненты, сенсоры и пошаговый гайд
  5. Find Me: Умный поисковик вещей на Arduino и Bluetooth
  6. DIY-контроллер увлажнителя на Arduino с реле: безопасная работа с высоким напряжением
  7. Измерение расстояния в реальном времени: Ардуино-сонар с визуализацией в Processing
  8. MobBob: Самостоятельная сборка Arduino-робота под управлением Android-смартфона
  9. Сборка аудиореактивной настольной лампы на Arduino Nano
  10. Своё рулевое управление (джойстик) для игр на Arduino