Controls (Керування) (aka "Control Flow" (Потік керування)) змінюють потік вашої програми та дозволяють використовувати умовну чи гілкову логіку. Наприклад, "if speed > 20, then turn LED lights red." (якщо швидкість > 20, тоді увімкнути червоне світло на LED). Існує багато різних типів керувань, щоб створювати цікаві програми, які виходять за межі простих команд руху.

await delay(4) затримує виконання наступного набору команд на кілька секунд.
Наприклад, використовуйте нижче для того, щоб встановити швидкість на 100 на 4 секунди, а потім зупинити:
async function startProgram() {
setSpeed(100);
await delay(4);
setSpeed(0);
}

Цикл (aka "for" цикл) — це конструкція, яка дозволяє повторювати виконання певної частини коду кілька разів.
Цикли дозволяють автоматизувати повторювані операції та зменшити кількість коду. У JavaScript for цикл виглядає так:
for (initialize loop variable; check loop condition; update loop variable) {
// code to repeat goes here (contained between the '{' and '}' braces)
}Опис елементів циклу:
- initialize loop variable (ініціалізація змінної циклу): Визначає початкове значення змінної, яка буде використовуватись для лічильника циклу. Наприклад: var _i1 = 0 — починаємо з 0.
- check loop condition (умова циклу): Перевіряє умову, за якої цикл має повторюватися. Якщо умова true, цикл виконується. Якщо false, цикл завершується. Наприклад: _i1 < 8 — цикл продовжує виконуватись, поки _i1 менше 8.
- update loop variable (оновлення змінної циклу): Після кожної ітерації циклу змінна оновлюється. Зазвичай додається значення до змінної, щоб цикл рухався вперед. Наприклад: _i1++ — збільшення на 1.
У цьому прикладі ми обертаємо робота на 90 градусів і кожного разу говоримо "Spin" 8 разів.
async function startProgram() {
setBackLed(255); // Ввімкнення заднього світлодіода
for (var _i1 = 0; _i1 < 8; _i1++) { // Цикл повторюється 8 разів
await speak('Spin', true); // Проговорюємо "Spin"
setHeading((getHeading() + 90)); // Змінюємо напрямок на 90 градусів
await delay(0.25); // Затримка 0.25 секунди
}
}
Зверніть увагу, що var _i1 створює "змінну циклу" під назвою _i1, щоб відстежувати ітерації циклу.
Коли ви визначаєте нові змінні циклу, ви можете використовувати будь-яке ім’я, яке вам подобається, за умови, що воно є унікальним, але ми використовуємо цю конвенцію для забезпечення однаковості з кодом, згенерованим на основі нашого полотна блоків (block canvas). Це означає, що _i1 — це просто змінна, яку ми використовуємо для відстеження того, скільки разів цикл виконується.
Ви можете змінити ім’я змінної на будь-яке інше, але для послідовності в коді ми дотримуємось цієї практики. Цікаве використання циклів для випадкових кольорів.
Для того щоб встановити випадковий колір на основному LED кожні 0.2с протягом 20 циклів, використовуйте:
async function startProgram() {
for (var _i1 = 0; _i1 < 20; _i1++) { // Цикл повторюється 20 разів
setMainLed(getRandomColor()); // Встановлюємо випадковий колір на основний LED
await delay(0.2); // Затримка 0.2 секунди
}
}
Щоб додати другий цикл до програми випадкових кольорів, вам потрібно нове, унікальне ім’я змінної.
Легкий спосіб зробити це — збільшити значення змінної _i# за допомогою _i2.
Наприклад, код нижче запускає цикл випадкових кольорів 20 разів, а потім запускає другий цикл, який повторює кольори світлофора 4 рази: Це означає, що для другого циклу ми змінюємо змінну циклу на _i2, щоб вона була унікальною і не переписувала попередній цикл з _i1.
async function startProgram() {
// випадкові кольори
for (var _i1 = 0; _i1 < 20; _i1++) {
setMainLed(getRandomColor());
await delay(0.1);
}
// світлофор
for (var _i2 = 0; _i2 < 4; _i2++) {
setMainLed({ r: 0, g: 255, b: 0 }); // Зелене світло
await delay(0.8);
setMainLed({ r: 255, g: 243, b: 14 }); // Жовте світло
await delay(0.8);
setMainLed({ r: 255, g: 0, b: 0 }); // Червоне світло
await delay(0.8);
}
}

