feat: adjusting game physics (#285)

* feat: adjusting game physics

* refactor: adjust physics and add tests

* fix: imports

* test: coverage

* feat: adjusted FlutterForestBonusBehavior rendering

Co-authored-by: alestiago <dev@alestiago.com>
pull/284/head
Allison Ryan 3 years ago committed by GitHub
parent 92b83dc892
commit 02edc75255
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -25,7 +25,7 @@ class FlutterForestBonusBehavior extends Component
gameRef gameRef
.read<GameBloc>() .read<GameBloc>()
.add(const BonusActivated(GameBonus.dashNest)); .add(const BonusActivated(GameBonus.dashNest));
gameRef.add( gameRef.firstChild<ZCanvasComponent>()!.add(
ControlledBall.bonus(characterTheme: gameRef.characterTheme) ControlledBall.bonus(characterTheme: gameRef.characterTheme)
..initialPosition = Vector2(17.2, -52.7), ..initialPosition = Vector2(17.2, -52.7),
); );

@ -35,7 +35,7 @@ class FlutterForest extends Component with ZIndex {
children: [ children: [
ScoringBehavior(points: 20000), ScoringBehavior(points: 20000),
], ],
)..initialPosition = Vector2(23.3, -46.75), )..initialPosition = Vector2(22.3, -46.75),
DashAnimatronic()..position = Vector2(20, -66), DashAnimatronic()..position = Vector2(20, -66),
FlutterForestBonusBehavior(), FlutterForestBonusBehavior(),
], ],

@ -12,8 +12,8 @@ class Launcher extends Component {
: super( : super(
children: [ children: [
LaunchRamp(), LaunchRamp(),
ControlledPlunger(compressionDistance: 10.5) ControlledPlunger(compressionDistance: 9.2)
..initialPosition = Vector2(41.1, 43), ..initialPosition = Vector2(41.2, 43.7),
RocketSpriteComponent()..position = Vector2(43, 62.3), RocketSpriteComponent()..position = Vector2(43, 62.3),
], ],
); );

@ -29,7 +29,7 @@ class SparkyScorch extends Component {
ScoringBehavior(points: 20000), ScoringBehavior(points: 20000),
], ],
)..initialPosition = Vector2(-3.3, -52.55), )..initialPosition = Vector2(-3.3, -52.55),
SparkyComputerSensor()..initialPosition = Vector2(-13, -49.8), SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9),
SparkyAnimatronic()..position = Vector2(-13.8, -58.2), SparkyAnimatronic()..position = Vector2(-13.8, -58.2),
SparkyComputer(), SparkyComputer(),
], ],
@ -53,7 +53,13 @@ class SparkyComputerSensor extends BodyComponent
@override @override
Body createBody() { Body createBody() {
final shape = CircleShape()..radius = 0.1; final shape = PolygonShape()
..setAsBox(
1,
0.1,
Vector2.zero(),
-0.18,
);
final fixtureDef = FixtureDef(shape, isSensor: true); final fixtureDef = FixtureDef(shape, isSensor: true);
final bodyDef = BodyDef( final bodyDef = BodyDef(
position: initialPosition, position: initialPosition,

@ -23,7 +23,7 @@ class PinballGame extends Forge2DGame
PinballGame({ PinballGame({
required this.characterTheme, required this.characterTheme,
required this.audio, required this.audio,
}) { }) : super(gravity: Vector2(0, 30)) {
images.prefix = ''; images.prefix = '';
controller = _GameBallsController(this); controller = _GameBallsController(this);
} }

@ -5,6 +5,7 @@ import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/android_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/android_bumper/behaviors/behaviors.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
export 'cubit/android_bumper_cubit.dart'; export 'cubit/android_bumper_cubit.dart';
@ -51,7 +52,10 @@ class AndroidBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.android.bumper.a.dimmed.keyName, dimmedAssetPath: Assets.images.android.bumper.a.dimmed.keyName,
spritePosition: Vector2(0, -0.1), spritePosition: Vector2(0, -0.1),
bloc: AndroidBumperCubit(), bloc: AndroidBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro android_bumper} /// {@macro android_bumper}
@ -64,7 +68,10 @@ class AndroidBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.android.bumper.b.dimmed.keyName, dimmedAssetPath: Assets.images.android.bumper.b.dimmed.keyName,
spritePosition: Vector2(0, -0.1), spritePosition: Vector2(0, -0.1),
bloc: AndroidBumperCubit(), bloc: AndroidBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro android_bumper} /// {@macro android_bumper}
@ -77,7 +84,10 @@ class AndroidBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.android.bumper.cow.dimmed.keyName, dimmedAssetPath: Assets.images.android.bumper.cow.dimmed.keyName,
spritePosition: Vector2(0, -0.68), spritePosition: Vector2(0, -0.68),
bloc: AndroidBumperCubit(), bloc: AndroidBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// Creates an [AndroidBumper] without any children. /// Creates an [AndroidBumper] without any children.
@ -113,15 +123,11 @@ class AndroidBumper extends BodyComponent with InitialPosition, ZIndex {
majorRadius: _majorRadius, majorRadius: _majorRadius,
minorRadius: _minorRadius, minorRadius: _minorRadius,
)..rotate(1.29); )..rotate(1.29);
final fixtureDef = FixtureDef(
shape,
restitution: 4,
);
final bodyDef = BodyDef( final bodyDef = BodyDef(
position: initialPosition, position: initialPosition,
); );
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixtureFromShape(shape);
} }
} }

