Вступление

В этой статье разберём, как сделать рулетку наград в Construct 3. Такая механика хорошо подходит для колеса удачи, ежедневных наград, бонусов за вход в игру, сундуков, кейсов или простого reward-экрана, где игрок нажимает кнопку, рулетка красиво крутится и в конце показывает выпавший приз.

На первый взгляд всё кажется простым: взяли колесо, добавили вращение, случайно остановили — готово. Но если сделать механику “на глаз”, быстро появляются проблемы: рулетка может останавливаться резко, награда может не совпадать с сектором, а сам рандом будет выглядеть подозрительно.

Поэтому мы сделаем более правильный вариант: сначала выбираем случайную награду, затем считаем угол остановки, добавляем несколько полных оборотов, небольшой разброс внутри сектора и плавное замедление. В итоге рулетка выглядит живо, но результат всегда совпадает с тем сектором, который выпал в логике. Такую механику можно использовать для:

  • daily reward;
  • колеса удачи;
  • внутриигровых бонусов;
  • кейсов и сундуков;
  • случайных наград после уровня;
  • мини-ивентов и промо-механик.

Какие объекты нужны в проекте

Для базовой версии понадобится несколько объектов:

  • roulette_wheel — сама рулетка, которая будет вращаться.
  • roulette_arrow — стрелка сверху. Она остаётся на месте и показывает выпавший сектор.
  • btn_claim_reward — кнопка запуска рулетки.
  • Mouse — нужен для клика по кнопке.
  • Browser — используем для тестового alert после остановки.

Главный объект здесь — roulette_wheel. Именно он будет менять угол. еред событиями обязательно проверьте у рулетки Origin point. Он должен быть строго в центре круга. Если origin будет смещён, рулетка начнёт вращаться криво, и формулы тут уже не спасут. Это тот случай, когда проблема не в математике, а в маленькой точке, которая решила жить своей жизнью.

Главная идея механики

Есть простой, но не самый удобный подход: запустить рулетку со случайной скоростью, постепенно замедлять её, а потом пытаться понять, где она остановилась. В теории звучит нормально, но на практике появляются лишние сложности: нужно высчитывать сектор по углу, учитывать погрешности, направление вращения и границы между секторами. Мы сделаем иначе.

Сначала выбираем случайный сектор, потом считаем финальный угол и уже после этого красиво докручиваем колесо до нужной позиции. То есть результат определяется заранее, а вращение просто показывает его игроку. Это не “подкрутка”, а нормальная игровая логика. Во многих играх сначала считается результат действия, а потом проигрывается анимация. Например, игра уже знает, какую награду получил игрок, но показывает это через красивый эффект, сундук или рулетку.

Переменные для рулетки

Для простой версии используем 5 глобальных переменных:

Переменная Для чего нужна
RewardIndex Хранит номер сектора, который выпал
StartAngle Запоминает угол рулетки в момент старта
EndAngle Хранит финальный угол, где рулетка должна остановиться
SpinTime Считает, сколько времени рулетка уже крутится
SpinDuration Задаёт общую длительность вращения

Что они означают:

  • RewardIndex — номер сектора, который выпал.
  • StartAngle — угол рулетки в момент старта.
  • EndAngle — угол, на котором рулетка должна остановиться.
  • SpinTime — сколько времени рулетка уже крутится.
  • SpinDuration — сколько всего длится вращение. Отдельную переменную IsSpinning мы не создаём. Вместо неё используем SpinDuration. Если SpinDuration = 0, рулетка не крутится. Если SpinDuration > 0, значит вращение сейчас активно. Так код становится чуть проще и чище.

Сектора и награды

В нашем примере у рулетки 8 секторов. Один сектор занимает 45 градусов, потому что:

360 / 8 = 45

Награды идут в таком порядке:

100, 10, 15, 20, 25, 30, 40, 50

Связь простая:

  • RewardIndex 0 → 100 coins
  • RewardIndex 1 → 10 coins
  • RewardIndex 2 → 15 coins
  • RewardIndex 3 → 20 coins
  • RewardIndex 4 → 25 coins
  • RewardIndex 5 → 30 coins
  • RewardIndex 6 → 40 coins
  • RewardIndex 7 → 50 coins

❗Важно, чтобы порядок наград в коде совпадал с расположением секторов на самой рулетке. Если потом поменяете картинку рулетки, но не обновите список наград, визуально будет выпадать одно, а в alert будет показываться другое.

Запуск вращения по кнопке

