Рассмотрим как написать простую игру для LEGO EV3 в CLEV3R. Про среду CLEV3R можно найти материалы на сайте разработчика clev3r.ru
Программа рабочая. Пока пишу статью и пока снимал видеоролик много раз успел поиграть. Мой рекорд 80 очков, хотя мой сын смог набрать аж 107.
Листинг (текст) программы целиком есть в конце статьи. Можно копировать и вставлять. После листинга ссылка на файл архива. В не архивированном виде не получилось разместить на сайте.
Видеоролик написания программы с проверками результата
Видеоролик показывает написание программы с небольшими пояснениями. На канале есть ещё несколько видео посвященных LEGO конструкциям.
Если видео не получается просмотреть, напишите в комментариях и я попробую разместить на другой площадке.
Координаты на экране блока LEGO EV3
Экран блока LEGO EV3 является жидкокристаллическим индикатором ЖКИ или на английский манер LCD. Координаты объектов на экране задаются в пикселях (в точках). Каждая точка может быть в одном из двух состояний — черная (тёмная) или белая (светлая). Когда EV3 выключен или после выполнения команды LCD.Clear() все пиксели экрана в состоянии светлая.
Начало координат в левом верхнем углу экрана. Координата самого левого верхнего пикселя x=0 и y=0. Всего столбцов точек по горизонтали, по координате x 178 штук, а строк точек по вертикали, по координате y 128 штук. Получается, что координата самой правой нижней точки x=177 и y=127.
Общее описание программы
Программа получилась простая, но выделить разделы в ней можно.

Присваиваем начальные значения переменным и константам. Здесь нет разделения на переменные и константы. Некоторые переменные имеют одно значение, не меняют его в процессе выполнения программы. Например, коэффициент гравитации g.
Некоторые переменные периодически меняют своё значение. Например, координата птицы по вертикали yb.
Функция для вывода на экран изображений препятствий — труб. Бывает удобно выделить определённую последовательность команд в отдельный блок, в отдельную функцию. Например, если одну и ту же последовательность требуется выполнить в разных местах программы. При такой организации удобно настраивать программу. Изменения вносить в одном месте легче, чем копировать несколько раз.


Эта группа команд устанавливает режим датчика, обнуляет таймер и делает начало программы более заметным. Для заметности поручам блоку EV3 пикнуть и отобразить на экране надпись.
Главный, основной цикл программы получился длинный, поэтому только кусок на картинке. Внутри этого цикла есть ещё цикл и условия и формулы. Пока мы играем в игру, программа выполняет этот цикл.


