flame_riverpod 1.1.0+1 flame_riverpod: ^1.1.0+1 copied to clipboard
Widgets, providers, and an example project for using Riverpod in conjunction with Flame.
import 'dart:async';
import 'package:flame/components.dart' hide Timer;
import 'package:flame_riverpod/flame_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final countingStreamProvider = StreamProvider<int>((ref) {
return Stream.periodic(const Duration(seconds: 1), (inc) => inc);
});
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
const Expanded(child: FlutterCountingComponent()),
Expanded(
child: RiverpodGameWidget.initialiseWithGame(
uninitialisedGame: (ref) => RefExampleGame(ref)))
]),
);
}
}
class FlutterCountingComponent extends ConsumerWidget {
const FlutterCountingComponent({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final textStyle =
Theme.of(context).textTheme.headline5?.copyWith(color: Colors.white);
final stream = ref.watch(countingStreamProvider);
return Material(
color: Colors.transparent,
child: Column(
children: [
Text('Flutter', style: textStyle),
stream.when(
data: (value) => Text('$value', style: textStyle),
error: (error, stackTrace) => Text('$error', style: textStyle),
loading: () => Text('Loading...', style: textStyle))
],
),
);
}
}
class RefExampleGame extends RiverpodAwareFlameGame {
RefExampleGame(super.ref);
@override
onLoad() async {
await super.onLoad();
add(TextComponent(text: 'Flame'));
add(RiverpodAwareTextComponent(ref));
}
}
class RiverpodAwareTextComponent extends PositionComponent
with RiverpodComponentMixin {
// ComponentRef is a wrapper around WidgetRef and exposes
// a subset of its API.
RiverpodAwareTextComponent(ComponentRef ref) {
this.ref = ref;
}
late TextComponent textComponent;
int currentValue = 0;
/// [onMount] should be used over [onLoad], as subscriptions are cancelled
/// inside [onRemove], which is only called if the [Component] was mounted.
@override
Future<void> onMount() async {
await super.onLoad();
add(textComponent = TextComponent(position: position + Vector2(0, 27)));
listen(countingStreamProvider, (p0, p1) {
if (p1.hasValue) {
currentValue = p1.value!;
textComponent.text = '$currentValue';
}
});
}
}