@ -5,8 +5,7 @@ import 'dart:math' as math;
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/gen/assets.gen.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/pinball_components.dart' hide Assets;
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
class AndroidSpaceship extends Component { class AndroidSpaceship extends Component {
@ -141,14 +140,9 @@ class _AndroidHead extends BodyComponent with InitialPosition, Layered, ZIndex {
majorRadius: 3.1, majorRadius: 3.1,
minorRadius: 2, minorRadius: 2,
)..rotate(1.4); )..rotate(1.4);
// TODO(allisonryan0002): use bumping behavior.
final fixtureDef = FixtureDef(
shape,
restitution: 0.1,
);
final bodyDef = BodyDef(position: initialPosition); final bodyDef = BodyDef(position: initialPosition);
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixtureFromShape(shape);
} }
} }

@ -116,7 +116,7 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
math.pow(defaultGravity, 2) - math.pow(positionalXForce, 2), math.pow(defaultGravity, 2) - math.pow(positionalXForce, 2),
); );
body.gravityOverride = Vector2(-positionalXForce, positionalYForce); body.gravityOverride = Vector2(positionalXForce, positionalYForce);
} }
} }

@ -4,6 +4,7 @@ import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_components/src/components/dash_nest_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/dash_nest_bumper/behaviors/behaviors.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
@ -47,8 +48,11 @@ class DashNestBumper extends BodyComponent with InitialPosition {
activeAssetPath: Assets.images.dash.bumper.main.active.keyName, activeAssetPath: Assets.images.dash.bumper.main.active.keyName,
inactiveAssetPath: Assets.images.dash.bumper.main.inactive.keyName, inactiveAssetPath: Assets.images.dash.bumper.main.inactive.keyName,
spritePosition: Vector2(0, -0.3), spritePosition: Vector2(0, -0.3),
children: children,
bloc: DashNestBumperCubit(), bloc: DashNestBumperCubit(),
children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro dash_nest_bumper} /// {@macro dash_nest_bumper}
@ -60,8 +64,11 @@ class DashNestBumper extends BodyComponent with InitialPosition {
activeAssetPath: Assets.images.dash.bumper.a.active.keyName, activeAssetPath: Assets.images.dash.bumper.a.active.keyName,
inactiveAssetPath: Assets.images.dash.bumper.a.inactive.keyName, inactiveAssetPath: Assets.images.dash.bumper.a.inactive.keyName,
spritePosition: Vector2(0.35, -1.2), spritePosition: Vector2(0.35, -1.2),
children: children,
bloc: DashNestBumperCubit(), bloc: DashNestBumperCubit(),
children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro dash_nest_bumper} /// {@macro dash_nest_bumper}
@ -73,8 +80,11 @@ class DashNestBumper extends BodyComponent with InitialPosition {
activeAssetPath: Assets.images.dash.bumper.b.active.keyName, activeAssetPath: Assets.images.dash.bumper.b.active.keyName,
inactiveAssetPath: Assets.images.dash.bumper.b.inactive.keyName, inactiveAssetPath: Assets.images.dash.bumper.b.inactive.keyName,
spritePosition: Vector2(0.35, -1.2), spritePosition: Vector2(0.35, -1.2),
children: children,
bloc: DashNestBumperCubit(), bloc: DashNestBumperCubit(),
children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// Creates an [DashNestBumper] without any children. /// Creates an [DashNestBumper] without any children.
@ -108,13 +118,11 @@ class DashNestBumper extends BodyComponent with InitialPosition {
majorRadius: _majorRadius, majorRadius: _majorRadius,
minorRadius: _minorRadius, minorRadius: _minorRadius,
)..rotate(math.pi / 1.9); )..rotate(math.pi / 1.9);
final fixtureDef = FixtureDef(shape, restitution: 4);
final bodyDef = BodyDef( final bodyDef = BodyDef(
position: initialPosition, position: initialPosition,
userData: this,
); );
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixtureFromShape(shape);
} }
} }

