通过滑动(运动事件)颤动多个字母选择
flutter multiple letter selection by sliding ( motion event )
我需要通过拖动字母来创建单词。
我搜索但找不到足够的代码来检测运动事件。
我想用手指轻扫 select 多个字母,并从 select 编辑的字母创建单词。
我需要制作一个如下所示的文字益智游戏。
我怎样才能制作这样的游戏?
您应该试用 GestureDetector 并使用其平移 drags gesture in Flutter
为此,您只需将 GestureDetector 作为持有字母的圆形 Widget 的父级并检测被拖动的内容。
我想这正是您想要的。
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:flutter/services.dart';
class DrawPatternGame extends StatefulWidget {
const DrawPatternGame({Key? key}) : super(key: key);
@override
State<DrawPatternGame> createState() => _DrawPatternGameState();
}
class _DrawPatternGameState extends State<DrawPatternGame> {
List<String> stringList = ["E", "L", "A", "K", "İ", "N", "U", "G"];
List<String> selectedLetter = [];
double radius = 80;
List<Offset> endLineOffsetList = [];
List<Offset> letterOffsetList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Draw Game"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: 300,
color: Colors.green,
child: Center(
child: Container(
padding: selectedLetter.isNotEmpty
? EdgeInsets.fromLTRB(8, 8, 8, 0)
: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.pink, borderRadius: BorderRadius.circular(32)),
child: Text(
selectedLetter.toSet().join(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
letterSpacing: 8,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
)),
),
Center(
child: GestureDetector(
onPanStart: (details) {
Offset correctedOffset = Offset(details.localPosition.dx - 104,
details.localPosition.dy - 104);
for (var i = 0; i < letterOffsetList.length; i++) {
if ((correctedOffset - (letterOffsetList[i])).distance < 24 &&
!selectedLetter.contains(stringList[i])) {
selectedLetter.add(stringList[i]);
print(stringList[i]);
endLineOffsetList
..add(letterOffsetList[i])
..add(letterOffsetList[i]);
setState(() {});
letterOffsetList = [];
break;
}
}
},
onPanUpdate: (details) {
if (endLineOffsetList.isNotEmpty &&
selectedLetter.length < stringList.length) {
Offset correctedOffset = Offset(
details.localPosition.dx - 104,
details.localPosition.dy - 104);
endLineOffsetList[endLineOffsetList.length - 1] =
correctedOffset;
for (var i = 0; i < letterOffsetList.length; i++) {
if ((correctedOffset - (letterOffsetList[i])).distance <
24 &&
!selectedLetter.contains(stringList[i])) {
endLineOffsetList[endLineOffsetList.length - 1] =
letterOffsetList[i];
selectedLetter.add(stringList[i]);
endLineOffsetList.add(letterOffsetList[i]);
print(stringList[i]);
Feedback.forTap(context);
break;
}
}
setState(() {});
letterOffsetList = [];
}
},
onPanEnd: (details) {
selectedLetter = [];
endLineOffsetList = [];
setState(() {});
},
child: Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius: radius + 32,
),
CustomPaint(
painter: LinePainter(endLineOffsetList: endLineOffsetList),
),
...List.generate(
stringList.length,
(i) {
letterOffsetList.add(Offset(
radius *
math.cos(2 * i * math.pi / stringList.length),
radius *
math.sin(2 * i * math.pi / stringList.length)));
return Transform.translate(
offset: letterOffsetList[i],
child: CircleAvatar(
backgroundColor:
selectedLetter.contains(stringList[i])
? Colors.pink
: null,
child: SizedBox(
width: 32,
height: 32,
child: Text(
stringList[i],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
),
);
},
)
],
),
),
)
],
),
);
}
}
class LinePainter extends CustomPainter {
final List<Offset>? endLineOffsetList;
LinePainter({this.endLineOffsetList});
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.pink
..strokeWidth = 5
..strokeCap = StrokeCap.round;
if (endLineOffsetList != null && endLineOffsetList!.length >= 2) {
for (var i = 0; i < endLineOffsetList!.length - 1; ++i) {
canvas.drawLine(
endLineOffsetList![i], endLineOffsetList![i + 1], paint);
}
}
}
@override
bool shouldRepaint(LinePainter oldDelegate) => true;
@override
bool shouldRebuildSemantics(LinePainter oldDelegate) => true;
}
我需要通过拖动字母来创建单词。
我搜索但找不到足够的代码来检测运动事件。
我想用手指轻扫 select 多个字母,并从 select 编辑的字母创建单词。
我需要制作一个如下所示的文字益智游戏。
您应该试用 GestureDetector 并使用其平移 drags gesture in Flutter
为此,您只需将 GestureDetector 作为持有字母的圆形 Widget 的父级并检测被拖动的内容。
我想这正是您想要的。
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:flutter/services.dart';
class DrawPatternGame extends StatefulWidget {
const DrawPatternGame({Key? key}) : super(key: key);
@override
State<DrawPatternGame> createState() => _DrawPatternGameState();
}
class _DrawPatternGameState extends State<DrawPatternGame> {
List<String> stringList = ["E", "L", "A", "K", "İ", "N", "U", "G"];
List<String> selectedLetter = [];
double radius = 80;
List<Offset> endLineOffsetList = [];
List<Offset> letterOffsetList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Draw Game"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: 300,
color: Colors.green,
child: Center(
child: Container(
padding: selectedLetter.isNotEmpty
? EdgeInsets.fromLTRB(8, 8, 8, 0)
: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.pink, borderRadius: BorderRadius.circular(32)),
child: Text(
selectedLetter.toSet().join(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
letterSpacing: 8,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
)),
),
Center(
child: GestureDetector(
onPanStart: (details) {
Offset correctedOffset = Offset(details.localPosition.dx - 104,
details.localPosition.dy - 104);
for (var i = 0; i < letterOffsetList.length; i++) {
if ((correctedOffset - (letterOffsetList[i])).distance < 24 &&
!selectedLetter.contains(stringList[i])) {
selectedLetter.add(stringList[i]);
print(stringList[i]);
endLineOffsetList
..add(letterOffsetList[i])
..add(letterOffsetList[i]);
setState(() {});
letterOffsetList = [];
break;
}
}
},
onPanUpdate: (details) {
if (endLineOffsetList.isNotEmpty &&
selectedLetter.length < stringList.length) {
Offset correctedOffset = Offset(
details.localPosition.dx - 104,
details.localPosition.dy - 104);
endLineOffsetList[endLineOffsetList.length - 1] =
correctedOffset;
for (var i = 0; i < letterOffsetList.length; i++) {
if ((correctedOffset - (letterOffsetList[i])).distance <
24 &&
!selectedLetter.contains(stringList[i])) {
endLineOffsetList[endLineOffsetList.length - 1] =
letterOffsetList[i];
selectedLetter.add(stringList[i]);
endLineOffsetList.add(letterOffsetList[i]);
print(stringList[i]);
Feedback.forTap(context);
break;
}
}
setState(() {});
letterOffsetList = [];
}
},
onPanEnd: (details) {
selectedLetter = [];
endLineOffsetList = [];
setState(() {});
},
child: Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius: radius + 32,
),
CustomPaint(
painter: LinePainter(endLineOffsetList: endLineOffsetList),
),
...List.generate(
stringList.length,
(i) {
letterOffsetList.add(Offset(
radius *
math.cos(2 * i * math.pi / stringList.length),
radius *
math.sin(2 * i * math.pi / stringList.length)));
return Transform.translate(
offset: letterOffsetList[i],
child: CircleAvatar(
backgroundColor:
selectedLetter.contains(stringList[i])
? Colors.pink
: null,
child: SizedBox(
width: 32,
height: 32,
child: Text(
stringList[i],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
),
);
},
)
],
),
),
)
],
),
);
}
}
class LinePainter extends CustomPainter {
final List<Offset>? endLineOffsetList;
LinePainter({this.endLineOffsetList});
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.pink
..strokeWidth = 5
..strokeCap = StrokeCap.round;
if (endLineOffsetList != null && endLineOffsetList!.length >= 2) {
for (var i = 0; i < endLineOffsetList!.length - 1; ++i) {
canvas.drawLine(
endLineOffsetList![i], endLineOffsetList![i + 1], paint);
}
}
}
@override
bool shouldRepaint(LinePainter oldDelegate) => true;
@override
bool shouldRebuildSemantics(LinePainter oldDelegate) => true;
}