После завершения игры и соответственно выхода из главного цикла, блок EV3 пикает и отображает на экране набранные очки. Назовём эту часть программы: «декоративное оформление конца игры».
Если возникают сложности с пониманием работы программы, напишите в комментариях и я сделаю пояснения.
Текст программы игры Flappy Bird
t=100 'время между прорисовками
yb=30 'положение птички по вертикали
xb=15 'положение птички по горизонтали
vy=0 ' скорость птички по вертикали
g=1 'коэффициент гравитации
vymax=5 'максимальная скорость снижения высоты птички
vfl=-3 'скорость птички вверх после нажатия кнопки
x1=178 'положение по горизонтали препятствия 1
x2=267 'положение по горизонтали препятствия 2
y1=64 'положение коридора в препятствии 1 по вертикали
y2=64 'положение коридора в препятствии 2 по вертикали
vx=-3 'скорость перемещения препятствий по горизонтали
c=3 'количество допустимых столкновений
c1=0 'флаг для исключения многократных срабатываний при одном столкновении
s=0 'количество набранных очков
Function Tube(in number Xt, in number Yt) 'функция прорисовки препятствия
LCD.FillRect(1,Xt-10,0,20,128)
LCD.FillRect(1,Xt-12,Yt-25,24,50)
LCD.FillRect(0,Xt-12,Yt-20,24,40)
EndFunction
Sensor.SetMode(1,0) 'установка режима датчика порта 1
Speaker.Tone(30,500,200)
LCD.Clear()
LCD.Text(1,20,20,2,"START")
Program.Delay(1000)
Time.Reset1() 'обнуление таймера для отслеживания времени между прорисовками
While yb>0 And yb<127 'основной цикл пока птичка не вылетела за дисплей
LCD.Clear() 'прорисовка во время игры
Tube(x1,y1) 'переход в функцию прорисовки препятствия с координатами 1
Tube(x2,y2) 'переход в функцию прорисовки препятствия с координатами 2
LCD.Text(1,30,110,2,"health "+c) 'выводим на дисплей количество возможных столкновений
LCD.Text(1,30,10,2,"SCORE "+s) 'выводим количество набранных очков
LCD.FillCircle(1,xb,yb,5) 'птицу рисую кружком
LCD.Update()
LCD.StopUpdate()
While Time.Get1()<t 'цикл отслеживающий нажатия кнопки и датчика касания длится пока длится время между прорисовками
If Sensor.ReadPercent(1)>10 Or Buttons.GetClicks()="U" Then
vy=vfl 'при нажатии кнопки скорость птички по вертикали становится равной скорости птички вверх
EndIf
EndWhile
Time.Reset1() 'обнуление таймера
t=100-(s/1.5) 'время между прорисовками уменьшается при увеличении количества набранных очков
yb+=vy 'корректируем положение птички по вертикали
If vy<vymax-g Then 'если скорость не очень большая, то увеличиваем
vy+=g 'корректируем скорость птички по вертикали
Else
vy=vymax 'скорость птички по вертикали приравниваем заданному vymax
EndIf
If x1>0 Then 'если препятствие 1 не достигло левого края дисплея
x1+=vx 'смещаем препятствие влево по дисплею
Else
x1=178 'перемещаем препятствие к правому краю дисплея
s++ 'добавляем набранное очко
c1=0 'сбрасываем флаг защиты от многократной фиксации одного столкновения
Speaker.Tone(20,400,100)
If y1<100 Then 'если координата середины коридора препятствия 1 не слишком велика
y1+=11 ' увеличиваем координату середины коридора
Else
y1-=80 'уменьшаем координату коридора, поднимаем к верхнему краю экрана
EndIf
EndIf
If x2>0 Then 'аналогично для препятствия 2
x2+=vx
Else
x2=178
s++
c1=0
Speaker.Tone(20,300,100)
If y2>25 Then
y2-=13
Else
y2+=80
EndIf
EndIf
If (Math.Abs(x1-xb)<=10 And Math.Abs(y1-yb)>20 Or Math.Abs(x2-xb)<=10 And Math.Abs(y2-yb)>20) And c1=0 Then 'по координатам проверяем столкновение птицы с препятствиями
c-- 'уменьшаем количество возможных столкновений
c1=1 'устанавливаем флаг против многократной фиксации одного столкновения
LCD.Clear() 'декоративное оформление столкновения
LCD.FillRect(1,15,15,150,100)
LCD.Text(0,40,30,2,"B A H !")
LCD.Update()
LCD.StopUpdate()
Speaker.Tone(40,1500,100)
Speaker.Tone(30,1200,100)
Program.Delay(1000)
Time.Reset1() 'обнуляем таймер, исключаем влияние столкновения на время до следующих прорисовок
EndIf
If c<0 Then 'выходим из основного цикла игры если закончилось количество возможных столкновений
break
EndIf
EndWhile 'конец основного цикла игры
Speaker.Tone(30,200,200) 'сигнал завершения игры
Speaker.Tone(30,300,200)
Speaker.Tone(30,100,400)
LCD.Clear()
LCD.Text(1,20,20,2,"The end")
LCD.Text(1,30,70,2,"SCORE "+s) 'выводим количество набранных очков
LCD.Update()
Program.Delay(3000)
Файл для скачивания
Можно скопировать программу прямо со странички сайта, а можно скачать файл и открыть его в CLEV3R.