Loop Until (також відомий як "while loop" – цикл поки) повторює код, поки не буде виконана умова.
Для цього вам потрібно розуміти, як писати умови за допомогою операторів та компараторів перед використанням Loop Until та інших команд нижче.
Шаблон виглядає так:
while ( !testCondition ) {
// код, який повторюється, поки умова
testCondition() не стане true, після чого цикл зупиняється
}
У цьому шаблоні testCondition – це вираз, який оцінюється як true або false. Оператор !, що означає "не", змінює значення умови на протилежне.
Тобто, якщо testCondition дає значення true, то !testCondition дасть false, і цикл зупиниться. Іншими словами, цикл завершується, коли умова стає true.
У цьому шаблоні testCondition – це вираз, який оцінюється як true (істина) або false (неправда). Оператор !, що означає "не", змінює значення умови на протилежне. Тобто, якщо testCondition дає значення true (умова істинна), то !testCondition дасть false (умова хибна), і цикл зупиниться. Іншими словами, цикл завершується, коли умова стає true (істина).
Приклад: Ви можете використовувати Loop Until, щоб повторювати збільшення швидкості до досягнення певної "Швидкості обмеження", наприклад, 80.
У цьому прикладі, коли швидкість досягне 80, програма зупиниться:
async function startProgram() {
setMainLed({ r: 33, g: 255, b: 20 });
setSpeed(20);
while ( !(getSpeed() === 80) ) { // Could also use JavaScript's !== (not equal to) comparator
await Sound.Game.Notification.play(true);
setSpeed((getSpeed() + 20));
await delay(1.5);
}
setMainLed({ r: 255, g: 26, b: 62 });
setSpeed(0.0);
await Sound.Mechanical.Skid.play(true);
} // code to loop until testCondition() is true, then exit the loop
}У цьому коді:
- Швидкість починається з 20 і збільшується на 20 до тих пір, поки не досягне 80.
- Як тільки швидкість досягає 80, цикл завершується, і виконується зупинка робота.
True (істина) та False (неправда) є булевими значеннями, що в програмуванні використовуються для позначення двох можливих станів: true означає, що умова правильна, а false — що умова хибна.

Loop Forever (також відомий як "while 1" або "while true" – цикл без кінця) повторює код вічно, або до того часу, поки програма не буде зупинена.
Шаблон виглядає так:
while (true)
{
// код, який буде виконуватися безкінечно
}
Наприклад, для створення метронома, що працює безкінечно, можна використати наступний код:
async function startProgram() {
setBackLed(255);
while (true) {
await Sound.Game.Coin.play(true); // програє звук монети
setHeading((getHeading() + 180)); // змінює напрямок на 180°
await delay(1.2); // затримка 1.2 секунди
await Sound.Game.Hit.play(true); // програє звук удару
setHeading((getHeading() - 180)); // змінює напрямок на -180°
await delay(1.2); // затримка 1.2 секунди
}
}
Цей код буде виконуватись безперервно, з чергуванням звуків та зміною напрямку робота.
Вкладені цикли (nested loops) в Loop Forever:
Ви можете вкладати цикли один в один, щоб створювати більш складні програми. Ось приклад, як можна додати світлову послідовність до метроному:
async function startProgram() {
setBackLed(255);
while (true) {
await Sound.Game.Coin.play(true); // програє звук монети
setHeading((getHeading() + 180)); // змінює напрямок на 180°
// зелене світло блимає
for (var green_count = 0; green_count < 6; green_count++) {
setMainLed({ r: 9, g: 255, b: 5 });
await delay(0.1);
setMainLed({ r: 255, g: 247, b: 245 });
await delay(0.1);
}
await Sound.Game.Hit.play(true); // програє звук удару
setHeading((getHeading() - 180)); // змінює напрямок на -180°
// червоне світло блимає
for (var red_count = 0; red_count < 6; red_count++) {
setMainLed({ r: 255, g: 15, b: 0 });
await delay(0.1);
setMainLed({ r: 255, g: 233, b: 227 });
await delay(0.1);
}
}
}
В цьому коді метроном замінює затримку (delay) на світлову послідовність: спочатку зелене світло, потім червоне, і так повторюється безкінечно.

