Для начала в двух словах опишу цель проекта. Хотелось придумать что-нибудь простое и наглядное для демонстрации коммуникации платы Arduino Uno и ПК по serial соединению. Что-нибудь, что бы вписывалось в регламенты проекта «выходного дня», а именно: делалось за пару часов и легко кодилось.
Решено было создать игру со следующими правилами. Действие происходит на рабочей двухмерной плоскости. Шарик «герой», положением которого управляет игрок, пытается уйти от столкновения с шариками «противниками». Шарик герой движется только по оси абсцисс, противники появляются в произвольном месте рабочей плоскости и движутся прямолинейно по оси ординат. В случае ухода шарика «героя» от столкновения с «противником», значение счетчика очков инкрементируется, в противном случае — счетчик сбрасывается и набранные ранее очки «сгорают».
Выбор языка программирования. Был выбран Processing, так как язык для программирования плат Arduino основан на нем, также Processing — хороший и простой инструмент для создания картинок, эффектов анимации и пр. Да, еще он бесплатный.
Сборка самодельного «джойстика». Все донельзя тривиально. Роль джойстика выполняет обычный потенциометр, подключенный между питанием +5V и землей GND на плате Arduino Uno. Средний контакт выведен на аналоговый пин «A0».
Естественно, при желании Вы можете использовать аналоговый стик, тачпад и пр. Суть та же.
Программирование платы Arduino. В данном проекте от платы Arduino требуется непрерывно отправлять данные о положении движка потенциометра. Впоследствии, эти данные на компьютере «подхватывает» Processing для нужд игры (определения координаты шарика «героя»).
Собственно, написание самой игры. Как уже говорилось ранее, игра пишется на языке Processing. Скачать дистрибутив можно на оф сайте, там же есть примеры использования. В моем случае «движок» состоит из 49 строчек кода из которых половина — это комментарии. Что хочу сказать, разобраться в нем сложности не составит. Вы можете самостоятельно изменить «шкурки» героев, добавить кол-во противников, ввести в игру бонусы, избавить данные с потенциометра от дребезга и пр. Мой код «as is» под спойлером.
Демонстрация игры
Решено было создать игру со следующими правилами. Действие происходит на рабочей двухмерной плоскости. Шарик «герой», положением которого управляет игрок, пытается уйти от столкновения с шариками «противниками». Шарик герой движется только по оси абсцисс, противники появляются в произвольном месте рабочей плоскости и движутся прямолинейно по оси ординат. В случае ухода шарика «героя» от столкновения с «противником», значение счетчика очков инкрементируется, в противном случае — счетчик сбрасывается и набранные ранее очки «сгорают».
Шаг 1
Выбор языка программирования. Был выбран Processing, так как язык для программирования плат Arduino основан на нем, также Processing — хороший и простой инструмент для создания картинок, эффектов анимации и пр. Да, еще он бесплатный.
Шаг 2
Сборка самодельного «джойстика». Все донельзя тривиально. Роль джойстика выполняет обычный потенциометр, подключенный между питанием +5V и землей GND на плате Arduino Uno. Средний контакт выведен на аналоговый пин «A0».
Естественно, при желании Вы можете использовать аналоговый стик, тачпад и пр. Суть та же.
Шаг 3
Программирование платы Arduino. В данном проекте от платы Arduino требуется непрерывно отправлять данные о положении движка потенциометра. Впоследствии, эти данные на компьютере «подхватывает» Processing для нужд игры (определения координаты шарика «героя»).
Код для платы Arduino Uno
int potPin = 0;// устанавливаем номер пина, к которому подключена средняя ножка
//потенциометра
void setup() {
Serial.begin(9600);//открываем serial соединение для приема и передачи данных
}
void loop() {
int val = map (analogRead(potPin), 0, 1023, 0, 640);//напряжение на средней ножке на
// аналоговом пине представляется в Arduino в виде числа от 0 до 1023.
// Функция map меняет диапазон представления с 0 до 640.
//Забегая вперед, последняя цифра должна советовать ширине заданного в программе
// на Processing окна
Serial.println(val);// для вывода сообщения в монитор последовательного порта
delay(50);// задержка в 50 мс
}
Шаг 4
Собственно, написание самой игры. Как уже говорилось ранее, игра пишется на языке Processing. Скачать дистрибутив можно на оф сайте, там же есть примеры использования. В моем случае «движок» состоит из 49 строчек кода из которых половина — это комментарии. Что хочу сказать, разобраться в нем сложности не составит. Вы можете самостоятельно изменить «шкурки» героев, добавить кол-во противников, ввести в игру бонусы, избавить данные с потенциометра от дребезга и пр. Мой код «as is» под спойлером.
Код игры на Processing
import processing.serial.*;//I/O library
Serial port;
PShape bot; //инициализация типа картинки для иллюстрации взрыва при столкновении
PFont font; // инициализация типа шрифта
int radiusOfHero=100, radiusOfEnemy, speedOfEnemy=1, Counter=0;
float positionOfHeroX=100.0, positionOfEnemyY = 0.0 ,positionOfEnemyX=0.0;
void setup()
{
size(640, 400);// задаем размеры окна
port = new Serial(this, "COM4", 9600);// в моем случае эмулятором COM порта присвоен
// номер 4
port.bufferUntil('\n');
bot = loadShape("2.svg");// задаем картинку, файл должен лежать в директории Processing
font = loadFont("AgencyFB-Bold-200.vlw");// выбранный шрифт для счетчика
textFont(font,200);
}
void draw() {
background(0);
fill(255);
text(Counter, 30,175);// вывод содержимого счетчика на окно сначальной координатой (30; 175)
//===============definiton of hero position=============
fill(0, 102, 153);
ellipse(positionOfHeroX, height-radiusOfHero/2, radiusOfHero, radiusOfHero);// положение
// шара-героя
//===============definition of enemy===============
fill(255,0,0);
radiusOfEnemy=round(random(60));{
for(int i = 0; i < height; i++)
positionOfEnemyY=positionOfEnemyY+0.02*speedOfEnemy;// скорость падения шаров-противников по оси ординат
ellipse(positionOfEnemyX, positionOfEnemyY, radiusOfEnemy*2, radiusOfEnemy*2); }// отрисовка шаров-противников
if (positionOfEnemyY>height) {
positionOfEnemyY=0.0;
positionOfEnemyX = round(random(width)); // условие для повторения падения шаров-противников
Counter++;}
//==============clash==========================
if (abs(positionOfHeroX-positionOfEnemyX) < (radiusOfHero+radiusOfEnemy)/2 &
(abs(height-radiusOfHero/2)-positionOfEnemyY) < (radiusOfHero+radiusOfEnemy)/2){// условие столкновения шаров-противников
background(255,0,0);
shape(bot, positionOfHeroX-radiusOfHero/2,height-radiusOfHero, 100, 100);
Counter=-1;
fill(255);
textFont(font,150);
text("TURN AWAY!", 0,height/2);
}
}
void serialEvent (Serial port) {
positionOfHeroX=round(float(port.readStringUntil('\n')));// считывание координаты положения шара-героя из порта COM4
}
Шаг 5
Демонстрация игры
Видео