feat: dynamic ball size (#113)

* feat: scale ball and add ball asset

* refactor: increase plunger properties

* test: board dimensions

* refactor: store adjusted height

* chore: add todo
pull/133/head
Allison Ryan 3 years ago committed by GitHub
parent 930c7fa001
commit 83e6cb892b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,8 +15,8 @@ class Board extends Component {
// TODO(alestiago): adjust positioning once sprites are added.
final bottomGroup = _BottomGroup(
position: Vector2(
PinballGame.boardBounds.center.dx,
PinballGame.boardBounds.bottom + 10,
BoardDimensions.bounds.center.dx,
BoardDimensions.bounds.bottom + 10,
),
spacing: 2,
);
@ -26,8 +26,8 @@ class Board extends Component {
// TODO(alestiago): adjust positioning to real design.
final dino = ChromeDino()
..initialPosition = Vector2(
PinballGame.boardBounds.center.dx + 25,
PinballGame.boardBounds.center.dy + 10,
BoardDimensions.bounds.center.dx + 25,
BoardDimensions.bounds.center.dy + 10,
);
await addAll([

@ -13,8 +13,8 @@ class Jetpack extends Forge2DBlueprint {
@override
void build(_) {
final position = Vector2(
PinballGame.boardBounds.left + 40.5,
PinballGame.boardBounds.top - 31.5,
BoardDimensions.bounds.left + 40.5,
BoardDimensions.bounds.top - 31.5,
);
addAllContactCallback([

@ -13,8 +13,8 @@ class Launcher extends Forge2DBlueprint {
@override
void build(_) {
final position = Vector2(
PinballGame.boardBounds.right - 31.3,
PinballGame.boardBounds.bottom + 33,
BoardDimensions.bounds.right - 31.3,
BoardDimensions.bounds.bottom + 33,
);
addAllContactCallback([
@ -67,8 +67,8 @@ class LauncherRamp extends BodyComponent with InitialPosition, Layered {
final rightStraightShape = EdgeShape()
..set(
startPosition..rotate(PinballGame.boardPerspectiveAngle),
endPosition..rotate(PinballGame.boardPerspectiveAngle),
startPosition..rotate(BoardDimensions.perspectiveAngle),
endPosition..rotate(BoardDimensions.perspectiveAngle),
);
final rightStraightFixtureDef = FixtureDef(rightStraightShape);
fixturesDef.add(rightStraightFixtureDef);

@ -1,7 +1,6 @@
import 'package:flame/components.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template plunger}
@ -26,10 +25,10 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition {
1.35,
0.5,
Vector2.zero(),
PinballGame.boardPerspectiveAngle,
BoardDimensions.perspectiveAngle,
);
final fixtureDef = FixtureDef(shape)..density = 20;
final fixtureDef = FixtureDef(shape)..density = 80;
final bodyDef = BodyDef()
..position = initialPosition
@ -50,7 +49,7 @@ class Plunger extends BodyComponent with KeyboardHandler, InitialPosition {
/// The velocity's magnitude depends on how far the [Plunger] has been pulled
/// from its original [initialPosition].
void _release() {
final velocity = (initialPosition.y - body.position.y) * 4;
final velocity = (initialPosition.y - body.position.y) * 5;
body.linearVelocity = Vector2(0, velocity);
}
@ -127,12 +126,12 @@ class PlungerAnchorPrismaticJointDef extends PrismaticJointDef {
plunger.body,
anchor.body,
anchor.body.position,
Vector2(18.6, PinballGame.boardBounds.height),
Vector2(18.6, BoardDimensions.bounds.height),
);
enableLimit = true;
lowerTranslation = double.negativeInfinity;
enableMotor = true;
motorSpeed = 80;
motorSpeed = 1000;
maxMotorForce = motorSpeed;
collideConnected = true;
}

@ -3,7 +3,6 @@
import 'package:flame/extensions.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/components/components.dart';
import 'package:pinball/game/pinball_game.dart';
import 'package:pinball_components/pinball_components.dart';
/// {@template wall}
@ -42,13 +41,12 @@ class Wall extends BodyComponent {
/// Create top, left, and right [Wall]s for the game board.
List<Wall> createBoundaries(Forge2DGame game) {
final topLeft =
PinballGame.boardBounds.topLeft.toVector2() + Vector2(18.6, 0);
final bottomRight = PinballGame.boardBounds.bottomRight.toVector2();
final topLeft = BoardDimensions.bounds.topLeft.toVector2() + Vector2(18.6, 0);
final bottomRight = BoardDimensions.bounds.bottomRight.toVector2();
final topRight =
PinballGame.boardBounds.topRight.toVector2() - Vector2(18.6, 0);
final bottomLeft = PinballGame.boardBounds.bottomLeft.toVector2();
BoardDimensions.bounds.topRight.toVector2() - Vector2(18.6, 0);
final bottomLeft = BoardDimensions.bounds.bottomLeft.toVector2();
return [
Wall(start: topLeft, end: topRight),
@ -67,8 +65,8 @@ class BottomWall extends Wall {
/// {@macro bottom_wall}
BottomWall()
: super(
start: PinballGame.boardBounds.bottomLeft.toVector2(),
end: PinballGame.boardBounds.bottomRight.toVector2(),
start: BoardDimensions.bounds.bottomLeft.toVector2(),
end: BoardDimensions.bounds.bottomRight.toVector2(),
);
}

@ -1,6 +1,5 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:math' as math;
import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
@ -22,15 +21,6 @@ class PinballGame extends Forge2DGame
late final Plunger plunger;
static final boardSize = Vector2(101.6, 143.8);
static final boardBounds = Rect.fromCenter(
center: Offset.zero,
width: boardSize.x,
height: -boardSize.y,
);
static final boardPerspectiveAngle =
-math.atan(18.6 / PinballGame.boardBounds.height);
@override
void onAttach() {
super.onAttach();
@ -80,7 +70,8 @@ class PinballGame extends Forge2DGame
Future<void> _addPlunger() async {
plunger = Plunger(compressionDistance: 29)
..initialPosition = boardBounds.center.toVector2() + Vector2(41.5, -49);
..initialPosition =
BoardDimensions.bounds.center.toVector2() + Vector2(41.5, -49);
await add(plunger);
}
@ -88,8 +79,8 @@ class PinballGame extends Forge2DGame
await add(
BonusWord(
position: Vector2(
boardBounds.center.dx - 3.07,
boardBounds.center.dy - 2.4,
BoardDimensions.bounds.center.dx - 3.07,
BoardDimensions.bounds.center.dy - 2.4,
),
),
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -23,13 +23,14 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
}
/// The size of the [Ball]
static final Vector2 size = Vector2.all(3);
static final Vector2 size = Vector2.all(4.5);
/// The base [Color] used to tint this [Ball]
final Color baseColor;
double _boostTimer = 0;
static const _boostDuration = 2.0;
late SpriteComponent _spriteComponent;
@override
Future<void> onLoad() async {
@ -37,9 +38,9 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
final sprite = await gameRef.loadSprite(Assets.images.ball.keyName);
final tint = baseColor.withOpacity(0.5);
await add(
SpriteComponent(
_spriteComponent = SpriteComponent(
sprite: sprite,
size: size,
size: size * 1.15,
anchor: Anchor.center,
)..tint(tint),
);
@ -88,6 +89,8 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
unawaited(gameRef.add(effect));
}
_rescale();
}
/// Applies a boost on this [Ball].
@ -95,4 +98,18 @@ class Ball<T extends Forge2DGame> extends BodyComponent<T>
body.applyLinearImpulse(impulse);
_boostTimer = _boostDuration;
}
void _rescale() {
final boardHeight = BoardDimensions.size.y;
const maxShrinkAmount = BoardDimensions.perspectiveShrinkFactor;
final adjustedYPosition = body.position.y + (boardHeight / 2);
final scaleFactor = ((boardHeight - adjustedYPosition) /
BoardDimensions.shrinkAdjustedHeight) +
maxShrinkAmount;
body.fixtures.first.shape.radius = (size.x / 2) * scaleFactor;
_spriteComponent.scale = Vector2.all(scaleFactor);
}
}

@ -0,0 +1,29 @@
import 'dart:math' as math;
import 'package:flame/extensions.dart';
/// {@template board_dimensions}
/// Contains various board properties and dimensions for global use.
/// {@endtemplate}
// TODO(allisonryan0002): consider alternatives for global dimensions.
class BoardDimensions {
/// Width and height of the board.
static final size = Vector2(101.6, 143.8);
/// [Rect] for easier access to board boundaries.
static final bounds = Rect.fromCenter(
center: Offset.zero,
width: size.x,
height: -size.y,
);
/// 3D perspective angle of the board in radians.
static final perspectiveAngle = -math.atan(18.6 / bounds.height);
/// Factor the board shrinks by from the closest point to the farthest.
static const perspectiveShrinkFactor = 0.63;
/// Board height based on the [perspectiveShrinkFactor].
static final shrinkAdjustedHeight =
(1 / (1 - perspectiveShrinkFactor)) * size.y;
}

@ -1,4 +1,5 @@
export 'ball.dart';
export 'board_dimensions.dart';
export 'board_side.dart';
export 'fire_effect.dart';
export 'flipper.dart';

@ -86,7 +86,7 @@ void main() {
final fixture = ball.body.fixtures[0];
expect(fixture.shape.shapeType, equals(ShapeType.circle));
expect(fixture.shape.radius, equals(1.5));
expect(fixture.shape.radius, equals(2.25));
},
);

@ -0,0 +1,27 @@
import 'package:flame/extensions.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart';
void main() {
group('BoardDimensions', () {
test('has size', () {
expect(BoardDimensions.size, equals(Vector2(101.6, 143.8)));
});
test('has bounds', () {
expect(BoardDimensions.bounds, isNotNull);
});
test('has perspectiveAngle', () {
expect(BoardDimensions.perspectiveAngle, isNotNull);
});
test('has perspectiveShrinkFactor', () {
expect(BoardDimensions.perspectiveShrinkFactor, equals(0.63));
});
test('has shrinkAdjustedHeight', () {
expect(BoardDimensions.shrinkAdjustedHeight, isNotNull);
});
});
}
Loading…
Cancel
Save