If Then (якщо – тоді) виконує код тільки за умови, що задана умова є істинною (true).
if (condition) {
// код виконується, якщо умова є істинною
}
Наприклад, якщо ви потримаєте робота і потрясете його, світло стане зеленим, а робот скаже "Shake" (потряси).
Для цього потрібно вкласти вираз if...then (якщо...тоді) всередину циклу while (true) (поки правда), як показано нижче. Батьківський цикл while (true) дозволяє програмі виконуватись безкінечно, даючи час роботу кілька разів реагувати.
async function startProgram() {
setStabilization(false); // вимикає стабілізацію
setBackLed(255); // вмикає заднє світло
while (true) {
if ((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4)) {
await speak("Shake", false); // якщо умова виконана, робот скаже "Shake"
setMainLed({ r: 0, g: 255, b: 0 }); // змінює світло на зелене
await delay(1); // затримка 1 секунда
}
await delay(0.025); // затримка для повторного перевірення умови
}
}
У цьому прикладі, якщо значення прискорення більше 1.4, це означає, що робот потрусився, і робот відреагує: він вимовить "Shake" і змінить світло на зелене.
У наведеному коді ми використовуємо умову для виявлення руху робота. Якщо робот буде рухатися (наприклад, буде потрясений), то відбудеться певна дія (наприклад, загориться зелене світло і робот скаже "Shake").
Оператор || (АБО) дозволяє виконати код, якщо хоча б одна з умов із заданого набору є істинною.
Наприклад, розглянемо попередню програму і змінимо її так, щоб передня нахил чи постукування по столу змінювали колір головного світлодіода на зелений:
async function startProgram() {
setStabilization(false); // вимикає стабілізацію
setBackLed(255); // вмикає заднє світло
while (true) { // цикл працює нескінченно
if (((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4) || (getOrientation().pitch < -45))) {
await speak("Shake or Pitch", false); // якщо виконано одну з умов, робот скаже "Shake or Pitch"
setMainLed({ r: 0, g: 255, b: 0 }); // змінює світло на зелене
await delay(1); // затримка 1 секунда
setMainLed({ r: 0, g: 0, b: 0 }); // вимикає світло
}
await delay(0.025); // затримка для повторного перевірення умови
}
}
|| (АБО): Якщо одна з умов Math.sqrt(...) > 1.4 (потрясіння) або getOrientation().pitch < -45 (нахил вперед) істинна, то виконуються дії в блоці if.
speak("Shake or Pitch", false): Робот скаже "Shake or Pitch", якщо одна з умов виконується.
Оператор && (та) вимагає, щоб додаткові умови були виконані.
Ви можете додавати стільки умов, скільки потрібно, але давайте додамо другу умову для того, щоб світло змінилося на зелене.
Друга умова буде вимірювання нахилу вперед за допомогою getOrientation().pitch.
Вам потрібно націлити робота так, щоб світло на хвості було направлене до вас, нахилити його вперед на 45° і потім поставити на стіл.
Якщо ви правильно налаштуєте кут нахилу, світло на LED стане зеленим.
async function startProgram() {
setStabilization(false); // вимикає стабілізацію
setBackLed(255); // вмикає заднє світло
while (true) { // цикл працює нескінченно
if (((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4) && (getOrientation().pitch < -45))) {
await speak("Shake and Pitch", false); // якщо виконано обидві умови, робот скаже "Shake and Pitch"
setMainLed({ r: 0, g: 255, b: 0 }); // змінює світло на зелене
await delay(1); // затримка 1 секунда
setMainLed({ r: 0, g: 0, b: 0 }); // вимикає світло
}
await delay(0.025); // затримка для повторного перевірення умови
}
}&& (та): Умова виконується лише якщо обидві умови правдиві:
- Перша умова Math.sqrt(...) > 1.4 (потрясіння);
- Друга умова getOrientation().pitch < -45 (нахил вперед).
speak("Shake and Pitch", false): Робот скаже "Shake and Pitch", якщо виконуються обидві умови.

