Files
flame/packages/flame/test/components/mixins/has_time_scale_test.dart
DevKage d2a8fe01fa feat: Add HasTimeScale mixin (#2431)
This PR adds a new mixin on Component. When attached to a component, it allows scaling the delta time of that component as well as all its children by a non-negative factor. The idea is to allows slowing down or speeding up the gameplay by change the scaling factor.

Note: This approach works only for framerate independent game logic. Code in update() that is not dependent on delta time will remain unaffected by time scale.
2023-03-27 22:01:42 +02:00

100 lines
2.8 KiB
Dart

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame_test/flame_test.dart';
import 'package:test/test.dart';
void main() {
group('HasTimeScale', () {
testWithGame<_GameWithTimeScale>(
'delta time scales correctly',
_GameWithTimeScale.new,
(game) async {
final component = _MovingComponent();
await game.add(component);
await game.ready();
const stepTime = 10.0;
var distance = 0.0;
final offset = stepTime * component.speed;
game.timeScale = 0.5;
distance = component.x;
game.update(stepTime);
expect(component.x, distance + game.timeScale * offset);
game.timeScale = 1.0;
distance = component.x;
game.update(stepTime);
expect(component.x, distance + game.timeScale * offset);
game.timeScale = 1.5;
distance = component.x;
game.update(stepTime);
expect(component.x, distance + game.timeScale * offset);
game.timeScale = 2.0;
distance = component.x;
game.update(stepTime);
expect(component.x, distance + game.timeScale * offset);
},
);
testWithGame(
'cascading time scale',
_GameWithTimeScale.new,
(game) async {
final component1 = _ComponentWithTimeScale();
final component2 = _MovingComponent();
await component1.add(component2);
await game.add(component1);
await game.ready();
const stepTime = 10.0;
var distance = 0.0;
final offset = stepTime * component2.speed;
game.timeScale = 0.5;
component1.timeScale = 0.5;
distance = component2.x;
game.update(stepTime);
expect(
component2.x,
distance + game.timeScale * component1.timeScale * offset,
);
game.timeScale = 1.0;
distance = component2.x;
game.update(stepTime);
expect(
component2.x,
distance + game.timeScale * component1.timeScale * offset,
);
component1.timeScale = 1.5;
distance = component2.x;
game.update(stepTime);
expect(
component2.x,
distance + game.timeScale * component1.timeScale * offset,
);
game.timeScale = 2.0;
distance = component2.x;
game.update(stepTime);
expect(
component2.x,
distance + game.timeScale * component1.timeScale * offset,
);
},
);
});
}
class _GameWithTimeScale extends FlameGame with HasTimeScale {}
class _ComponentWithTimeScale extends Component with HasTimeScale {}
class _MovingComponent extends PositionComponent {
final speed = 1.0;
@override
void update(double dt) => position.setValues(position.x + speed * dt, 0);
}