mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-01 01:18:38 +08:00 
			
		
		
		
	 ccee9a466b
			
		
	
	ccee9a466b
	
	
	
		
			
			* 👌 Use `Offset` type directly in `JoystickAction.update` calculations (#631) * Move files to src and comply with the dart package layout convention * Fixing widgets example Co-authored-by: Serge Matveenko <lig@countzero.co> Co-authored-by: Erick Zanardo <erickzanardoo@gmail.com>
		
			
				
	
	
		
			131 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flutter/animation.dart';
 | |
| import 'package:meta/meta.dart';
 | |
| 
 | |
| import '../extensions/vector2.dart';
 | |
| import 'effects.dart';
 | |
| 
 | |
| class Vector2Percentage {
 | |
|   final Vector2 v;
 | |
|   final Vector2 previous;
 | |
|   final double startAt;
 | |
|   final double endAt;
 | |
| 
 | |
|   Vector2Percentage(
 | |
|     this.v,
 | |
|     this.previous,
 | |
|     this.startAt,
 | |
|     this.endAt,
 | |
|   );
 | |
| }
 | |
| 
 | |
| class MoveEffect extends SimplePositionComponentEffect {
 | |
|   List<Vector2> path;
 | |
|   Vector2Percentage _currentSubPath;
 | |
|   List<Vector2Percentage> _percentagePath;
 | |
|   Vector2 _startPosition;
 | |
| 
 | |
|   /// Duration or speed needs to be defined
 | |
|   MoveEffect({
 | |
|     @required this.path,
 | |
|     double duration,
 | |
|     double speed,
 | |
|     Curve curve,
 | |
|     bool isInfinite = false,
 | |
|     bool isAlternating = false,
 | |
|     bool isRelative = false,
 | |
|     void Function() onComplete,
 | |
|   })  : assert(
 | |
|           (duration != null) ^ (speed != null),
 | |
|           "Either speed or duration necessary",
 | |
|         ),
 | |
|         super(
 | |
|           isInfinite,
 | |
|           isAlternating,
 | |
|           duration: duration,
 | |
|           speed: speed,
 | |
|           curve: curve,
 | |
|           isRelative: isRelative,
 | |
|           modifiesPosition: true,
 | |
|           onComplete: onComplete,
 | |
|         );
 | |
| 
 | |
|   @override
 | |
|   void initialize(component) {
 | |
|     super.initialize(component);
 | |
|     List<Vector2> _movePath;
 | |
|     _startPosition = component.position.clone();
 | |
|     // With relative here we mean that any vector in the list is relative
 | |
|     // to the previous vector in the list, except the first one which is
 | |
|     // relative to the start position of the component.
 | |
|     if (isRelative) {
 | |
|       Vector2 lastPosition = _startPosition;
 | |
|       _movePath = [];
 | |
|       for (Vector2 v in path) {
 | |
|         final nextPosition = v + lastPosition;
 | |
|         _movePath.add(nextPosition);
 | |
|         lastPosition = nextPosition;
 | |
|       }
 | |
|     } else {
 | |
|       _movePath = path;
 | |
|     }
 | |
|     endPosition = isAlternating ? _startPosition : _movePath.last;
 | |
| 
 | |
|     double pathLength = 0;
 | |
|     Vector2 lastPosition = _startPosition;
 | |
|     for (Vector2 v in _movePath) {
 | |
|       pathLength += v.distanceTo(lastPosition);
 | |
|       lastPosition = v;
 | |
|     }
 | |
| 
 | |
|     _percentagePath = <Vector2Percentage>[];
 | |
|     lastPosition = _startPosition;
 | |
|     for (Vector2 v in _movePath) {
 | |
|       final lengthToPrevious = lastPosition.distanceTo(v);
 | |
|       final lastEndAt =
 | |
|           _percentagePath.isNotEmpty ? _percentagePath.last.endAt : 0.0;
 | |
|       final endPercentage = lastEndAt + lengthToPrevious / pathLength;
 | |
|       _percentagePath.add(
 | |
|         Vector2Percentage(
 | |
|           v,
 | |
|           lastPosition,
 | |
|           lastEndAt,
 | |
|           _movePath.last == v ? 1.0 : endPercentage,
 | |
|         ),
 | |
|       );
 | |
|       lastPosition = v;
 | |
|     }
 | |
|     final double totalPathLength = isAlternating ? pathLength * 2 : pathLength;
 | |
|     speed ??= totalPathLength / duration;
 | |
| 
 | |
|     // `duration` is not null when speed is null
 | |
|     duration ??= totalPathLength / speed;
 | |
| 
 | |
|     // `speed` is always not null here already
 | |
|     peakTime = isAlternating ? duration / 2 : duration;
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void reset() {
 | |
|     super.reset();
 | |
|     if (_percentagePath?.isNotEmpty ?? false) {
 | |
|       _currentSubPath = _percentagePath.first;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void update(double dt) {
 | |
|     super.update(dt);
 | |
|     _currentSubPath ??= _percentagePath.first;
 | |
|     if (!curveDirection.isNegative && _currentSubPath.endAt < curveProgress ||
 | |
|         curveDirection.isNegative && _currentSubPath.startAt > curveProgress) {
 | |
|       _currentSubPath =
 | |
|           _percentagePath.firstWhere((v) => v.endAt >= curveProgress);
 | |
|     }
 | |
|     final double lastEndAt = _currentSubPath.startAt;
 | |
|     final double localPercentage =
 | |
|         (curveProgress - lastEndAt) / (_currentSubPath.endAt - lastEndAt);
 | |
|     component.position = _currentSubPath.previous +
 | |
|         ((_currentSubPath.v - _currentSubPath.previous) * localPercentage);
 | |
|   }
 | |
| }
 |