Создаём событие клика по кнопке btn_claim_reward. Условия: Второе условие не даёт запустить рулетку повторно, пока она уже крутится. Дальше задаём стартовые значения: Разберём по смыслу. SpinTime = 0 начинает вращение с нуля. random(3, 4.2) делает длительность немного разной. Иногда рулетка крутится быстрее, иногда дольше, поэтому анимация не выглядит одинаковой. floor(random(0, 8)) выбирает случайный сектор от 0 до 7. Самая большая формула считает финальный угол. В ней есть три важные части. Полные обороты:

floor(random(4, 8)) * 360

Рулетка делает от 4 до 7 полных кругов, поэтому вращение выглядит нормально, а не как лёгкий поворот на пару градусов. Небольшой разброс внутри сектора:

random(-10, 10)

Без этого рулетка всегда останавливалась бы почти идеально по центру сектора. Работало бы, но выглядело бы слишком механически. Коррекция угла:

((360 - RewardIndex * 45 + random(-10, 10)) - (StartAngle % 360) + 360) % 360

Эта часть помогает докрутить рулетку именно до выбранного сектора, учитывая текущий угол колеса.

Плавное вращение через Every tick

После запуска рулетки нужно каждый кадр обновлять её угол. Создаём событие: Внутри действием увеличиваем время вращения:

dt делает анимацию стабильной на разных устройствах, а min() не даёт SpinTime стать больше, чем SpinDuration. Теперь меняем угол рулетки:

lerp() плавно двигает значение от одного числа к другому. В нашем случае — от StartAngle к EndAngle. Обычный прогресс дал бы равномерное вращение. А нам нужно, чтобы рулетка сначала крутилась быстро, а потом плавно замедлялась. За это отвечает формула:

1 - (1 - progress) * (1 - progress) * (1 - progress)

Она создаёт эффект ease out: быстрый старт и мягкая остановка. Без резкого торможения, будто рулетку поймали за край рукой.

Остановка рулетки и получение награды

Теперь нужно понять, когда вращение закончилось. Создаём событие: Когда время дошло до конца, выполняем действия: Первое действие фиксирует рулетку точно на финальном угле. Это убирает возможные маленькие погрешности. SpinDuration = 0 останавливает механику и снова разрешает нажимать кнопку. Для теста используем Browser Alert. Награду берём через tokenat():

tokenat("100,10,15,20,25,30,40,50", RewardIndex, ",")

Например, если RewardIndex = 2, из списка возьмётся третье значение — 15. В финальной версии alert лучше заменить на красивое popup-окно: затемнение фона, иконка монет, текст “Вы получили 50 монет” и кнопка “Забрать”.

Почему этот подход удобнее

Можно было бы сделать рулетку через случайную скорость и постепенное замедление. Но тогда пришлось бы после остановки вычислять сектор по углу, следить за границами и ловить мелкие ошибки. В нашем варианте всё проще:

  • награда выбирается сразу;
  • сектор известен заранее;
  • финальный угол считается точно;
  • анимация выглядит случайной за счёт оборотов, длительности и разброса;
  • после остановки мы точно знаем, что получил игрок. Поэтому такой способ хорошо подходит для игровых механик, где важна и красивая анимация, и понятная логика.

Особенно интересно связать рулетку с системой ежедневных наград. Например, игрок заходит один раз в день, нажимает кнопку, крутит рулетку и получает бонус. Если он заходит несколько дней подряд, награда увеличивается. Если пропускает день — серия сбрасывается. Так обычная рулетка превращается в полноценную daily reward system.

Заключение

Мы сделали механику рулетки в Construct 3, которая не просто вращается, а работает по нормальной игровой логике. Главный принцип простой: сначала выбираем награду, потом считаем финальный угол, затем красиво докручиваем рулетку до нужного сектора и после остановки выдаём результат. Такой подход удобен тем, что визуальная часть и логика не спорят друг с другом. Рулетка выглядит случайной, но результат всегда корректно совпадает с выбранным сектором.

Эту механику можно использовать для колеса удачи, daily reward, кейсов, сундуков и бонусных систем. А дальше её можно развивать: добавить Firebase, сохранение прогресса, серию входов, редкие призы и красивое окно получения награды. Если хотите быстрее разобраться в механике, можно скачать готовый исходник Construct 3 и открыть проект у себя. Внутри уже настроены рулетка, плавное вращение, случайный выбор сектора, остановка на нужной награде и тестовое уведомление с результатом.