Для начала в двух словах опишу цель проекта. Хотелось придумать что-нибудь простое и наглядное для демонстрации коммуникации платы Arduino Uno и ПК по serial соединению. Что-нибудь, что бы вписывалось в регламенты проекта «выходного дня», а именно: делалось за пару часов и легко кодилось.
Решено было создать игру со следующими правилами. Действие происходит на рабочей двухмерной плоскости. Шарик «герой», положением которого управляет игрок, пытается уйти от столкновения с шариками «противниками». Шарик герой движется только по оси абсцисс, противники появляются в произвольном месте рабочей плоскости и движутся прямолинейно по оси ординат. В случае ухода шарика «героя» от столкновения с «противником», значение счетчика очков инкрементируется, в противном случае — счетчик сбрасывается и набранные ранее очки «сгорают».
Шаг 1
Выбор языка программирования. Был выбран Processing, так как язык для программирования плат Arduino основан на нем, также Processing — хороший и простой инструмент для создания картинок, эффектов анимации и пр. Да, еще он бесплатный.
Шаг 2
Сборка самодельного «джойстика». Все донельзя тривиально. Роль джойстика выполняет обычный потенциометр, подключенный между питанием +5V и землей GND на плате Arduino Uno. Средний контакт выведен на аналоговый пин «A0».
Естественно, при желании Вы можете использовать аналоговый стик, тачпад и пр. Суть та же.
Шаг 3
Программирование платы Arduino. В данном проекте от платы Arduino требуется непрерывно отправлять данные о положении движка потенциометра. Впоследствии, эти данные на компьютере «подхватывает» Processing для нужд игры (определения координаты шарика «героя»).
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» под спойлером.
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
Демонстрация игры
ссылка на оригинал статьи http://geektimes.ru/post/262878/
Добавить комментарий