mirror of https://github.com/flutter/pinball.git
refactor: moved gravity logic to `BallGravitatingBehavior` (#314)
parent
c67db0e55c
commit
01dc3f387a
@ -0,0 +1,35 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:pinball_flame/pinball_flame.dart';
|
||||
|
||||
/// Scales the ball's gravity according to its position on the board.
|
||||
class BallGravitatingBehavior extends Component
|
||||
with ParentIsA<Ball>, HasGameRef<Forge2DGame> {
|
||||
@override
|
||||
void update(double dt) {
|
||||
super.update(dt);
|
||||
final defaultGravity = gameRef.world.gravity.y;
|
||||
|
||||
final maxXDeviationFromCenter = BoardDimensions.bounds.width / 2;
|
||||
const maxXGravityPercentage =
|
||||
(1 - BoardDimensions.perspectiveShrinkFactor) / 2;
|
||||
final xDeviationFromCenter = parent.body.position.x;
|
||||
|
||||
final positionalXForce = ((xDeviationFromCenter / maxXDeviationFromCenter) *
|
||||
maxXGravityPercentage) *
|
||||
defaultGravity;
|
||||
final positionalYForce = math.sqrt(
|
||||
math.pow(defaultGravity, 2) - math.pow(positionalXForce, 2),
|
||||
);
|
||||
|
||||
final gravityOverride = parent.body.gravityOverride;
|
||||
if (gravityOverride != null) {
|
||||
gravityOverride.setValues(positionalXForce, positionalYForce);
|
||||
} else {
|
||||
parent.body.gravityOverride = Vector2(positionalXForce, positionalYForce);
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
export 'ball_gravitating_behavior.dart';
|
||||
export 'ball_scaling_behavior.dart';
|
||||
|
@ -0,0 +1,63 @@
|
||||
// ignore_for_file: cascade_invocations
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame_test/flame_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:pinball_components/src/components/ball/behaviors/behaviors.dart';
|
||||
|
||||
import '../../../../helpers/helpers.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
final asset = Assets.images.ball.ball.keyName;
|
||||
final flameTester = FlameTester(() => TestGame([asset]));
|
||||
|
||||
group('BallGravitatingBehavior', () {
|
||||
const baseColor = Color(0xFFFFFFFF);
|
||||
test('can be instantiated', () {
|
||||
expect(
|
||||
BallGravitatingBehavior(),
|
||||
isA<BallGravitatingBehavior>(),
|
||||
);
|
||||
});
|
||||
|
||||
flameTester.test('can be loaded', (game) async {
|
||||
final ball = Ball.test(baseColor: baseColor);
|
||||
final behavior = BallGravitatingBehavior();
|
||||
await ball.add(behavior);
|
||||
await game.ensureAdd(ball);
|
||||
expect(
|
||||
ball.firstChild<BallGravitatingBehavior>(),
|
||||
equals(behavior),
|
||||
);
|
||||
});
|
||||
|
||||
flameTester.test(
|
||||
"overrides the body's horizontal gravity symmetrically",
|
||||
(game) async {
|
||||
final ball1 = Ball.test(baseColor: baseColor)
|
||||
..initialPosition = Vector2(10, 0);
|
||||
await ball1.add(BallGravitatingBehavior());
|
||||
|
||||
final ball2 = Ball.test(baseColor: baseColor)
|
||||
..initialPosition = Vector2(-10, 0);
|
||||
await ball2.add(BallGravitatingBehavior());
|
||||
|
||||
await game.ensureAddAll([ball1, ball2]);
|
||||
game.update(1);
|
||||
|
||||
expect(
|
||||
ball1.body.gravityOverride!.x,
|
||||
equals(-ball2.body.gravityOverride!.x),
|
||||
);
|
||||
expect(
|
||||
ball1.body.gravityOverride!.y,
|
||||
equals(ball2.body.gravityOverride!.y),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
Loading…
Reference in new issue