<commit_before>import 'dart:async';
import 'dart:math' as math;

import 'package:flame/components.dart' show SpriteComponent;
import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart';

/// {@template flipper}
/// A bat, typically found in pairs at the bottom of the board.
///
/// [Flipper] can be controlled by the player in an arc motion.
/// {@endtemplate flipper}
class Flipper extends PositionBodyComponent with KeyboardHandler {
  /// {@macro flipper}
  Flipper._({
    required Vector2 position,
    required this.side,
    required List<LogicalKeyboardKey> keys,
  })  : _position = position,
        _keys = keys,
        super(size: Vector2(width, height));

  /// A left positioned [Flipper].
  Flipper.left({
    required Vector2 position,
  }) : this._(
          position: position,
          side: BoardSide.left,
          keys: [
            LogicalKeyboardKey.arrowLeft,
            LogicalKeyboardKey.keyA,
          ],
        );

  /// A right positioned [Flipper].
  Flipper.right({
    required Vector2 position,
  }) : this._(
          position: position,
          side: BoardSide.right,
          keys: [
            LogicalKeyboardKey.arrowRight,
            LogicalKeyboardKey.keyD,
          ],
        );

  static const spritePath = 'components/flipper.png';

  /// The width of the [Flipper].
  static const width = 12.0;

  /// The height of the [Flipper].
  static const height = 2.8;

  /// The speed required to move the [Flipper] to its highest position.
  ///
  /// The higher the value, the faster the [Flipper] will move.
  static const double _speed = 60;

  /// 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;

  /// 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;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    final sprite = await gameRef.loadSprite(spritePath);
    positionComponent = SpriteComponent(
      sprite: sprite,
      size: Vector2(width, height),
    );

    if (side == BoardSide.right) {
      positionComponent?.flipHorizontally();
    }
  }

  /// Applies downward linear velocity to the [Flipper], moving it to its
  /// resting position.
  void _moveDown() {
    body.linearVelocity = Vector2(0, -_speed);
  }
<commit_msg>Update lib/game/components/flipper.dart<commit_after>import 'dart:async';
import 'dart:math' as math;

import 'package:flame/components.dart' show SpriteComponent;
import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart';

/// {@template flipper}
/// A bat, typically found in pairs at the bottom of the board.
///
/// [Flipper] can be controlled by the player in an arc motion.
/// {@endtemplate flipper}
class Flipper extends PositionBodyComponent with KeyboardHandler {
  /// {@macro flipper}
  Flipper._({
    required Vector2 position,
    required this.side,
    required List<LogicalKeyboardKey> keys,
  })  : _position = position,
        _keys = keys,
        super(size: Vector2(width, height));

  /// A left positioned [Flipper].
  Flipper.left({
    required Vector2 position,
  }) : this._(
          position: position,
          side: BoardSide.left,
          keys: [
            LogicalKeyboardKey.arrowLeft,
            LogicalKeyboardKey.keyA,
          ],
        );

  /// A right positioned [Flipper].
  Flipper.right({
    required Vector2 position,
  }) : this._(
          position: position,
          side: BoardSide.right,
          keys: [
            LogicalKeyboardKey.arrowRight,
            LogicalKeyboardKey.keyD,
          ],
        );

  static const spritePath = 'components/flipper.png';

  /// The width of the [Flipper].
  static const width = 12.0;

  /// The height of the [Flipper].
  static const height = 2.8;

  /// The speed required to move the [Flipper] to its highest position.
  ///
  /// The higher the value, the faster the [Flipper] will move.
  static const double _speed = 60;

  /// 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;

  /// 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;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    final sprite = await gameRef.loadSprite(spritePath);
    positionComponent = SpriteComponent(
      sprite: sprite,
      size: size,
    );

    if (side == BoardSide.right) {
      positionComponent?.flipHorizontally();
    }
  }

  /// Applies downward linear velocity to the [Flipper], moving it to its
  /// resting position.
  void _moveDown() {
    body.linearVelocity = Vector2(0, -_speed);
  }

{'fraction_non_alphanumeric': 0.11567982456140351, 'fraction_numerical': 0.006030701754385965, 'mean_word_length': 2.6904922454484153, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3081614', 'n_tokens_mistral': 1669, 'n_tokens_neox': 1673, 'n_words': 508}