diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 95134ec2..4d8601b7 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -1,5 +1,6 @@ export 'anchor.dart'; export 'ball.dart'; +export 'flipper.dart'; export 'plunger.dart'; export 'score_points.dart'; export 'wall.dart'; diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 91e12854..26a96122 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -1,8 +1,16 @@ +import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; import 'package:pinball/game/game.dart'; -class PinballGame extends Forge2DGame with FlameBloc { +class PinballGame extends Forge2DGame with FlameBloc, KeyboardEvents { + late final Flipper _rightFlipper; + late final Flipper _leftFlipper; + late final RevoluteJoint _leftFlipperRevoluteJoint; + late final RevoluteJoint _rightFlipperRevoluteJoint; + void spawnBall() { add(Ball(position: ballStartingPosition)); } @@ -23,5 +31,112 @@ class PinballGame extends Forge2DGame with FlameBloc { await add(BottomWall(this)); addContactCallback(BottomWallBallContactCallback()); + + final center = screenToWorld(camera.viewport.effectiveSize / 2); + const flipperSpace = 2; + await add( + _leftFlipper = Flipper( + position: Vector2( + (center.x - (Flipper.size.x / 2)) - (flipperSpace / 2), + center.y, + ), + ), + ); + final leftFlipperAnchor = Anchor( + position: Vector2( + _leftFlipper.body.position.x, + _leftFlipper.body.position.y - Flipper.size.y / 2, + ), + ); + await add(leftFlipperAnchor); + final leftFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef( + flipper: _leftFlipper, + anchor: leftFlipperAnchor, + ); + // TODO(alestiago): Remove casting once the following is closed: + // https://github.com/flame-engine/forge2d/issues/36 + _leftFlipperRevoluteJoint = + world.createJoint(leftFlipperRevoluteJointDef) as RevoluteJoint; + + await add( + _rightFlipper = Flipper( + position: Vector2( + (center.x + (Flipper.size.x / 2)) + (flipperSpace / 2), + center.y, + ), + isMirrored: true, + ), + ); + final rightFlipperAnchor = Anchor( + position: Vector2( + _rightFlipper.body.position.x + Flipper.size.x, + _rightFlipper.body.position.y - Flipper.size.y / 2, + ), + ); + await add(rightFlipperAnchor); + final rightFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef( + flipper: _rightFlipper, + anchor: rightFlipperAnchor, + isMirrored: true, + ); + _rightFlipperRevoluteJoint = + world.createJoint(rightFlipperRevoluteJointDef) as RevoluteJoint; + } + + @override + Future onMount() async { + super.onMount(); + // TODO(erickzanardo): Clean this once the issue is solved: + // https://github.com/flame-engine/flame/issues/1417 + await Future.delayed(const Duration(milliseconds: 500)); + await _leftFlipper.hasMounted.future; + await _rightFlipper.hasMounted.future; + + _leftFlipperRevoluteJoint.setLimits( + _leftFlipperRevoluteJoint.lowerLimit * -1, + _leftFlipperRevoluteJoint.upperLimit, + ); + _rightFlipperRevoluteJoint.setLimits( + _rightFlipperRevoluteJoint.lowerLimit, + _rightFlipperRevoluteJoint.upperLimit * -1, + ); + } + + @override + KeyEventResult onKeyEvent( + RawKeyEvent event, + Set keysPressed, + ) { + if (event is RawKeyDownEvent && + (event.data.logicalKey == LogicalKeyboardKey.arrowLeft || + event.data.logicalKey == LogicalKeyboardKey.keyA)) { + _leftFlipper.moveUp(); + } + + if (event is RawKeyUpEvent && + (event.data.logicalKey == LogicalKeyboardKey.arrowLeft || + event.data.logicalKey == LogicalKeyboardKey.keyA)) { + _leftFlipper.moveDown(); + } + + if (event is RawKeyDownEvent && + (event.data.logicalKey == LogicalKeyboardKey.arrowLeft || + event.data.logicalKey == LogicalKeyboardKey.keyA)) { + _leftFlipper.moveUp(); + } + + if (event is RawKeyUpEvent && + (event.data.logicalKey == LogicalKeyboardKey.arrowRight || + event.data.logicalKey == LogicalKeyboardKey.keyD)) { + _rightFlipper.moveDown(); + } + + if (event is RawKeyDownEvent && + (event.data.logicalKey == LogicalKeyboardKey.arrowRight || + event.data.logicalKey == LogicalKeyboardKey.keyD)) { + _rightFlipper.moveUp(); + } + + return KeyEventResult.handled; } }