С чего начать
Что это и зачем
StepType.Script
Блок «JS код» выполняет произвольный код на JavaScript. Он нужен там, где кубиков становится слишком много: сложные условия, арифметика, работа с переменными, свои циклы. Три строки кода часто короче десятка блоков.
Идея — смешивать: наглядные действия (ждать, кликать, скроллить) оставляйте кубиками, а ветвистую логику пишите кодом. Внутри кода доступ к автоматизации даёт объект ctx — через него ищут картинки, кликают, читают и меняют переменные.
Как добавить блок
- Откройте визуальный редактор сценария.
- В палитре слева найдите категорию «Переменные» → блок «JS код».
- Перетащите его на холст и соедините со Start (и с остальным графом).
- Двойной клик по узлу открывает редактор кода.
У узла один вход и один выход Out — он ведёт себя как обычный шаг.
Редактор кода
Окно редактора собрано под удобное написание кода:
Кнопка «Проверить» ещё и вытаскивает из кода переменные, объявленные через ctx.setVar("имя", …), и показывает их в списке «Переменные сценария».
Объект ctx
Переменные
Общие для всего сценария: их видят и кубики, и другие JS-узлы.
Поиск картинок
Картинка задаётся ключом из реестра проекта — так же, как в кубиках.
Действия
Результат поиска
Заполняются после findImage/waitImage и блоков поиска.
Окна и управление
Прочее
Примеры и нюансы
Клики и поиск
Найти картинку и кликнуть:
if (ctx.findImage("кнопка")) { ctx.clickFound(); }
Ждать до 10 секунд, кликнуть, иначе остановиться:
// ждём кнопку, кликаем со случайной задержкой if (ctx.waitImage("кнопка", 10)) { ctx.clickFound(); ctx.delay(500 + rand()*300); } else { ctx.log("кнопка не появилась"); ctx.stop(); }
Несколько вариантов по очереди (что найдётся первым):
if (ctx.findImage("согласиться")) { ctx.clickFound(); } else if (ctx.findImage("закрыть")) { ctx.clickFound(); } else { ctx.log("ни одного окна нет"); }
Найти, кликнуть и напечатать текст (например, в поле ввода):
if (ctx.findImage("поле_поиска")) { ctx.clickFound(); ctx.delay(300); ctx.typeText("золотой меч"); ctx.key("Enter"); }
Сложное условие (то, ради чего и нужен код):
var hp = ctx.getNum("hp"); var mana = ctx.getNum("mana"); if (hp < 30 && mana > 50) { ctx.findImage("хил") && ctx.clickFound(); } else { ctx.findImage("атака") && ctx.clickFound(); }
Циклы и повторы
Кликать, пока картинка на экране (собрать все награды):
// жмём «собрать», пока кнопка видна — но не более 20 раз var n = 0; while (ctx.findImage("собрать") && n < 20) { ctx.clickFound(); ctx.delay(400); n++; } ctx.log("собрано раз: " + n);
Повторить действие N раз:
for (var i = 1; i <= 5; i++) { ctx.key("Space"); ctx.delay(300); ctx.log("выстрел " + i); }
Задержки и человекоподобность
Случайная задержка (чтобы клики не были «по метроному»):
ctx.delay(800 + rand()*600); // пауза 0.8–1.4 сек
Клик с небольшим разбросом вокруг точки:
// не точно в центр, а ±5 пикселей var x = ctx.foundX + Math.round(rand()*10 - 5); var y = ctx.foundY + Math.round(rand()*10 - 5); ctx.click(x, y);
Иногда пауза подольше (имитация «отвлёкся»):
if (rand() < 0.1) { // в 10% случаев ctx.log("длинная пауза"); ctx.delay(3000 + rand()*2000); }
Переменные и флаги
Счётчик и остановка по порогу:
ctx.setVar("кликов", ctx.getNum("кликов") + 1); if (ctx.getNum("кликов") >= 10) { ctx.log("хватит"); ctx.stop(); }
Флаг «первый запуск» (инициализация один раз):
if (!ctx.has("инициализирован")) { ctx.setVar("инициализирован", 1); ctx.setVar("золото", 0); ctx.log("первый запуск — обнулил счётчики"); }
Накопление и цель:
ctx.setVar("золото", ctx.getNum("золото") + 25); if (ctx.getNum("золото") >= 1000) { ctx.log("цель достигнута: " + ctx.getNum("золото")); ctx.stop(); }
Связка с кубиками
Самый правильный паттерн (особенно для параллельного режима): ждать картинку — родным блоком «Ждать», а сразу после него поставить короткий JS-узел с логикой.
После блока «Ждать "враг"» — быстрая логика:
// картинка уже найдена блоком «Ждать», координаты в foundX/foundY ctx.setVar("врагов", ctx.getNum("врагов") + 1); ctx.clickFound(); if (ctx.getNum("врагов") % 5 == 0) { ctx.key("r"); // перезарядка каждые 5 врагов }
Мультиоконный режим
Блок «JS код» работает в обоих режимах, и действия корректно попадают в нужное окно. Но есть разница:
Правило для параллельного режима: скрипт должен быть коротким и без долгих ожиданий.
- Можно: findImage (мгновенная проверка), логика, setVar, один clickFound.
- Избегать: waitImage, длинный delay, длинные циклы — они замораживают соседние окна.
- Как надо: ожидание — родным блоком «Ждать», а скрипт ставить после него только для быстрой логики.