Flutter Flame转盘平滑旋转与定时精准停止的实现难题
Flutter转盘平滑旋转与精准停止优化问题
我在Flutter应用中实现了转盘功能,目标是让转盘平滑旋转并在指定时长内精准停在预设位置,但目前无法确保转盘在规定时间内准确停在目标切片上。
具体问题如下:
- 平滑旋转:难以保持旋转过程中角速度稳定及减速平滑;
- 精准停止:虽设置了最大速度检测、角度校验等停止条件,但停止位置常超出目标或耗时过长。
以下是当前用于转盘旋转与停止逻辑的代码片段:
class WheelUpdater extends PositionComponent { final SpinTheWheel spinTheWheelModel; final VoidCallback onSpinStop; late double _angularVelocity; late bool _spinning; late bool _isMaxSpeedReached; late int _sliceCount; late double _sliceAngle; late AudioService _audioService; late double _elapsedTime; late double stopAngle; late int totalDuration; WheelUpdater({ required this.spinTheWheelModel, required this.onSpinStop, }) : assert( spinTheWheelModel.stopPosition <= spinTheWheelModel.slices.length, 'Stop position must be less than or equal to the number of slices'), assert(spinTheWheelModel.duration >= 0, 'duration must be greater than or equal to 0') { _sliceCount = spinTheWheelModel.slices.length; _sliceAngle = 2 * pi / _sliceCount; _angularVelocity = 0; _spinning = false; _isMaxSpeedReached = false; _audioService = AudioServiceImp(); totalDuration = spinTheWheelModel.duration; _elapsedTime = 0; } @override FutureOr<void> onLoad() async { await _audioService.loadAll([Song.tick, Song.winner]); return super.onLoad(); } @override void onRemove() async { await _audioService.clearAll(); super.onRemove(); } @override void update(double dt) { super.update(dt); double previousAngle = angle; if (_spinning) { _elapsedTime += dt * 1000; angle += _angularVelocity * dt; double maxSpeedTime = totalDuration * 0.5; if (_elapsedTime >= maxSpeedTime && !_isMaxSpeedReached) { _isMaxSpeedReached = true; } if (_isMaxSpeedReached && _angularVelocity >= 1) { _angularVelocity -= dt; } else { _angularVelocity += dt; } if (angle >= 2 * pi) { angle = (2 * pi) - angle; } int previousSliceIndex = (previousAngle / _sliceAngle).floor(); int currentSliceIndex = (angle / _sliceAngle).floor(); if (previousSliceIndex != currentSliceIndex) { _playTickSound(); } if (isStoppingConditionReached) { _spinning = false; angle = stopAngle + 0.3; _winnerDeclared(); onSpinStop(); } } } void startSpin() { if (!_spinning) { _spinning = true; _angularVelocity = 0; _isMaxSpeedReached = false; _elapsedTime = 0; } } bool get isStoppingConditionReached { if (spinTheWheelModel.stopPosition == 0) { stopAngle = 0; } else { stopAngle = _sliceAngle * (_sliceCount - spinTheWheelModel.stopPosition); } double offsetAngle = _sliceAngle * 0.4; return _isMaxSpeedReached && _angularVelocity <= 1 && angle >= (stopAngle + offsetAngle) && angle <= (stopAngle + _sliceAngle - offsetAngle); } /// Plays the tick sound when the wheel rotates to a new slice. Future<void> _playTickSound() async { await _audioService.play(Song.tick); } Future<void> _winnerDeclared() async { if (spinTheWheelModel.showHapticFeedback) { await HapticFeedback.vibrate(); } /// Plays the winner sound when the spinning stops at the designated position. await _audioService.play(Song.winner); } }
我已尝试调整角速度、停止条件等参数,但仍未达到预期效果。恳请协助优化逻辑或提供合适公式,以实现转盘的平滑旋转与定时精准停止,感谢您的指导!
内容的提问来源于stack exchange,提问作者Tushar Nikam
相关产品推荐
相关产品推荐