Оператори If Then Else виконують код, що міститься в "if" (якщо умова виконується), або виконують код у "else" (інакше), якщо умова не виконана.
if (condition) {
// код виконується, якщо умова істинна
} else {
// код виконується, якщо умова хибна
{
}Давайте побудуємо на основі попереднього прикладу if then ще й умову "else", яка встановлює світло на червоне, коли умова не виконується, але світло все одно стає зеленим, коли ви потрясаєте робота:
async function startProgram() {
setStabilization(false); // вимкнення стабілізації
setBackLed(255); // увімкнення заднього світла
while (true) { // нескінченний цикл
if ((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4)) { // якщо робот трясеться
await speak("Shake", false); // сказати "Shake"
setMainLed({ r: 0, g: 255, b: 0 }); // встановити світло на зелене
await delay(1); // затримка 1 секунда
} else { // якщо умова не виконана
setMainLed({ r: 255, g: 0, b: 0 }); // встановити світло на червоне
}
await delay(0.025); // затримка для повторної перевірки умови
}
}
Для створення більше ніж 2 варіантів результату ви можете вкладати кілька операторів if then else.
Наприклад, давайте створимо програму з трьома умовами:
- Світло червоне на місці;
- Світло зелене при тремтінні робота;
- Світло синє, коли робот нахиляється вперед:
async function startProgram() {
setStabilization(false); // вимкнення стабілізації
setBackLed(255); // увімкнення заднього світла
while (true) { // нескінченний цикл
if ((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4)) { // якщо робот трясеться
await speak("Shake", false); // сказати "Shake"
setMainLed({ r: 0, g: 255, b: 0 }); // встановити світло на зелене
await delay(1); // затримка 1 секунда
} else {
if ((getOrientation().pitch < -45)) { // якщо робот нахиляється вперед
await speak("Pitch", false); // сказати "Pitch"
setMainLed({ r: 0, g: 0, b: 255 }); // встановити світло на синє
await delay(1); // затримка 1 секунда
} else {
setMainLed({ r: 255, g: 0, b: 0 }); // встановити світло на червоне
}
}
await delay(0.025); // затримка для повторної перевірки умови
}
}If Then Else дозволяє виконувати різний код залежно від того, чи виконується умова.
У прикладі світло змінюється на зелений, якщо робот тремтить, на синій, якщо нахиляється вперед, і на червоний, коли умови не виконуються.

Команда exitProgram() завершує виконання програми, що є еквівалентом натискання кнопки "Stop" (Стоп).
Наприклад, якщо ви хочете, щоб програма завершилася після одного натискання, використовуйте:
async function startProgram() {
setStabilization(false); // вимкнення стабілізації
setBackLed(255); // увімкнення заднього світла
while (true) { // нескінченний цикл
if ((Math.sqrt((getAcceleration().x ** 2) + (getAcceleration().y ** 2) + (getAcceleration().z ** 2)) > 1.4)) { // якщо робот потрясти
await speak("Shake", false); // сказати "Shake"
setMainLed({ r: 0, g: 255, b: 0 }); // встановити світло на зелене
await delay(1); // затримка 1 секунда
await speak("Exit Program", true); // сказати "Exit Program"
exitProgram(); // завершити програму
}
await delay(0.025); // затримка для перевірки умови
}
}exitProgram() зупиняє виконання програми, тобто аналогічно натисканню кнопки "Stop" (Стоп).
У прикладі програма завершується після того, як робот почне тремтіти і спрацює відповідна умова.
Команда await() (Чекати) вимагає завершення команд, що базуються на часі, перед тим, як програма продовжить виконання наступної команди.
Це автоматично додається до команд, що вимагають часу для виконання, таких як await roll (Чекати рух) та await delay (Чекати затримку), де вказано час (тривалість).
async function startProgram() {
await roll(90, 100, 2); // чекає завершення руху на 2 секунди перед переходом до наступної команди
}await (Чекати) застосовується до асинхронних команд, де потрібно почекати, поки одна команда не завершиться, перш ніж виконати наступну.
У прикладі ви чекаєте завершення руху робота (roll) на 2 секунди перед тим, як програма продовжить виконання наступних команд.
Команда return (Повернути) припиняє виконання функції та повертає керування до викликаючої функції.
Оператор return (Повернути) також може повернути значення до викликаючої функції. Ця команда недоступна у блоковому редакторі.
У текстовому редакторі ви можете використовувати return (Повернути) для створення функцій, які виконують завдання, що можуть бути повторно використані в коді кілька разів, але ці функції не можуть бути асинхронними або мати асинхронні функції всередині:
roundToTenths = function(decimalNum) { // <-- Зверніть увагу, що ми не оголосили цю функцію як 'async'
// В цій функції немає асинхронних функцій!
var roundedNum = Math.round(decimalNum * 10.0) / 10.0;
return roundedNum; // Повертаємо округлене значення
};
async function startProgram() {
speak("Pi is approximately " + roundToTenths(Math.PI)); // Викликаємо функцію roundToTenths
await delay(3); // Чекаємо 3 секунди
exitProgram(); // Завершуємо програму
}return (Повернути) припиняє виконання функції і повертає результат або значення.
У прикладі roundToTenths округлює число до десяткових знаків, і значення повертається за допомогою return (Повернути).
