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:math' as math;
import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart';
/// {@template flipper}
@ -10,12 +12,21 @@ import 'package:pinball/game/game.dart';
///
/// [Flipper] can be controlled by the player in an arc motion.
/// {@endtemplate flipper}
class Flipper extends BodyComponent {
class Flipper extends BodyComponent with KeyboardHandler {
/// {@macro flipper}
Flipper({
required Vector2 position,
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.
paint = Paint()
..color = const Color(0xFF00FF00)
@ -33,22 +44,27 @@ class Flipper extends BodyComponent {
/// The higher the value, the faster the [Flipper] will move.
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.
///
/// A [Flipper] with [BoardSide.left] has a counter-clockwise arc motion,
/// whereas a [Flipper] with [BoardSide.right] has a clockwise arc motion.
final BoardSide side;
/// Applies downard linear velocity to the [Flipper] to move it up.
void moveDown() {
/// The initial position of the [Flipper] body.
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);
}
/// Applies upward linear velocity to the [Flipper] to move it up.
void moveUp() {
void _moveUp() {
body.linearVelocity = Vector2(0, _speed);
}
@ -120,6 +136,22 @@ class Flipper extends BodyComponent {
super.onMount();
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}

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

Loading…
Cancel
Save