* Game as a component * Fix component stories * Effects are now components * Update effects docs * Handle swap of parent * Fix reAddChildren * Wait for children to be added * BaseComponent and PositionComponent to be non-abstract * Simplify HasGameRef * Revert so that onLoad can be null * Fix example description * Effects as components * Remove gameRef from addChildren * Fix hasGameRef * Start migrating effects * Updated comments of effect fields * Fix comments * Continue to fix sequence and combined effects * Upgrade ordered_set * Fix position_component_test * BaseComponent -> Component * Fix combined and sequence effects * Await components to be added in tests * Remove unnecessary game.update in tests * Fix some tests related to composition * BaseGame should be used in examples * Fix CombinedEffect test * Keyboard code to be based on Component * Fix keyboard tests * Fix analyze problems * Fix sequence_effect * Fix combined_effect_test * Store peak state instead of end state * Fix sequence_effect tests * Update tutorial * Fix tutorial 1 * Remove SimplePositionComponentEffect * Remove unused test variable * Update docs * Removed onMount * Remove onMount * Add missing dartdoc * Fix dart docs * Add super.update where needed * Move reAddChildren to component * Reorganize method order in game widget * preOffset -> initialDelay, postOffset -> peakDelay * Introduce component.onParentChange * Remove tests in wrong file * Fix composed component test * Add game lifecycle test * Use BaseGame for mouse cursor test * Oxygen should (?) not call super.update * Use BaseGame in keyboard_test * Fix onLoad to be properly cached * Re-add unintentionally removed override * Fix info for collision detection tests * Add test for correct lifecycle on parent change * Fix particles example * Add component lifecycle diagram to the docs * Add docs for the game lifecycle * onRemove should be called when a game is removed from the widget * Fix analyze errors * prepare should be called from the component itself, not its parent * Fix dartdoc * onParentChange -> onMount * onMount should have void as return type * Simplify the loaderFuture in GameWidget * Fix mock_canvas * Fix rebase problem * Remove asComponent * Less complex _loaderFuture * Add super.update to no_fcs parallax example * Fix async tests * Revert _loaderFuture * Fix analyze issues * await gameWithCollidables * Keep epsilon small where it can be * tappable methods should return bool * Game lifecycle is now the same as for Component * Remove mustCallSuper from component.update * Make onLoadCache protected * @internal on onLoadCache * Cache/Memoize debugPaint and debugTextPaint * Fix imports * Fix comments * Always call super.onLoad so that mixins can override it * Add forgotten super.onLoad * Bump coverage percentage * HasCollidables should override update * Fix Game comments * Fix some dartdoc * Apply suggestions from code review Co-authored-by: Erick <erickzanardoo@gmail.com> * Game + Loadable as mixins * Update packages/flame/lib/src/game/game_widget/game_widget.dart Co-authored-by: Luan Nico <luanpotter27@gmail.com> * Update loadable docs * Fix comments * Move fps_counter * Fix keyboard example * Fix dartdoc * Remove tutorials temporarily * Fix game lowlevel graph * Fix resize issue Co-authored-by: Erick <erickzanardoo@gmail.com> Co-authored-by: Luan Nico <luanpotter27@gmail.com>
4.2 KiB
Other inputs
This includes documentation for input methods besides keyboard and mouse.
For other input documents, see also:
- Gesture Input: for mouse and touch pointer gestures
- Keyboard Input: for keystrokes
Joystick
Flame provides a component capable of creating a virtual joystick for taking input for your game.
To use this feature, you need to create a JoystickComponent, configure it the way you want, and
add it to your game.
Check this example to get a better understanding:
class MyGame extends FlameGame with HasDraggableComponents {
MyGame() {
joystick.addObserver(player);
add(player);
add(joystick);
}
@override
Future<void> onLoad() async {
super.onLoad();
final image = await images.load('joystick.png');
final sheet = SpriteSheet.fromColumnsAndRows(
image: image,
columns: 6,
rows: 1,
);
final joystick = JoystickComponent(
knob: SpriteComponent(
sprite: sheet.getSpriteById(1),
size: Vector2.all(100),
),
background: SpriteComponent(
sprite: sheet.getSpriteById(0),
size: Vector2.all(150),
),
margin: const EdgeInsets.only(left: 40, bottom: 40),
);
final player = Player(joystick);
add(player);
add(joystick);
}
}
class JoystickPlayer extends SpriteComponent with HasGameRef {
/// Pixels/s
double maxSpeed = 300.0;
final JoystickComponent joystick;
JoystickPlayer(this.joystick)
: super(
size: Vector2.all(100.0),
) {
anchor = Anchor.center;
}
@override
Future<void> onLoad() async {
super.onLoad();
sprite = await gameRef.loadSprite('layers/player.png');
position = gameRef.size / 2;
}
@override
void update(double dt) {
super.update(dt);
if (joystick.direction != JoystickDirection.idle) {
position.add(joystick.velocity * maxSpeed * dt);
angle = joystick.delta.screenAngle();
}
}
}
So in this example, we create the classes MyGame and Player. MyGame creates a joystick which is
passed to the Player when it is created. In the Player class we act upon the current state of
the joystick.
The joystick has a few fields that change depending on what state it is in. These are the fields that should be used to know the state of the joystick:
intensity: The percentage [0.0, 1.0] that the knob is dragged from the epicenter to the edge of the joystick (orknobRadiusif that is set).delta: The absolute amount (defined as aVector2) that the knob is dragged from its epicenter.velocity: The percentage, presented as aVector2, and direction that the knob is currently pulled from its base position to a edge of the joystick.
If you want to create buttons to go with your joystick, check out
MarginButtonComponent.
A full examples of how to use it can be found here. And it can be seen running here.
HudButtonComponent
A HudButtonComponent is a button that can be defined with margins to the edge of the Viewport
instead of with a position. It takes two PositionComponents. button and buttonDown, the first
is used for when the button is idle and the second is shown when the button is being pressed. The
second one is optional if you don't want to change the look of the button when it is pressed, or if
you handle this through the button component.
As the name suggests this button is a hud by default, which means that it will be static on your
screen even if the camera for the game moves around. You can also use this component as a non-hud by
setting hudButtonComponent.isHud = false;.
If you want to act upon the button being pressed (which would be the common thing to do) you can either pass in
a callback function as the onPressed argument, or you extend the component and override
onTapDown, onTapUp and/or onTapCancel and implement your logic in there.
Gamepad
Flame has a separate plugin to support external game controllers (gamepads), checkout here for more information.