@ -87,13 +87,7 @@ class _DinoTopWall extends BodyComponent with InitialPosition, ZIndex {
); );
final body = world.createBody(bodyDef); final body = world.createBody(bodyDef);
_createFixtureDefs().forEach( _createFixtureDefs().forEach(body.createFixture);
(fixture) => body.createFixture(
fixture
..restitution = 0.1
..friction = 0,
),
);
return body; return body;
} }

@ -24,7 +24,7 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition {
/// The speed required to move the [Flipper] to its highest position. /// The speed required to move the [Flipper] to its highest position.
/// ///
/// The higher the value, the faster the [Flipper] will move. /// The higher the value, the faster the [Flipper] will move.
static const double _speed = 60; static const double _speed = 90;
/// Whether the [Flipper] is on the left or right side of the board. /// Whether the [Flipper] is on the left or right side of the board.
/// ///

@ -36,7 +36,7 @@ class Kicker extends BodyComponent with InitialPosition {
}) : _side = side, }) : _side = side,
super( super(
children: [ children: [
BumpingBehavior(strength: 15)..applyTo(['bouncy_edge']), BumpingBehavior(strength: 20)..applyTo(['bouncy_edge']),
KickerBallContactBehavior()..applyTo(['bouncy_edge']), KickerBallContactBehavior()..applyTo(['bouncy_edge']),
KickerBlinkingBehavior(), KickerBlinkingBehavior(),
_KickerSpriteGroupComponent( _KickerSpriteGroupComponent(

@ -79,7 +79,7 @@ class Plunger extends BodyComponent with InitialPosition, Layered, ZIndex {
/// The velocity's magnitude depends on how far the [Plunger] has been pulled /// The velocity's magnitude depends on how far the [Plunger] has been pulled
/// from its original [initialPosition]. /// from its original [initialPosition].
void release() { void release() {
final velocity = (initialPosition.y - body.position.y) * 7; final velocity = (initialPosition.y - body.position.y) * 11;
body.linearVelocity = Vector2(0, velocity); body.linearVelocity = Vector2(0, velocity);
_spriteComponent.release(); _spriteComponent.release();
} }

@ -1,6 +1,7 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
/// {@template slingshots} /// {@template slingshots}
@ -28,7 +29,7 @@ class Slingshots extends Component with ZIndex {
} }
/// {@template slingshot} /// {@template slingshot}
/// Elastic bumper that bounces the [Ball] off of its straight sides. /// Elastic bumper that bounces the [Ball] off of its sides.
/// {@endtemplate} /// {@endtemplate}
class Slingshot extends BodyComponent with InitialPosition { class Slingshot extends BodyComponent with InitialPosition {
/// {@macro slingshot} /// {@macro slingshot}
@ -39,7 +40,10 @@ class Slingshot extends BodyComponent with InitialPosition {
}) : _length = length, }) : _length = length,
_angle = angle, _angle = angle,
super( super(
children: [_SlinghsotSpriteComponent(spritePath, angle: angle)], children: [
_SlinghsotSpriteComponent(spritePath, angle: angle),
BumpingBehavior(strength: 20),
],
renderBody: false, renderBody: false,
); );
@ -52,37 +56,27 @@ class Slingshot extends BodyComponent with InitialPosition {
final topCircleShape = CircleShape()..radius = circleRadius; final topCircleShape = CircleShape()..radius = circleRadius;
topCircleShape.position.setValues(0, -_length / 2); topCircleShape.position.setValues(0, -_length / 2);
final topCircleFixtureDef = FixtureDef(topCircleShape);
final bottomCircleShape = CircleShape()..radius = circleRadius; final bottomCircleShape = CircleShape()..radius = circleRadius;
bottomCircleShape.position.setValues(0, _length / 2); bottomCircleShape.position.setValues(0, _length / 2);
final bottomCircleFixtureDef = FixtureDef(bottomCircleShape);
final leftEdgeShape = EdgeShape() final leftEdgeShape = EdgeShape()
..set( ..set(
Vector2(circleRadius, _length / 2), Vector2(circleRadius, _length / 2),
Vector2(circleRadius, -_length / 2), Vector2(circleRadius, -_length / 2),
); );
final leftEdgeShapeFixtureDef = FixtureDef(
leftEdgeShape,
restitution: 5,
);
final rightEdgeShape = EdgeShape() final rightEdgeShape = EdgeShape()
..set( ..set(
Vector2(-circleRadius, _length / 2), Vector2(-circleRadius, _length / 2),
Vector2(-circleRadius, -_length / 2), Vector2(-circleRadius, -_length / 2),
); );
final rightEdgeShapeFixtureDef = FixtureDef(
rightEdgeShape,
restitution: 5,
);
return [ return [
topCircleFixtureDef, FixtureDef(topCircleShape),
bottomCircleFixtureDef, FixtureDef(bottomCircleShape),
leftEdgeShapeFixtureDef, FixtureDef(leftEdgeShape),
rightEdgeShapeFixtureDef, FixtureDef(rightEdgeShape),
]; ];
} }

@ -4,6 +4,7 @@ import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_components/src/components/sparky_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/sparky_bumper/behaviors/behaviors.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
@ -51,7 +52,10 @@ class SparkyBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.sparky.bumper.a.dimmed.keyName, dimmedAssetPath: Assets.images.sparky.bumper.a.dimmed.keyName,
spritePosition: Vector2(0, -0.25), spritePosition: Vector2(0, -0.25),
bloc: SparkyBumperCubit(), bloc: SparkyBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro sparky_bumper} /// {@macro sparky_bumper}
@ -64,7 +68,10 @@ class SparkyBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.sparky.bumper.b.dimmed.keyName, dimmedAssetPath: Assets.images.sparky.bumper.b.dimmed.keyName,
spritePosition: Vector2(0, -0.35), spritePosition: Vector2(0, -0.35),
bloc: SparkyBumperCubit(), bloc: SparkyBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// {@macro sparky_bumper} /// {@macro sparky_bumper}
@ -77,7 +84,10 @@ class SparkyBumper extends BodyComponent with InitialPosition, ZIndex {
dimmedAssetPath: Assets.images.sparky.bumper.c.dimmed.keyName, dimmedAssetPath: Assets.images.sparky.bumper.c.dimmed.keyName,
spritePosition: Vector2(0, -0.4), spritePosition: Vector2(0, -0.4),
bloc: SparkyBumperCubit(), bloc: SparkyBumperCubit(),
children: children, children: [
...?children,
BumpingBehavior(strength: 20),
],
); );
/// Creates an [SparkyBumper] without any children. /// Creates an [SparkyBumper] without any children.
@ -112,15 +122,11 @@ class SparkyBumper extends BodyComponent with InitialPosition, ZIndex {
majorRadius: _majorRadius, majorRadius: _majorRadius,
minorRadius: _minorRadius, minorRadius: _minorRadius,
)..rotate(math.pi / 2.1); )..rotate(math.pi / 2.1);
final fixtureDef = FixtureDef( final bodyDef = BodyDef(
shape, position: initialPosition,
restitution: 4,
); );
final bodyDef = BodyDef()
..position = initialPosition
..userData = this;
return world.createBody(bodyDef)..createFixture(fixtureDef); return world.createBody(bodyDef)..createFixtureFromShape(shape);
} }
} }

