feat: moved key listening to Flipper

pull/15/head
alestiago 4 years ago
parent 9d44d0b748
commit 32fc3aec4f

@ -1,8 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'dart:math' as math; import 'dart:math' as math;
import 'package:flame/input.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:flutter/services.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
/// {@template flipper} /// {@template flipper}
@ -10,12 +12,21 @@ import 'package:pinball/game/game.dart';
/// ///
/// [Flipper] can be controlled by the player in an arc motion. /// [Flipper] can be controlled by the player in an arc motion.
/// {@endtemplate flipper} /// {@endtemplate flipper}
class Flipper extends BodyComponent { class Flipper extends BodyComponent with KeyboardHandler {
/// {@macro flipper} /// {@macro flipper}
Flipper({ Flipper({
required Vector2 position, required Vector2 position,
required this.side, required this.side,
}) : _position = position { }) : _position = position,
_keys = side.isLeft
? [
LogicalKeyboardKey.arrowLeft,
LogicalKeyboardKey.keyA,
]
: [
LogicalKeyboardKey.arrowRight,
LogicalKeyboardKey.keyD,
] {
// TODO(alestiago): Use sprite instead of color when provided. // TODO(alestiago): Use sprite instead of color when provided.
paint = Paint() paint = Paint()
..color = const Color(0xFF00FF00) ..color = const Color(0xFF00FF00)
@ -33,22 +44,27 @@ class Flipper extends BodyComponent {
/// 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 = 60;
/// The initial position of the [Flipper] body.
final Vector2 _position;
/// 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.
/// ///
/// A [Flipper] with [BoardSide.left] has a counter-clockwise arc motion, /// A [Flipper] with [BoardSide.left] has a counter-clockwise arc motion,
/// whereas a [Flipper] with [BoardSide.right] has a clockwise arc motion. /// whereas a [Flipper] with [BoardSide.right] has a clockwise arc motion.
final BoardSide side; final BoardSide side;
/// Applies downard linear velocity to the [Flipper] to move it up. /// The initial position of the [Flipper] body.
void moveDown() { final Vector2 _position;
/// The [LogicalKeyboardKey]s that will control the [Flipper].
///
/// [onKeyEvent] method listens to when one of these keys is pressed.
final List<LogicalKeyboardKey> _keys;
/// Applies downard linear velocity to the [Flipper] to move it down.
void _moveDown() {
body.linearVelocity = Vector2(0, -_speed); body.linearVelocity = Vector2(0, -_speed);
} }
/// Applies upward linear velocity to the [Flipper] to move it up. /// Applies upward linear velocity to the [Flipper] to move it up.
void moveUp() { void _moveUp() {
body.linearVelocity = Vector2(0, _speed); body.linearVelocity = Vector2(0, _speed);
} }
@ -120,6 +136,22 @@ class Flipper extends BodyComponent {
super.onMount(); super.onMount();
hasMounted.complete(); hasMounted.complete();
} }
@override
bool onKeyEvent(
RawKeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
if (!_keys.contains(event.logicalKey)) return true;
if (event is RawKeyDownEvent) {
_moveUp();
} else if (event is RawKeyUpEvent) {
_moveDown();
}
return true;
}
} }
/// {@template flipper_anchor_revolute_joint} /// {@template flipper_anchor_revolute_joint}

@ -1,13 +1,12 @@
import 'dart:async';
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';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
class PinballGame extends Forge2DGame with FlameBloc, KeyboardEvents { class PinballGame extends Forge2DGame
late final Flipper _rightFlipper; with FlameBloc, HasKeyboardHandlerComponents {
late final Flipper _leftFlipper;
late final RevoluteJoint _leftFlipperRevoluteJoint; late final RevoluteJoint _leftFlipperRevoluteJoint;
late final RevoluteJoint _rightFlipperRevoluteJoint; late final RevoluteJoint _rightFlipperRevoluteJoint;
@ -29,19 +28,18 @@ class PinballGame extends Forge2DGame with FlameBloc, KeyboardEvents {
Future<void> _addFlippers() async { Future<void> _addFlippers() async {
const spaceBetweenFlippers = 2; const spaceBetweenFlippers = 2;
await add( final leftFlipper = Flipper(
_leftFlipper = Flipper( position: Vector2(
position: Vector2( flippersPosition.x - (Flipper.width / 2) - (spaceBetweenFlippers / 2),
flippersPosition.x - (Flipper.width / 2) - (spaceBetweenFlippers / 2), flippersPosition.y,
flippersPosition.y,
),
side: BoardSide.left,
), ),
side: BoardSide.left,
); );
final leftFlipperAnchor = FlipperAnchor(flipper: _leftFlipper); await add(leftFlipper);
final leftFlipperAnchor = FlipperAnchor(flipper: leftFlipper);
await add(leftFlipperAnchor); await add(leftFlipperAnchor);
final leftFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef( final leftFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef(
flipper: _leftFlipper, flipper: leftFlipper,
anchor: leftFlipperAnchor, anchor: leftFlipperAnchor,
); );
// TODO(alestiago): Remove casting once the following is closed: // TODO(alestiago): Remove casting once the following is closed:
@ -49,93 +47,55 @@ class PinballGame extends Forge2DGame with FlameBloc, KeyboardEvents {
_leftFlipperRevoluteJoint = _leftFlipperRevoluteJoint =
world.createJoint(leftFlipperRevoluteJointDef) as RevoluteJoint; world.createJoint(leftFlipperRevoluteJointDef) as RevoluteJoint;
await add( final rightFlipper = Flipper(
_rightFlipper = Flipper( position: Vector2(
position: Vector2( flippersPosition.x + (Flipper.width / 2) + (spaceBetweenFlippers / 2),
flippersPosition.x + (Flipper.width / 2) + (spaceBetweenFlippers / 2), flippersPosition.y,
flippersPosition.y,
),
side: BoardSide.right,
), ),
side: BoardSide.right,
); );
final rightFlipperAnchor = FlipperAnchor(flipper: _rightFlipper); await add(rightFlipper);
final rightFlipperAnchor = FlipperAnchor(flipper: rightFlipper);
await add(rightFlipperAnchor); await add(rightFlipperAnchor);
final rightFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef( final rightFlipperRevoluteJointDef = FlipperAnchorRevoluteJointDef(
flipper: _rightFlipper, flipper: rightFlipper,
anchor: rightFlipperAnchor, anchor: rightFlipperAnchor,
); );
// TODO(alestiago): Remove casting once the following is closed: // TODO(alestiago): Remove casting once the following is closed:
// https://github.com/flame-engine/forge2d/issues/36 // https://github.com/flame-engine/forge2d/issues/36
_rightFlipperRevoluteJoint = _rightFlipperRevoluteJoint =
world.createJoint(rightFlipperRevoluteJointDef) as RevoluteJoint; world.createJoint(rightFlipperRevoluteJointDef) as RevoluteJoint;
}
@override
Future<void> onLoad() async {
addContactCallback(BallScorePointsCallback());
await add(BottomWall(this));
addContactCallback(BottomWallBallContactCallback());
await _addFlippers();
}
@override
Future<void> onMount() async {
super.onMount();
// TODO(erickzanardo): Clean this once the issue is solved: // TODO(erickzanardo): Clean this once the issue is solved:
// https://github.com/flame-engine/flame/issues/1417 // https://github.com/flame-engine/flame/issues/1417
// FIXME(erickzanardo): when mounted the initial potion is not fully // FIXME(erickzanardo): when mounted the initial potion is not fully
// reached. // reached.
await _leftFlipper.hasMounted.future; unawaited(
await _rightFlipper.hasMounted.future; leftFlipper.hasMounted.future.whenComplete(
() => FlipperAnchorRevoluteJointDef.unlock(
FlipperAnchorRevoluteJointDef.unlock( _leftFlipperRevoluteJoint,
_leftFlipperRevoluteJoint, leftFlipper.side,
BoardSide.left, ),
),
); );
FlipperAnchorRevoluteJointDef.unlock( unawaited(
_rightFlipperRevoluteJoint, rightFlipper.hasMounted.future.whenComplete(
BoardSide.right, () => FlipperAnchorRevoluteJointDef.unlock(
_rightFlipperRevoluteJoint,
rightFlipper.side,
),
),
); );
} }
@override @override
KeyEventResult onKeyEvent( Future<void> onLoad() async {
RawKeyEvent event, addContactCallback(BallScorePointsCallback());
Set<LogicalKeyboardKey> 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 && await add(BottomWall(this));
(event.data.logicalKey == LogicalKeyboardKey.arrowRight || addContactCallback(BottomWallBallContactCallback());
event.data.logicalKey == LogicalKeyboardKey.keyD)) {
_rightFlipper.moveUp();
}
return KeyEventResult.handled; await _addFlippers();
} }
@override @override

Loading…
Cancel
Save