feat: fixed positioning (#70)

* feat: game uses fixed positioning now

* feat: fixed positioning

* feat: pr suggestion

* lint
pull/74/head
Erick 4 years ago committed by GitHub
parent 4af09b64fa
commit a111fd417e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,25 +7,23 @@ import 'package:pinball/game/game.dart';
/// {entemplate} /// {entemplate}
class Board extends Component { class Board extends Component {
/// {@macro board} /// {@macro board}
Board({required Vector2 size}) : _size = size; Board();
final Vector2 _size;
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
// TODO(alestiago): adjust positioning once sprites are added. // TODO(alestiago): adjust positioning once sprites are added.
final bottomGroup = _BottomGroup( final bottomGroup = _BottomGroup(
position: Vector2( position: Vector2(
_size.x / 2, PinballGame.boardBounds.center.dx,
_size.y / 1.25, PinballGame.boardBounds.bottom + 10,
), ),
spacing: 2, spacing: 2,
); );
final dashForest = _FlutterForest( final dashForest = _FlutterForest(
position: Vector2( position: Vector2(
_size.x / 1.25, PinballGame.boardBounds.right - 20,
_size.y / 4.25, PinballGame.boardBounds.top - 20,
), ),
); );

@ -30,18 +30,23 @@ class JetpackRamp extends Component with HasGameRef<PinballGame> {
// TODO(ruialonso): Use a bezier curve once control points are defined. // TODO(ruialonso): Use a bezier curve once control points are defined.
color: const Color.fromARGB(255, 8, 218, 241), color: const Color.fromARGB(255, 8, 218, 241),
center: position, center: position,
width: 62, width: 5,
radius: 200, radius: 18,
angle: math.pi, angle: math.pi,
rotation: math.pi,
)..layer = layer;
final leftOpening = _JetpackRampOpening(
outsideLayer: Layer.spaceship,
rotation: math.pi,
) )
..initialPosition = position ..initialPosition = position - Vector2(2, 22)
..layer = layer;
final leftOpening = _JetpackRampOpening(outsideLayer: Layer.spaceship)
..initialPosition = position + Vector2(-27.6, 25.3)
..layer = Layer.jetpack; ..layer = Layer.jetpack;
final rightOpening = _JetpackRampOpening() final rightOpening = _JetpackRampOpening(
..initialPosition = position + Vector2(-10.6, 25.3) rotation: math.pi,
)
..initialPosition = position - Vector2(-13, 22)
..layer = Layer.opening; ..layer = Layer.opening;
await addAll([ await addAll([
@ -60,20 +65,26 @@ class _JetpackRampOpening extends RampOpening {
/// {@macro jetpack_ramp_opening} /// {@macro jetpack_ramp_opening}
_JetpackRampOpening({ _JetpackRampOpening({
Layer? outsideLayer, Layer? outsideLayer,
}) : super( required double rotation,
}) : _rotation = rotation,
super(
pathwayLayer: Layer.jetpack, pathwayLayer: Layer.jetpack,
outsideLayer: outsideLayer, outsideLayer: outsideLayer,
orientation: RampOrientation.down, orientation: RampOrientation.down,
); );
// TODO(ruialonso): Avoid magic number 2, should be proportional to final double _rotation;
// TODO(ruialonso): Avoid magic number 3, should be propotional to
// [JetpackRamp]. // [JetpackRamp].
static const _size = 2; static final Vector2 _size = Vector2(3, .1);
@override @override
Shape get shape => PolygonShape() Shape get shape => PolygonShape()
..setAsEdge( ..setAsBox(
Vector2(initialPosition.x - _size, initialPosition.y), _size.x,
Vector2(initialPosition.x + _size, initialPosition.y), _size.y,
initialPosition,
_rotation,
); );
} }

@ -28,26 +28,27 @@ class LauncherRamp extends Component with HasGameRef<PinballGame> {
final straightPath = Pathway.straight( final straightPath = Pathway.straight(
color: const Color.fromARGB(255, 34, 255, 0), color: const Color.fromARGB(255, 34, 255, 0),
start: Vector2(0, 0), start: Vector2(position.x, position.y),
end: Vector2(0, 700), end: Vector2(position.x, 74),
width: 80, width: 5,
) )
..initialPosition = position ..initialPosition = position
..layer = layer; ..layer = layer;
final curvedPath = Pathway.arc( final curvedPath = Pathway.arc(
color: const Color.fromARGB(255, 251, 255, 0), color: const Color.fromARGB(255, 251, 255, 0),
center: position + Vector2(-29, -8), center: position + Vector2(-1, 68),
radius: 300, radius: 20,
angle: 10 * math.pi / 9, angle: 8 * math.pi / 9,
width: 80, width: 5,
) rotation: math.pi,
..initialPosition = position + Vector2(-28.8, -6) )..layer = layer;
..layer = layer;
final leftOpening = _LauncherRampOpening(rotation: 13 * math.pi / 180) final leftOpening = _LauncherRampOpening(rotation: 13 * math.pi / 180)
..initialPosition = position + Vector2(-72.5, 12) ..initialPosition = position + Vector2(1, 49)
..layer = Layer.opening; ..layer = Layer.opening;
final rightOpening = _LauncherRampOpening(rotation: 0) final rightOpening = _LauncherRampOpening(rotation: 0)
..initialPosition = position + Vector2(-46.8, 17) ..initialPosition = position + Vector2(-16, 46)
..layer = Layer.opening; ..layer = Layer.opening;
await addAll([ await addAll([

@ -150,10 +150,7 @@ class Pathway extends BodyComponent with InitialPosition, Layered {
final fixturesDef = <FixtureDef>[]; final fixturesDef = <FixtureDef>[];
for (final path in _paths) { for (final path in _paths) {
final chain = ChainShape() final chain = ChainShape()..createChain(path);
..createChain(
path.map(gameRef.screenToWorld).toList(),
);
fixturesDef.add(FixtureDef(chain)); fixturesDef.add(FixtureDef(chain));
} }

@ -15,7 +15,10 @@ class Spaceship extends Forge2DBlueprint {
@override @override
void build() { void build() {
final position = Vector2(30, -50); final position = Vector2(
PinballGame.boardBounds.left + radius + 0.5,
PinballGame.boardBounds.center.dy + 34,
);
addAllContactCallback([ addAllContactCallback([
SpaceshipHoleBallContactCallback(), SpaceshipHoleBallContactCallback(),

@ -1,7 +1,9 @@
// ignore_for_file: avoid_renaming_method_parameters // ignore_for_file: avoid_renaming_method_parameters
import 'package:flame/extensions.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:pinball/game/components/components.dart'; import 'package:pinball/game/components/components.dart';
import 'package:pinball/game/pinball_game.dart';
/// {@template wall} /// {@template wall}
/// A continuous generic and [BodyType.static] barrier that divides a game area. /// A continuous generic and [BodyType.static] barrier that divides a game area.
@ -39,15 +41,16 @@ class Wall extends BodyComponent {
/// Create top, left, and right [Wall]s for the game board. /// Create top, left, and right [Wall]s for the game board.
List<Wall> createBoundaries(Forge2DGame game) { List<Wall> createBoundaries(Forge2DGame game) {
final topLeft = Vector2.zero(); final topLeft = PinballGame.boardBounds.topLeft.toVector2();
final bottomRight = game.screenToWorld(game.camera.viewport.effectiveSize); final bottomRight = PinballGame.boardBounds.bottomRight.toVector2();
final topRight = Vector2(bottomRight.x, topLeft.y); final topRight = Vector2(bottomRight.x, topLeft.y);
final bottomLeft = Vector2(topLeft.x, bottomRight.y); final bottomLeft = Vector2(topLeft.x, bottomRight.y);
return [ return [
Wall(start: topLeft, end: topRight), Wall(start: topLeft, end: topRight),
Wall(start: topRight, end: bottomRight), Wall(start: topRight, end: bottomRight),
Wall(start: bottomLeft, end: topLeft), Wall(start: topLeft, end: bottomLeft),
]; ];
} }
@ -59,13 +62,10 @@ List<Wall> createBoundaries(Forge2DGame game) {
/// {@endtemplate} /// {@endtemplate}
class BottomWall extends Wall { class BottomWall extends Wall {
/// {@macro bottom_wall} /// {@macro bottom_wall}
BottomWall(Forge2DGame game) BottomWall()
: super( : super(
start: game.screenToWorld(game.camera.viewport.effectiveSize), start: PinballGame.boardBounds.bottomLeft.toVector2(),
end: Vector2( end: PinballGame.boardBounds.bottomRight.toVector2(),
0,
game.screenToWorld(game.camera.viewport.effectiveSize).y,
),
); );
} }

@ -1,6 +1,7 @@
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:async'; import 'dart:async';
import 'package:flame/extensions.dart';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
@ -16,6 +17,13 @@ class PinballGame extends Forge2DGame
late final Plunger plunger; late final Plunger plunger;
static final boardSize = Vector2(72, 128);
static final boardBounds = Rect.fromCenter(
center: Offset.zero,
width: boardSize.x,
height: -boardSize.y,
);
@override @override
void onAttach() { void onAttach() {
super.onAttach(); super.onAttach();
@ -27,11 +35,16 @@ class PinballGame extends Forge2DGame
_addContactCallbacks(); _addContactCallbacks();
await _addGameBoundaries(); await _addGameBoundaries();
unawaited(_addBoard()); unawaited(add(Board()));
unawaited(_addPlunger()); unawaited(_addPlunger());
unawaited(_addBonusWord()); unawaited(_addBonusWord());
unawaited(_addPaths()); unawaited(_addPaths());
unawaited(addFromBlueprint(Spaceship())); unawaited(addFromBlueprint(Spaceship()));
// Fix camera on the center of the board size
camera
..followVector2(screenToWorld(boardSize / 2))
..zoom = size.y / 14;
} }
void _addContactCallbacks() { void _addContactCallbacks() {
@ -41,44 +54,27 @@ class PinballGame extends Forge2DGame
} }
Future<void> _addGameBoundaries() async { Future<void> _addGameBoundaries() async {
await add(BottomWall(this)); await add(BottomWall());
createBoundaries(this).forEach(add); createBoundaries(this).forEach(add);
} }
Future<void> _addBoard() async {
final board = Board(
size: screenToWorld(
Vector2(
camera.viewport.effectiveSize.x,
camera.viewport.effectiveSize.y,
),
),
);
await add(board);
}
Future<void> _addPlunger() async { Future<void> _addPlunger() async {
plunger = Plunger( plunger = Plunger(compressionDistance: 2);
compressionDistance: camera.viewport.effectiveSize.y / 12,
); plunger.initialPosition = boardBounds.bottomRight.toVector2() -
plunger.initialPosition = screenToWorld(
Vector2( Vector2(
camera.viewport.effectiveSize.x / 2 + 450, 8,
camera.viewport.effectiveSize.y - plunger.compressionDistance, -10,
),
); );
await add(plunger); await add(plunger);
} }
Future<void> _addBonusWord() async { Future<void> _addBonusWord() async {
await add( await add(
BonusWord( BonusWord(
position: screenToWorld( position: Vector2(
Vector2( boardBounds.center.dx,
camera.viewport.effectiveSize.x / 2, boardBounds.bottom + 10,
camera.viewport.effectiveSize.y - 50,
),
), ),
), ),
); );
@ -86,18 +82,22 @@ class PinballGame extends Forge2DGame
Future<void> _addPaths() async { Future<void> _addPaths() async {
final jetpackRamp = JetpackRamp( final jetpackRamp = JetpackRamp(
position: Vector2(42.6, -45), position: Vector2(
PinballGame.boardBounds.left + 25,
PinballGame.boardBounds.top - 20,
),
); );
final launcherRamp = LauncherRamp( final launcherRamp = LauncherRamp(
position: screenToWorld( position: Vector2(
Vector2( PinballGame.boardBounds.right - 23,
camera.viewport.effectiveSize.x / 2 + 400, PinballGame.boardBounds.bottom + 40,
camera.viewport.effectiveSize.y / 2 - 330,
),
), ),
); );
await addAll([jetpackRamp, launcherRamp]); await addAll([
jetpackRamp,
launcherRamp,
]);
} }
void spawnBall() { void spawnBall() {

@ -15,7 +15,7 @@ void main() {
flameTester.test( flameTester.test(
'loads correctly', 'loads correctly',
(game) async { (game) async {
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
@ -27,7 +27,7 @@ void main() {
flameTester.test( flameTester.test(
'has one left flipper', 'has one left flipper',
(game) async { (game) async {
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
@ -41,7 +41,7 @@ void main() {
flameTester.test( flameTester.test(
'has one right flipper', 'has one right flipper',
(game) async { (game) async {
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
@ -55,7 +55,7 @@ void main() {
flameTester.test( flameTester.test(
'has two Baseboards', 'has two Baseboards',
(game) async { (game) async {
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
@ -67,7 +67,7 @@ void main() {
flameTester.test( flameTester.test(
'has two Kickers', 'has two Kickers',
(game) async { (game) async {
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);
@ -80,7 +80,7 @@ void main() {
'has three RoundBumpers', 'has three RoundBumpers',
(game) async { (game) async {
// TODO(alestiago): change to [NestBumpers] once provided. // TODO(alestiago): change to [NestBumpers] once provided.
final board = Board(size: Vector2.all(500)); final board = Board();
await game.ready(); await game.ready();
await game.ensureAdd(board); await game.ensureAdd(board);

Loading…
Cancel
Save