@ -23,7 +23,7 @@ abstract class ZIndexes {
// TODO(allisonryan0002): fix this magic zindex. Could bump all priorities so // TODO(allisonryan0002): fix this magic zindex. Could bump all priorities so
// there are no negatives. // there are no negatives.
static const boardBackground = 3 * _below + _base; static const boardBackground = 5 * _below + _base;
static const decal = _above + boardBackground; static const decal = _above + boardBackground;
@ -61,7 +61,7 @@ abstract class ZIndexes {
// Flutter Forest // Flutter Forest
static const flutterForest = _above + launchRampForegroundRailing; static const flutterForest = _above + ballOnBoard;
// Sparky Scorch // Sparky Scorch

@ -7,6 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/android_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/android_bumper/behaviors/behaviors.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import '../../../helpers/helpers.dart'; import '../../../helpers/helpers.dart';
@ -62,6 +63,30 @@ void main() {
}); });
group('adds', () { group('adds', () {
flameTester.test('an AndroidBumperBallContactBehavior', (game) async {
final androidBumper = AndroidBumper.a();
await game.ensureAdd(androidBumper);
expect(
androidBumper.children
.whereType<AndroidBumperBallContactBehavior>()
.single,
isNotNull,
);
});
flameTester.test('an AndroidBumperBlinkingBehavior', (game) async {
final androidBumper = AndroidBumper.a();
await game.ensureAdd(androidBumper);
expect(
androidBumper.children
.whereType<AndroidBumperBlinkingBehavior>()
.single,
isNotNull,
);
});
});
group("'a' adds", () {
flameTester.test('new children', (game) async { flameTester.test('new children', (game) async {
final component = Component(); final component = Component();
final androidBumper = AndroidBumper.a( final androidBumper = AndroidBumper.a(
@ -71,13 +96,51 @@ void main() {
expect(androidBumper.children, contains(component)); expect(androidBumper.children, contains(component));
}); });
flameTester.test('an AndroidBumperBallContactBehavior', (game) async { flameTester.test('a BumpingBehavior', (game) async {
final androidBumper = AndroidBumper.a(); final androidBumper = AndroidBumper.a();
await game.ensureAdd(androidBumper); await game.ensureAdd(androidBumper);
expect( expect(
androidBumper.children androidBumper.children.whereType<BumpingBehavior>().single,
.whereType<AndroidBumperBallContactBehavior>() isNotNull,
.single, );
});
});
group("'b' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final androidBumper = AndroidBumper.b(
children: [component],
);
await game.ensureAdd(androidBumper);
expect(androidBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final androidBumper = AndroidBumper.b();
await game.ensureAdd(androidBumper);
expect(
androidBumper.children.whereType<BumpingBehavior>().single,
isNotNull,
);
});
});
group("'cow' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final androidBumper = AndroidBumper.cow(
children: [component],
);
await game.ensureAdd(androidBumper);
expect(androidBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final androidBumper = AndroidBumper.cow();
await game.ensureAdd(androidBumper);
expect(
androidBumper.children.whereType<BumpingBehavior>().single,
isNotNull, isNotNull,
); );
}); });

@ -6,6 +6,7 @@ import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_components/src/components/dash_nest_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/dash_nest_bumper/behaviors/behaviors.dart';
import '../../../helpers/helpers.dart'; import '../../../helpers/helpers.dart';
@ -63,8 +64,39 @@ void main() {
verify(bloc.close).called(1); verify(bloc.close).called(1);
}); });
group('adds', () { flameTester.test('adds a DashNestBumperBallContactBehavior', (game) async {
flameTester.test('adds new children', (game) async { final dashNestBumper = DashNestBumper.a();
await game.ensureAdd(dashNestBumper);
expect(
dashNestBumper.children
.whereType<DashNestBumperBallContactBehavior>()
.single,
isNotNull,
);
});
group("'main' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final dashNestBumper = DashNestBumper.main(
children: [component],
);
await game.ensureAdd(dashNestBumper);
expect(dashNestBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final dashNestBumper = DashNestBumper.main();
await game.ensureAdd(dashNestBumper);
expect(
dashNestBumper.children.whereType<BumpingBehavior>().single,
isNotNull,
);
});
});
group("'a' adds", () {
flameTester.test('new children', (game) async {
final component = Component(); final component = Component();
final dashNestBumper = DashNestBumper.a( final dashNestBumper = DashNestBumper.a(
children: [component], children: [component],
@ -73,13 +105,31 @@ void main() {
expect(dashNestBumper.children, contains(component)); expect(dashNestBumper.children, contains(component));
}); });
flameTester.test('a DashNestBumperBallContactBehavior', (game) async { flameTester.test('a BumpingBehavior', (game) async {
final dashNestBumper = DashNestBumper.a(); final dashNestBumper = DashNestBumper.a();
await game.ensureAdd(dashNestBumper); await game.ensureAdd(dashNestBumper);
expect( expect(
dashNestBumper.children dashNestBumper.children.whereType<BumpingBehavior>().single,
.whereType<DashNestBumperBallContactBehavior>() isNotNull,
.single, );
});
});
group("'b' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final dashNestBumper = DashNestBumper.b(
children: [component],
);
await game.ensureAdd(dashNestBumper);
expect(dashNestBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final dashNestBumper = DashNestBumper.b();
await game.ensureAdd(dashNestBumper);
expect(
dashNestBumper.children.whereType<BumpingBehavior>().single,
isNotNull, isNotNull,
); );
}); });

@ -4,6 +4,7 @@ import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import '../../helpers/helpers.dart'; import '../../helpers/helpers.dart';
@ -14,8 +15,6 @@ void main() {
Assets.images.slingshot.lower.keyName, Assets.images.slingshot.lower.keyName,
]; ];
final flameTester = FlameTester(() => TestGame(assets)); final flameTester = FlameTester(() => TestGame(assets));
const length = 2.0;
const angle = 0.0;
flameTester.test('loads correctly', (game) async { flameTester.test('loads correctly', (game) async {
final component = Slingshots(); final component = Slingshots();
@ -40,68 +39,12 @@ void main() {
}, },
); );
flameTester.test( flameTester.test('adds BumpingBehavior', (game) async {
'loads correctly', final slingshots = Slingshots();
(game) async { await game.ensureAdd(slingshots);
final slingshot = Slingshot( for (final slingshot in slingshots.children) {
length: length, expect(slingshot.firstChild<BumpingBehavior>(), isNotNull);
angle: angle, }
spritePath: assets.first, });
);
await game.ensureAdd(slingshot);
expect(game.contains(slingshot), isTrue);
},
);
flameTester.test(
'body is static',
(game) async {
final slingshot = Slingshot(
length: length,
angle: angle,
spritePath: assets.first,
);
await game.ensureAdd(slingshot);
expect(slingshot.body.bodyType, equals(BodyType.static));
},
);
flameTester.test(
'has restitution',
(game) async {
final slingshot = Slingshot(
length: length,
angle: angle,
spritePath: assets.first,
);
await game.ensureAdd(slingshot);
final totalRestitution = slingshot.body.fixtures.fold<double>(
0,
(total, fixture) => total + fixture.restitution,
);
expect(totalRestitution, greaterThan(0));
},
);
flameTester.test(
'has no friction',
(game) async {
final slingshot = Slingshot(
length: length,
angle: angle,
spritePath: assets.first,
);
await game.ensureAdd(slingshot);
final totalFriction = slingshot.body.fixtures.fold<double>(
0,
(total, fixture) => total + fixture.friction,
);
expect(totalFriction, equals(0));
},
);
}); });
} }

