Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Commit

Permalink
feat: add sparky bumpers (#150)
Browse files Browse the repository at this point in the history
* feat: added sparky bumpers

* test: tests for sparky bumpers

* feat: sandbox for sparky bumpers

* chore: unused imports

* refactor: removed Bumper and added TODO for future refactor

* fix: fixed size and tracing

* fix: fix tracing

* fix: final ellipse sizes

* refactor: different sized bumpers

* Update packages/pinball_components/lib/src/components/sparky_bumper.dart

Co-authored-by: Allison Ryan <allisonryan0002@gmail.com>
Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 6, 2022
1 parent d798fdf commit 254c38d
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 0 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions packages/pinball_components/lib/gen/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -19,3 +19,4 @@ export 'shapes/shapes.dart';
export 'spaceship.dart';
export 'spaceship_rail.dart';
export 'spaceship_ramp.dart';
export 'sparky_bumper.dart';
125 changes: 125 additions & 0 deletions packages/pinball_components/lib/src/components/sparky_bumper.dart
@@ -0,0 +1,125 @@
import 'dart:math' as math;

import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball_components/pinball_components.dart';

/// {@template sparky_bumper}
/// Bumper for Sparky area.
/// {@endtemplate}
// TODO(ruimiguel): refactor later to unify with DashBumpers.
class SparkyBumper extends BodyComponent with InitialPosition {
/// {@macro sparky_bumper}
SparkyBumper._({
required double majorRadius,
required double minorRadius,
required String activeAssetPath,
required String inactiveAssetPath,
required SpriteComponent spriteComponent,
}) : _majorRadius = majorRadius,
_minorRadius = minorRadius,
_activeAssetPath = activeAssetPath,
_inactiveAssetPath = inactiveAssetPath,
_spriteComponent = spriteComponent;

/// {@macro sparky_bumper}
SparkyBumper.a()
: this._(
majorRadius: 2.9,
minorRadius: 2.1,
activeAssetPath: Assets.images.sparkyBumper.a.active.keyName,
inactiveAssetPath: Assets.images.sparkyBumper.a.inactive.keyName,
spriteComponent: SpriteComponent(
anchor: Anchor.center,
position: Vector2(0, -0.25),
),
);

/// {@macro sparky_bumper}
SparkyBumper.b()
: this._(
majorRadius: 2.85,
minorRadius: 2,
activeAssetPath: Assets.images.sparkyBumper.b.active.keyName,
inactiveAssetPath: Assets.images.sparkyBumper.b.inactive.keyName,
spriteComponent: SpriteComponent(
anchor: Anchor.center,
position: Vector2(0, -0.35),
),
);

/// {@macro sparky_bumper}
SparkyBumper.c()
: this._(
majorRadius: 3,
minorRadius: 2.2,
activeAssetPath: Assets.images.sparkyBumper.c.active.keyName,
inactiveAssetPath: Assets.images.sparkyBumper.c.inactive.keyName,
spriteComponent: SpriteComponent(
anchor: Anchor.center,
position: Vector2(0, -0.4),
),
);

final double _majorRadius;
final double _minorRadius;
final String _activeAssetPath;
late final Sprite _activeSprite;
final String _inactiveAssetPath;
late final Sprite _inactiveSprite;
final SpriteComponent _spriteComponent;

@override
Future<void> onLoad() async {
await super.onLoad();
await _loadSprites();

// TODO(erickzanardo): Look into using onNewState instead.
// Currently doing: onNewState(gameRef.read<GameState>()) will throw an
// `Exception: build context is not available yet`
deactivate();
await add(_spriteComponent);
}

@override
Body createBody() {
renderBody = false;

final shape = EllipseShape(
center: Vector2.zero(),
majorRadius: _majorRadius,
minorRadius: _minorRadius,
)..rotate(math.pi / 1.9);
final fixtureDef = FixtureDef(shape)
..friction = 0
..restitution = 4;

final bodyDef = BodyDef()
..position = initialPosition
..userData = this;

return world.createBody(bodyDef)..createFixture(fixtureDef);
}

Future<void> _loadSprites() async {
// TODO(alestiago): I think ideally we would like to do:
// Sprite(path).load so we don't require to store the activeAssetPath and
// the inactive assetPath.
_inactiveSprite = await gameRef.loadSprite(_inactiveAssetPath);
_activeSprite = await gameRef.loadSprite(_activeAssetPath);
}

/// Activates the [DashNestBumper].
void activate() {
_spriteComponent
..sprite = _activeSprite
..size = _activeSprite.originalSize / 10;
}

/// Deactivates the [DashNestBumper].
void deactivate() {
_spriteComponent
..sprite = _inactiveSprite
..size = _inactiveSprite.originalSize / 10;
}
}
3 changes: 3 additions & 0 deletions packages/pinball_components/pubspec.yaml
Expand Up @@ -39,6 +39,9 @@ flutter:
- assets/images/spaceship/ramp/
- assets/images/chrome_dino/
- assets/images/kicker/
- assets/images/sparky_bumper/a/
- assets/images/sparky_bumper/b/
- assets/images/sparky_bumper/c/

flutter_gen:
line_length: 80
Expand Down
1 change: 1 addition & 0 deletions packages/pinball_components/sandbox/lib/main.dart
Expand Up @@ -21,5 +21,6 @@ void main() {
addChromeDinoStories(dashbook);
addDashNestBumperStories(dashbook);
addKickerStories(dashbook);
addSparkyBumperStories(dashbook);
runApp(dashbook);
}
@@ -0,0 +1,47 @@
import 'dart:async';

import 'package:flame/extensions.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/ball/basic_ball_game.dart';

class SparkyBumperGame extends BasicBallGame {
SparkyBumperGame({
required this.trace,
}) : super(color: const Color(0xFF0000FF));

static const info = '''
Shows how a SparkyBumper is rendered.
Activate the "trace" parameter to overlay the body.
''';

final bool trace;

@override
Future<void> onLoad() async {
await super.onLoad();

final center = screenToWorld(camera.viewport.canvasSize! / 2);
final sparkyBumperA = SparkyBumper.a()
..initialPosition = Vector2(center.x - 20, center.y - 20)
..priority = 1;
final sparkyBumperB = SparkyBumper.b()
..initialPosition = Vector2(center.x - 10, center.y + 10)
..priority = 1;
final sparkyBumperC = SparkyBumper.c()
..initialPosition = Vector2(center.x + 20, center.y)
..priority = 1;
await addAll([
sparkyBumperA,
sparkyBumperB,
sparkyBumperC,
]);

if (trace) {
sparkyBumperA.trace();
sparkyBumperB.trace();
sparkyBumperC.trace();
}
}
}
@@ -0,0 +1,17 @@
import 'package:dashbook/dashbook.dart';
import 'package:flame/game.dart';
import 'package:sandbox/common/common.dart';
import 'package:sandbox/stories/sparky_bumper/sparky_bumper_game.dart';

void addSparkyBumperStories(Dashbook dashbook) {
dashbook.storiesOf('Sparky Bumpers').add(
'Basic',
(context) => GameWidget(
game: SparkyBumperGame(
trace: context.boolProperty('Trace', true),
),
),
codeLink: buildSourceLink('sparky_bumper/basic.dart'),
info: SparkyBumperGame.info,
);
}
Expand Up @@ -6,3 +6,4 @@ export 'effects/stories.dart';
export 'flipper/stories.dart';
export 'layer/stories.dart';
export 'spaceship/stories.dart';
export 'sparky_bumper/stories.dart';
@@ -0,0 +1,74 @@
// ignore_for_file: cascade_invocations

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 '../../helpers/helpers.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(TestGame.new);

group('SparkyBumper', () {
flameTester.test('"a" loads correctly', (game) async {
final bumper = SparkyBumper.a();
await game.ensureAdd(bumper);

expect(game.contains(bumper), isTrue);
});

flameTester.test('"b" loads correctly', (game) async {
final bumper = SparkyBumper.b();
await game.ensureAdd(bumper);
expect(game.contains(bumper), isTrue);
});

flameTester.test('"c" loads correctly', (game) async {
final bumper = SparkyBumper.c();
await game.ensureAdd(bumper);
expect(game.contains(bumper), isTrue);
});

flameTester.test('activate returns normally', (game) async {
final bumper = SparkyBumper.a();
await game.ensureAdd(bumper);

expect(bumper.activate, returnsNormally);
});

flameTester.test('deactivate returns normally', (game) async {
final bumper = SparkyBumper.a();
await game.ensureAdd(bumper);

expect(bumper.deactivate, returnsNormally);
});

flameTester.test('changes sprite', (game) async {
final bumper = SparkyBumper.a();
await game.ensureAdd(bumper);

final spriteComponent = bumper.firstChild<SpriteComponent>()!;

final deactivatedSprite = spriteComponent.sprite;
bumper.activate();
expect(
spriteComponent.sprite,
isNot(equals(deactivatedSprite)),
);

final activatedSprite = spriteComponent.sprite;
bumper.deactivate();
expect(
spriteComponent.sprite,
isNot(equals(activatedSprite)),
);

expect(
activatedSprite,
isNot(equals(deactivatedSprite)),
);
});
});
}

0 comments on commit 254c38d

Please sign in to comment.