diff --git a/packages/flame_bloc/DEPRECATED_README.md b/packages/flame_bloc/DEPRECATED_README.md new file mode 100644 index 00000000000..aeebc65882f --- /dev/null +++ b/packages/flame_bloc/DEPRECATED_README.md @@ -0,0 +1,58 @@ +# Flame Bloc 🔥🧱 + +This is documentation for the deprecated version of the Flame Bloc. This API will live until the +next major version is released. + +`flame_bloc` provides easy access to blocs/cubits that are available on the widget tree to your Flame +game and makes it possible for Flame components to listen to state changes to those blocs/cubits. + +## How to use + +Lets assume we have a bloc that handles player inventory and it is available on the widget tree via +a `BlocProvider` like this: + +```dart +BlocProvider( + create: (_) => InventoryBloc(), + child: GameWidget(game: ExampleGame()), +) +``` + +To enable the features of `flame_bloc` in your game, you can make your game class inherit from +`FlameBlocGame`, or if you are already using an enhanced `FlameGame` class (like for example a +`Forge2DGame`), the `FlameBloc` mixin can be used instead. + + +To access the bloc from inside your game, the `read` method can be used. + +```dart +class ExampleGame extends FlameBlocGame { + void selectWeapon() { + read.add(WeaponSelected('axe')); + } +} +``` + +To have your components listen to state change, the `BlocComponent` mixin can be used. + + +```dart +class PlayerComponent with BlocComponent { + + // onNewState can be overriden to so the component + // can be notified on state changes + @override + void onNewState(InventoryState state) { + print(state.weapon); + } + + @override + void update(double dt) { + // the `state` getter can also be used to have + // direct access to the current state + print(state.weapon); + } +} +``` + +For a full example, check the [example folder](./example) diff --git a/packages/flame_bloc/LICENSE b/packages/flame_bloc/LICENSE index 3897c4d092d..569a5b82968 100644 --- a/packages/flame_bloc/LICENSE +++ b/packages/flame_bloc/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Blue Fire +Copyright (c) 2022 Blue Fire Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/flame_bloc/README.md b/packages/flame_bloc/README.md index 36be7290226..2c6b01905f0 100644 --- a/packages/flame_bloc/README.md +++ b/packages/flame_bloc/README.md @@ -1,55 +1,109 @@ # Flame Bloc 🔥🧱 -`flame_bloc` adds easy access to blocs/cubits that are available on the widget tree to your Flame -game and makes it possible for Flame components to listen to state changes to those blocs/cubits. +`flame_bloc` offers a simple and natural (as in similar to `flutter_bloc`) way to use blocs and +cubits inside a `FlameGame`. + +For a migration guide from the previous API to the current one, +[check this article](https://verygood.ventures/blog/flame-bloc-new-api). ## How to use -Lets assume we have a bloc that handles player inventory and it is available on the widget tree via -a `BlocProvider` like this: +Lets assume we have a bloc that handles player inventory, first we need to make it available to our +components. + +We can do that by using `FlameBlocProvider` component: ```dart -BlocProvider( - create: (_) => InventoryBloc(), - child: GameWidget(game: ExampleGame()), -) +class MyGame extends FlameGame { + @override + Future onLoad() async { + await add( + FlameBlocProvider( + create: () => PlayerInventoryBloc(), + children: [ + Player(), + // ... + ], + ), + ); + } +} ``` -To enable the features of `flame_bloc` in your game, you can make your game class inherit from -`FlameBlocGame`, or if you are already using an enhanced `FlameGame` class (like for example a -`Forge2DGame`), the `FlameBloc` mixin can be used instead. - +With the above changes, the `Player` component will now have access to our bloc. -To access the bloc from inside your game, the `read` method can be used. +If more than one bloc needs to be provided, `FlameMultiBlocProvider` can be used in a similar fashion: ```dart -class ExampleGame extends FlameBlocGame { - void selectWeapon() { - read.add(WeaponSelected('axe')); +class MyGame extends FlameGame { + @override + Future onLoad() async { + await add( + FlameMultiBlocProvider( + providers: [ + FlameBlocProvider( + create: () => PlayerInventoryBloc(), + ), + FlameBlocProvider( + create: () => PlayerStatsBloc(), + ), + ], + children: [ + Player(), + // ... + ], + ), + ); } } ``` -To have your components listen to state change, the `BlocComponent` mixin can be used. +Listening to states changes at the component level can be done with two approaches: +By using `FlameBlocListener` component: ```dart -class PlayerComponent with BlocComponent { - - // onNewState can be overriden to so the component - // can be notified on state changes +class Player extends PositionComponent { @override - void onNewState(InventoryState state) { - print(state.weapon); + Future onLoad() async { + await add( + FlameBlocListener( + listener: (state) { + updateGear(state); + }, + ), + ); } +} +``` + +Or by using `FlameBlocListenable` mixin: + +```dart +class Player extends PositionComponent + with FlameBlocListenable { @override - void update(double dt) { - // the `state` getter can also be used to have - // direct access to the current state - print(state.weapon); + void onNewState(state) { + updateGear(state); } } ``` +If all your component need is to simply access a bloc, the `FlameBlocReader` mixin can be applied +to a component: + + +```dart +class Player extends PositionComponent + with FlameBlocReader { + + void takeHit() { + bloc.add(const PlayerDamaged()); + } +} +``` + +Note that one limitation of the mixin is that it can access only a single bloc. + For a full example, check the [example folder](./example)