@ -6,6 +6,7 @@ import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_components/src/components/bumping_behavior.dart';
import 'package:pinball_components/src/components/sparky_bumper/behaviors/behaviors.dart'; import 'package:pinball_components/src/components/sparky_bumper/behaviors/behaviors.dart';
import '../../../helpers/helpers.dart'; import '../../../helpers/helpers.dart';
@ -62,6 +63,30 @@ void main() {
}); });
group('adds', () { group('adds', () {
flameTester.test('a SparkyBumperBallContactBehavior', (game) async {
final sparkyBumper = SparkyBumper.a();
await game.ensureAdd(sparkyBumper);
expect(
sparkyBumper.children
.whereType<SparkyBumperBallContactBehavior>()
.single,
isNotNull,
);
});
flameTester.test('a SparkyBumperBlinkingBehavior', (game) async {
final sparkyBumper = SparkyBumper.a();
await game.ensureAdd(sparkyBumper);
expect(
sparkyBumper.children
.whereType<SparkyBumperBlinkingBehavior>()
.single,
isNotNull,
);
});
});
group("'a' adds", () {
flameTester.test('new children', (game) async { flameTester.test('new children', (game) async {
final component = Component(); final component = Component();
final sparkyBumper = SparkyBumper.a( final sparkyBumper = SparkyBumper.a(
@ -71,16 +96,54 @@ void main() {
expect(sparkyBumper.children, contains(component)); expect(sparkyBumper.children, contains(component));
}); });
flameTester.test('a SparkyBumperBallContactBehavior', (game) async { flameTester.test('a BumpingBehavior', (game) async {
final sparkyBumper = SparkyBumper.a(); final sparkyBumper = SparkyBumper.a();
await game.ensureAdd(sparkyBumper); await game.ensureAdd(sparkyBumper);
expect( expect(
sparkyBumper.children sparkyBumper.children.whereType<BumpingBehavior>().single,
.whereType<SparkyBumperBallContactBehavior>()
.single,
isNotNull, isNotNull,
); );
}); });
}); });
group("'b' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final sparkyBumper = SparkyBumper.b(
children: [component],
);
await game.ensureAdd(sparkyBumper);
expect(sparkyBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final sparkyBumper = SparkyBumper.b();
await game.ensureAdd(sparkyBumper);
expect(
sparkyBumper.children.whereType<BumpingBehavior>().single,
isNotNull,
);
});
group("'c' adds", () {
flameTester.test('new children', (game) async {
final component = Component();
final sparkyBumper = SparkyBumper.c(
children: [component],
);
await game.ensureAdd(sparkyBumper);
expect(sparkyBumper.children, contains(component));
});
flameTester.test('a BumpingBehavior', (game) async {
final sparkyBumper = SparkyBumper.c();
await game.ensureAdd(sparkyBumper);
expect(
sparkyBumper.children.whereType<BumpingBehavior>().single,
isNotNull,
);
});
});
});
}); });
} }

