Реализация Spin-the-Wheel (колесо фортуны) в мобильном приложении
Колесо фортуны — геймификационный элемент, который может как увлечь пользователя, так и разочаровать сломанной механикой. Мы сталкивались с проектами, где простая анимация вращения выглядела неестественно, а победный сектор определялся банальным таймером без учёта физики. Разрабатывая колесо под ключ, мы опираемся на точную физическую модель, дискретные шаги остановки и визуальный фидбек, который превращает момент приза в мини-событие. Ниже — технические детали, проверенные на 40+ геймификационных проектах за 5 лет опыта.
Физика вращения: как добиться реализма?
Колесо должно имитировать настоящий физический объект с инерцией и трением. Простое «крутить N секунд и остановиться» не работает — нужно экспоненциальное замедление. Базовая модель на iOS выглядит так:
// Угловая скорость уменьшается каждый кадр
angularVelocity *= decelerationFactor // 0.96–0.98 для медленного замедления
// CADisplayLink обновляет угол каждый кадр
currentAngle += angularVelocity * dt
wheelLayer.transform = CATransform3DMakeRotation(currentAngle, 0, 0, 1)
// Остановка при достижении минимальной скорости
if abs(angularVelocity) < 0.01 { stopAndSnap() }
Параметр decelerationFactor определяет ощущение: 0.99 — тяжёлый барабан с долгим вращением, 0.95 — лёгкое и резкое. Мы подбираем его под концепцию бренда. Для наглядности сравним варианты:
decelerationFactor |
Поведение | Время до остановки (с) | Типичное применение |
|---|---|---|---|
| 0.99 | Медленное, плавное | 5–7 | Премиум-бренды, крупные призы |
| 0.97 | Среднее | 3–4 | Универсальное |
| 0.95 | Быстрое, резкое | 1–2 | Бонусы, ежедневные награды |
Почему точная остановка на нужном секторе — не обман?
Честная рандомизация и точная остановка на предопределённом секторе совместимы. Алгоритм:
- Победный сектор определяется до старта — сервером или клиентским seed.
- Целевой угол:
targetAngle = sectorMidpoint + randomOffset(±halfSectorAngle). -
decelerationFactorкорректируется так, чтобы колесо завершило целое число оборотов и попало вtargetAngle.
Формула для вычисления:
let totalRotation = currentAngle + (Double(minFullRotations) * 2 * .pi) + targetAngle
decelerationFactor = 1 - initialVelocity / totalRotation
Это скрывает предопределённость — вращение выглядит естественно, а остановка приходится на нужный сектор.
Snap-анимация и визуальный фидбек: когда победа ощущается реальной
В конце вращения добавляем «отскок» через CASpringAnimation:
let snapAnimation = CASpringAnimation(keyPath: "transform.rotation.z")
snapAnimation.fromValue = currentAngle
snapAnimation.toValue = snappedAngle
snapAnimation.stiffness = 200
snapAnimation.damping = 15
snapAnimation.initialVelocity = angularVelocity
После остановки запускаем:
-
Haptic feedback:
UINotificationFeedbackGeneratorна iOS,VibrationEffectна Android. - Lottie-конфетти: overlay поверх колеса.
-
Подсветка сектора:
CALayerс анимациейshadowOpacity(три мигания).
Реализация по платформам: что входит в работу
Для каждой платформы используем нативные API:
- iOS:
CADisplayLink+CALayerилиUIView. Сектора —CAShapeLayer/UIBezierPath. - Android:
ValueAnimator+ кастомныйTimeInterpolator(логарифм).Canvas.drawArc. - Flutter:
AnimationController+ кастомныйSimulation(наследникSpringSimulation).CustomPainter. - React Native:
Animated.Value+react-native-svgили готовый пакет.
Отметим: что входит в наш проект:
- Физическая модель с регулируемым замедлением
- Логика остановки на заданном секторе (с серверной верификацией)
- Визуальный фидбек (snap, haptic, конфетти)
- Интеграция с системой наград (in-app purchase, аналитика)
- Тестирование на 10+ устройствах с разными версиями ОС
- Документация по API и кастомизации
Как мы работаем: этапы и сроки
- Анализ — обсуждаем механику, частоту выпадения призов, бренд-стиль. Оцениваем сложность интеграции с вашим бэкендом.
- Проектирование — выбираем платформу, готовим прототип физики в изоляции.
- Реализация — пишем код, настраиваем decelerationFactor, тестируем остановку.
- Интеграция — подключаем логику призов, аналитику (Firebase, Amplitude), AB-тесты.
- Деплой — загружаем в App Store / Google Play, настраиваем push-уведомления (APNs/FCM) для напоминаний.
Сроки: от 2 до 5 дней в зависимости от сложности. Стоимость рассчитывается индивидуально после брифа. Получите консультацию — напишите нам с описанием проекта.
Типичные ошибки и как их избежать
- Слишком быстрая или медленная анимация — решается настройкой
decelerationFactorна этапе прототипирования. - Заметная предопределённость — избегаем фиксированного числа оборотов, используем случайный сдвиг в пределах сектора.
- Отсутствие обратной связи на старых устройствах — тестируем haptic и анимации на устройствах 3-летней давности.
- Проблемы с App Store Review — следяем, чтобы колесо не имитировало азартные игры (Section 4.2/5.1). Всегда используем честную рандомизацию с серверной проверкой.
Наш опыт более 5 лет разработки геймификации гарантирует, что колесо будет работать стабильно и соответствовать требованиям магазинов приложений. Свяжитесь, чтобы мы оценили ваш проект.
Интеграция с аналитикой и push-уведомлениями
Колесо фортуны — инструмент роста, который нужно правильно измерять. Мы настраиваем события: spin_started, spin_completed, prize_claimed, prize_dismissed. В Firebase Analytics или Amplitude это занимает 2–3 часа и даёт полную картину воронки вовлечённости.
A/B-тесты через Firebase Remote Config или Amplitude Experiment позволяют менять наборы призов, коэффициент замедления и частоту показа колеса без нового релиза приложения. Это быстрее, надёжнее и дешевле альтернативных подходов, требующих полного цикла публикации в App Store или Google Play.
Push-уведомления через APNs и FCM напоминают пользователям о ежедневной возможности прокрутить колесо. По данным наших клиентов, такие напоминания повышают DAU на 12–18% в течение первого месяца после запуска. Мы настраиваем шаблоны уведомлений и логику триггеров на стороне сервера, чтобы система работала автономно. Стоимость интеграции аналитики и push-уведомлений — от 50 000 до 150 000 ₽ в зависимости от сложности инфраструктуры.







