Arduino:Примеры/EsploraPong
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Игра в Pong с помощью Esplora[1]
А не хотите ли поиграть с помощью Esplora в Pong? Этот пример покажет как.
Он создан, чтобы работать в паре со скетчем Processing (это язык программирования с открытым кодом). Esplora считывает данных со своих кнопок и слайдера, а затем через последовательный порт отправляет данные скетчу Processing, а он, в свою очередь использует их для перемещения «рокеток» в Pong.
Если Processing на вашем компьютере нет, его можно загрузить с сайта Processing, а затем установить, следуя руководству по инсталляции.
Скетч Processing к этому примеру можно скачать по этой ссылке(также с кодом можно ознакомиться ниже).
Вам нужно лишь распаковать этот фал в папке скетчей Processing, а затем открыть саму Processing и запустить там нужный файл с расширением *.pde.
Необходимое оборудование
- Плата Arduino Esplora;
Необходимое ПО
Цепь
Для этого примера нужна лишь плата Arduino Esplora.
Элементы Esplora, необходимые для этого примера – кнопки и линейный потенциометр
Код для Arduino
Этот пример отправляет на компьютер данные о позиции слайдера линейного потенциометра и состоянии трех кнопок. Processing-скетч, связанный с этим Esplora-скетчем, считывает эти данные, чтобы управлять «рокетками» и другими элементами игры Pong.
Данные всегда отправляются в таком порядке: слайдер, 1-ая кнопка, 3-тья кнопка, 4-ая кнопка. Кроме того, эти данные разделены запятыми. Функция Serial.printIn() отправляет данные о последней кнопке, завершая их символом новой строки. Processing-скетчу этот символ нужен для того, чтобы знать, что он получил все необходимые данные от датчиков.
ПРИМЕЧАНИЕ: Одновременно к последовательным портам компьютера может иметь доступ только одна программа. То есть, если у вас открыт Serial Monitor, то скетчу Processing к последовательному порту Esplora доступ будет закрыт. Точно также, при запущенном скетче Processing открыть Serial Monitor и перепрограммировать Esplora будет нельзя.
/*
Игра в Pong с помощью Esplora
Этот скетч через последовательный порт подключается к скетчу Processing,
чтобы сделать Esplora контроллером для игры в Pong.
Он передает скетчу Processing информацию о позиции слайдера и состояниях трех кнопок Esplora.
Эти данные отделены друг от друга запятыми.
Скетч Processing использует эти данные, чтобы управлять имеющейся в нем графикой.
Слайдер отвечает за высоту «рокетки»,
кнопка 1 перезагружает игру,
кнопка 2 ставит мячик в центр,
кнопка 3 меняет игрока.
В эту игру можно играть и на одной, и на двух Esplora.
Создан 22 декабря 2012 Томом Иго (Tom Igoe).
Этот код не защищен авторским правом.
*/
#include <Esplora.h>
void setup() {
Serial.begin(9600); // инициализируем последовательную передачу данных
}
void loop() {
// Считываем данные от слайдера и трех кнопок
int slider = Esplora.readSlider();
int resetButton = Esplora.readButton(SWITCH_1);
int serveButton = Esplora.readButton(SWITCH_3);
int switchPlayerButton = Esplora.readButton(SWITCH_4);
Serial.print(slider); // выводим на Serial Monitor данные от слайдера
Serial.print(","); // добавляем запятую
Serial.print(resetButton); // выводим данные от перезагружающей кнопки
Serial.print(","); // добавляем еще запятую
Serial.print(serveButton); // выводим данные от кнопки, ставящей мячик в центр экрана
Serial.print(","); // добавляем еще запятую
Serial.println(switchPlayerButton); // выводим данные от последней кнопки плюс символ новой строки
delay(10); // делаем задержку перед тем, как отправлять следующую порцию данных
}
Код для Processing
ProcessingPong.pde
/*
Скетч к Processing для игры в Pong
Этот скетч принимает через последовательный порт входящие данные
от одной или двух плат Esplora, тем самым позволяя играть в Pong.
«Эсплоры» пересылают скетчу четыре значения, разделенных запятыми
и заканчивающихся переводом строки.
Это значения от четырех устройств ввода:
* слайдера (отвечает за ход «ракетки» вверх-вниз),
* кнопки номер 1 (перезагружает игру),
* кнопки номер 2 (ставит мячик в центр),
* кнопки номер 3 (меняет игроков местами).
Эти значения отсылаются скетчу Processing при помощи Arduino-скетча
под названием «Игра в Pong с помощью Esplora» (EsploraPong).
Чтобы начать игру, выберите номер порта (портов) Esplora.
Создан 22 декабря 2012 Томом Иго (Tom Igoe).
Этот код не защищен авторским правом.
*/
import processing.serial.*; // импортируем библиотеку Serial
import java.awt.Rectangle; // импортируем Java-класс Rectangle
Serial[] EsploraList = new Serial[2]; // список девайсов, коммуникация с которыми будет осуществляться при помощи последовательного порта
int portCount = 0; // количество инициализированных последовательных портов
String portNumber = ""; // строка, обозначающая следующий порт, который будет инициализирован
Rectangle leftPaddle, rightPaddle; // прямоугольники, играющие роль «ракеток»
int resetButton = 1; // значение для кнопки сброса
int serveButton = 1; // значение для кнопки, которая ставит мячик в центр экрана
int switchSidesButton = 1; // значение для кнопки, меняющей игроков местами
int paddleHeight = 50; // вертикальный размер «ракетки»
int paddleWidth = 10; // горизонтальный размер «ракетки»
int ballSize = 10; // размер мячика
int xDirection = 2; // для перемещения мячика по горизонтали: влево «-2», вправо «2»
int yDirection = 2; // для перемещения мячика по вертикали: вверх «-2», вниз «2»
int xPos, yPos; // вертикальная и горизонтальная позиция мячика
boolean ballInMotion = false; // должен ли мячик двигаться или нет
int leftScore = 0; // счетчик очков для игрока слева
int rightScore = 0; // счетчик очков для игрока справа
int fontSize = 20; // размер шрифтов на экране
void setup() {
size(640, 480); // размер для экрана программы
// Инициализируем «ракетки»:
leftPaddle = new Rectangle(50, height/2, paddleWidth, paddleHeight);
rightPaddle = new Rectangle(width-50, height/2, paddleWidth, paddleHeight);
// Делаем так, чтобы у рисуемых нами фигур не было контура:
noStroke();
// Инициализируем мячик в центре экрана:
xPos = width/2;
yPos = height/2;
// Создаем шрифт. Это будет третий шрифт, доступный системе:
PFont myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);
}
void draw() {
// Очищаем экран:
background(0);
fill(255);
// Если было инициализировано недостаточно портов... :
if (portCount < 2) {
// Требуем список последовательных портов:
String[] portList = Serial.list();
// Выводим на экране инструкции:
text("Type the port number of Esplora #" + (portCount+1), 20, 20); // "Введите номер порта Esplora #"
text("(or type enter to finish):", 20, 40); // "Или нажмите Enter, чтобы закончить"
// Выводим на экране список портов:
for (int i = 0; i < portList.length; i++) {
text("port " + i + ": " + portList[i], 20, (i+4)*20);
}
}
// Если портов достаточно... :
else {
// Рисуем первую «ракетку»:
rect(leftPaddle.x, leftPaddle.y, leftPaddle.width, leftPaddle.height);
// Рисуем вторую «ракетку»:
rect(rightPaddle.x, rightPaddle.y, rightPaddle.width, rightPaddle.height);
// Вычисляем позицию мячика и рисуем его:
if (ballInMotion == true) {
animateBall();
}
// Показываем счетчики очков:
text(leftScore, fontSize, fontSize);
text(rightScore, width-fontSize, fontSize);
}
}
// Функция serialEvent будет запускаться автоматически всякий раз,
// когда в буфере появятся байты от bufferUntil():
void serialEvent(Serial thisPort) {
// Считываем значения в буфере последовательного порта:
String inputString = thisPort.readStringUntil('\n');
// Отрезаем от входящей строки символы возврата строки и перевода строки:
inputString = trim(inputString);
// Делим входящую строку по запятым и конвертируем результат в целые числа:
int sensors[] = int(split(inputString, ','));
// Если получили от датчиков все необходимые данные, используем их:
if (sensors.length == 4) {
// Если это левая Esplora:
if (thisPort == EsploraList[0] && EsploraList[0] != null) {
// подгоняем значения от слайдера к диапазону хода «ракеток»:
leftPaddle.y = int(map(sensors[0], 0, 1023, 0, height - leftPaddle.height));
}
// если это правая Esplora:
if (thisPort == EsploraList[1] && EsploraList[1] != null) {
rightPaddle.y = int(map(sensors[0], 0, 1023, 0, height- rightPaddle.height));
}
// Если кнопка сброса поменяла свое состояние, сбрасываем очки:
if (resetButton == 1 && sensors[1] == 0) {
leftScore = 0;
rightScore = 0;
resetBall();
ballInMotion = true;
}
// Сохраняем текущее состояние кнопки сброса для сравнения при следующем считывании:
resetButton = sensors[1];
// Если кнопка для перемещения мячика в центр экрана поменяла свое состояние,
// то ставим мячик в центр:
if (serveButton == 1 && sensors[2] == 0) {
resetBall();
ballInMotion = true;
}
// сохраняем текущее состояние этой кнопки для сравнения при следующем считывании:
serveButton = sensors[2];
// Если кнопка смены игроков поменяла свое состояние,
// то меняем правого и левого игроков местами:
if (switchSidesButton == 1 && sensors[3] == 0) {
switchSides();
}
// Сохраняем текущее состояние этой кнопки для сравнения при следующем считывании:
switchSidesButton = sensors[3];
}
}
void animateBall() {
if (leftPaddle.contains(xPos, yPos) || // если позиция мячика внутри левой «ракетки»
rightPaddle.contains(xPos, yPos)) { // или если позиция мячика внутри правой «ракетки»
xDirection = -xDirection; // реверсируем направление движения мячика по оси X
}
// Если мячик вышел за пределы экрана слева, засчитываем очки правому игроку:
if (xPos < 0) {
rightScore++;
resetBall();
}
// Если мячик вышел за пределы экрана справа, засчитываем очки левому игроку:
if (xPos > width) {
leftScore++;
resetBall();
}
// Делаем так, чтобы мячик не мог выйти за пределы экрана сверху и снизу:
if ((yPos <= 0) || (yPos >=height)) {
// Реверсируем движение мячика по оси Y:
yDirection = -yDirection;
}
// Обновляем позицию мячика:
xPos = xPos + xDirection;
yPos = yPos + yDirection;
// Рисуем мячик:
rect(xPos, yPos, ballSize, ballSize);
}
void resetBall() {
// Ставим мячик в центр:
xPos = width/2;
yPos = height/2;
}
void keyReleased() {
// Если нажат Enter, останавливаем выбор номера порта:
if (key == ENTER) {
if (portNumber != "" && portCount < 2) {
choosePort(int(portNumber));
}
portCount++;
}
// Если пользователь жмет на клавиши от 0 до 9, используем это как выбор номера порта:
if (key >= '0' && key <= '9') {
portNumber += key;
}
}
void choosePort(int whichPort) {
// Получаем название порта из списка последовательных портов:
String portName = Serial.list()[whichPort];
// Инициализируем следующую Esplora:
EsploraList[portCount] = new Serial(this, portName, 9600);
// Считываем байты в буфер последовательного порта до тех пор,
// пока не доберемся до символа перевода строки (номер 10 в таблице ASCII):
EsploraList[portCount].bufferUntil('\n');
// Очищаем строку с номером порта:
portNumber = "";
}
void switchSides() {
Serial temp = EsploraList[0]; // на время сохраняем первый элемент
EsploraList[0] = EsploraList[1]; // перемещаем второй элемент к первому
EsploraList[1] = temp; // перемещаем первый элемент ко второму
}
См.также
- Esplora Pong
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Пример
- Примеры
- Пример программирования Arduino
- Примеры программирования Arduino