【问题标题】:flutter multiple letter selection by sliding ( motion event )通过滑动(运动事件)颤动多个字母选择
【发布时间】:2020-04-23 23:51:45
【问题描述】:

我需要通过拖动字母来创建单词。 我搜索但找不到足够的代码来检测运动事件。 我想通过用手指滑动来选择多个字母并从选定的字母中创建单词。 我需要制作一个像下面这样的文字益智游戏。 我怎样才能制作这样的游戏?

【问题讨论】:

    标签: flutter multi-select flutter-animation motion sliding


    【解决方案1】:

    我想这正是你想要的。

    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;
    }
    

    【讨论】:

    • 请在您的回答中提供一些代码。不接受仅链接答案。
    【解决方案2】:

    您应该试验一下 GestureDetector 并使用它的 pan drags gesture in Flutter

    为此,您只需将 GestureDetector 作为持有字母的圆形 Widget 的父级并检测被拖动的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多