@ -9,6 +9,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/flutter_forest/behaviors/behaviors.dart'; import 'package:pinball/game/components/flutter_forest/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart';
import '../../../../helpers/helpers.dart'; import '../../../../helpers/helpers.dart';
@ -40,9 +41,8 @@ void main() {
DashNestBumper.test(bloc: DashNestBumperCubit()), DashNestBumper.test(bloc: DashNestBumperCubit()),
DashNestBumper.test(bloc: DashNestBumperCubit()), DashNestBumper.test(bloc: DashNestBumperCubit()),
]; ];
await parent.addAll(bumpers); await game.ensureAdd(ZCanvasComponent(children: [parent]));
await game.ensureAdd(parent); await parent.ensureAddAll([...bumpers, behavior]);
await parent.ensureAdd(behavior);
for (final bumper in bumpers) { for (final bumper in bumpers) {
bumper.bloc.onBallContacted(); bumper.bloc.onBallContacted();
@ -65,8 +65,7 @@ void main() {
DashNestBumper.test(bloc: DashNestBumperCubit()), DashNestBumper.test(bloc: DashNestBumperCubit()),
DashNestBumper.test(bloc: DashNestBumperCubit()), DashNestBumper.test(bloc: DashNestBumperCubit()),
]; ];
await parent.addAll(bumpers); await game.ensureAdd(ZCanvasComponent(children: [parent]));
await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
for (final bumper in bumpers) { for (final bumper in bumpers) {
@ -74,10 +73,10 @@ void main() {
} }
await game.ready(); await game.ready();
expect( // expect(
game.descendants().whereType<Ball>().single, // game.descendants().whereType<Ball>().single,
isNotNull, // isNotNull,
); // );
}, },
); );
}); });

Loading…
Cancel
Save