【发布时间】:2021-12-30 14:01:11
【问题描述】:
是否可以在Flame for Flutter 中制作一个由Flutter 小部件组成的叠加层,并具有一些透明的小部件,通过叠加层可以看到游戏?
我发现可以实现透明小部件的信息 (How to create a transparent container in flutter),但我不确定它们是否可以使火焰覆盖透明。
问题更新:
这是我想要达到的目标的一个最小示例。
import 'dart:async';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Flame.device.fullScreen();
await Flame.device.setPortrait();
runApp(MainApp());
}
class MainApp extends StatelessWidget {
MainApp({Key? key}) : super(key: key);
final game = MainGame();
@override
Widget build(BuildContext context) {
return MaterialApp(
darkTheme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.deepPurple,
),
home: GameWidget(
game: game,
overlayBuilderMap: {
'MainMenu': (context, MainGame game) => MainMenu(game: game),
},
),
);
}
}
class MainGame extends FlameGame with MultiTouchTapDetector {
@override
void render(Canvas canvas) {
super.render(canvas);
Paint paint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawRect(Rect.fromPoints(const Offset(10.0, 10.0), const Offset(30.0, 30.0)), paint);
}
@override
void onTapDown(int pointerId, TapDownInfo info) {
if (!overlays.isActive('MainMenu')) {
overlays.add('MainMenu');
}
else {
overlays.remove('MainMenu');
}
super.onTapDown(pointerId, info);
}
}
class MainMenu extends StatefulWidget {
const MainMenu({Key? key, required this.game}) : super(key: key);
/// The reference to the game.
final MainGame game;
@override
_MainMenuState createState() => _MainMenuState();
}
class _MainMenuState extends State<MainMenu> with TickerProviderStateMixin {
static Duration duration = const Duration(milliseconds: 250);
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: duration)
..addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.dismissed) {
widget.game.overlays.remove('MainMenu');
}
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
void deactivate() {
//_controller.reverse(from: 1.0);
super.deactivate();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, _) {
double animationVal = _controller.value;
double translateVal = (animationVal - 1.0) * 320.0;
return Transform.translate(
offset: Offset(translateVal, 0.0),
child: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
decoration: const BoxDecoration(
color: Colors.deepPurple,
),
child: Column(
children: const <Widget>[
Text('MyApp Menu'),
],
),
),
ListTile(
title: const Text('Item 1'),
onTap: () => _controller.reverse(),
),
ListTile(
title: const Text('Item 2'),
onTap: () => _controller.reverse(),
),
]
),
),
);
},
);
}
}
在示例中,抽屉菜单滑入屏幕。按“第 1 项”按应关闭菜单。按下游戏黑色区域的其他位置,只需隐藏抽屉菜单即可关闭它。我在这里看到两个选项:
- 在隐藏菜单之前对其进行动画处理,但我不知道如何从
MainGame类中引用MainMenu类。在这种情况下,我不会调用overlays.remove,而是_controller.reverse(),它最终会调用overlays.remove。 - 制作一个透明小部件作为
MainMenu的一部分,占据屏幕的其余部分并捕获onTap事件以调用_controller.reverse()。
那么我有两个子问题:
- Drawer 小部件的源中有一个值 320。我可以得到抽屉小部件
width以便在那里放置正确的值。我不想设置抽屉的width。我希望它是默认的width。 - 我可以在抽屉的右上外边缘放置一个看起来像标签的图像或图标吗?当抽屉出来时,它会是“>”。我知道如何将图像放在游戏的角落。我不知道如何将它附加到抽屉。
另一个更新:
我根据@spydon 的回答更改了示例。现在出现了一系列新问题。这是更改后的来源:
import 'dart:async';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
final GlobalKey<ScaffoldState> _key = GlobalKey();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Flame.device.fullScreen();
await Flame.device.setPortrait();
runApp(const MainApp());
}
class MainApp extends StatefulWidget {
const MainApp({Key? key}) : super(key: key);
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
final game = MainGame();
@override
Widget build(BuildContext context) {
return MaterialApp(
darkTheme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.deepPurple,
),
home: Scaffold(
key: _key,
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
decoration: const BoxDecoration(
color: Colors.deepPurple,
),
child: Column(
children: const <Widget>[
Text('MyApp Menu'),
],
),
),
ListTile(
title: const Text('Item 1'),
onTap: () { Navigator.of(context).pop(); },
),
ListTile(
title: const Text('Item 2'),
onTap: () { Navigator.of(context).pop(); },
),
]
),
),
body: GameWidget(game: game),
),
);
}
}
class MainGame extends FlameGame with MultiTouchTapDetector {
@override
void render(Canvas canvas) {
super.render(canvas);
Paint paint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawRect(Rect.fromPoints(const Offset(10.0, 10.0), const Offset(30.0, 30.0)), paint);
}
@override
void onTapDown(int pointerId, TapDownInfo info) {
_key.currentState!.openDrawer();
super.onTapDown(pointerId, info);
}
}
【问题讨论】:
标签: flutter transparent flame