如何使用 GridView 或 TableView 在颤振中制作填字游戏 [英] How to make crossword type puzzle in flutter using GridView or TableView

查看:19
本文介绍了如何使用 GridView 或 TableView 在颤振中制作填字游戏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个任务,我必须制作一个类似填字游戏的东西.首先,我将向您展示我想要实现的确切图像.

I got a task in which I had to make a something like crossword puzzle. First of all, I will show you the exact image which I want to achieve.

我尝试过很多可能的方法,比如

I have tried using many possible ways like

  • 尝试使用 Flutter 中提供的 GridViewTable 小部件.

尝试将 GridView/Table 放入 GestureDetector

但问题是我无法获得用户用手指拖动的单词.字母表和正确的单词来自服务器端.此外,当用户拖动一些字母时,如果单词匹配,那么我必须在正确的单词上制作一个椭圆形,因此可能会有很多单词这么多椭圆形.这意味着我如何制作椭圆形?

but the problem is that I can't get the word on which the user dragged with his finger. The alphabets and the correct word is coming from server-side. Also when the user dragged on some alphabets then if words match then I have to make an oval shape on the correct words and so there could be many words so many oval shapes. This means that how can I make the oval shape?

使用 Positioned 或其他一些技巧?

Using Positioned or some other tricks?

我在颤振中搜索了任何可以帮助我的包,但不幸的是,我没有找到.

I searched for any packages in flutter which could help me but unfortunately, I didn't find any.

推荐答案

好的,正如我所承诺的,我有一个答案给你,我想为它的混乱程度道歉.这里已经很晚了,我想今晚把这个送给你.现在这可能不是最好的方法,但它确实有效,您绝对可以将我的代码的某些部分模块化为它们自己的函数.您可能会想要测试它,因为我确信它此时是可破坏的,并根据需要添加条件.似乎应该有一种更简单的方法来做到这一点,但我找不到,所以这就是我的选择.

Okay as promised I have an answer for you I want apologize for how messy it is. It's getting really late here and I wanted to get this to you tonight. Now this might not be this best way but it works and you could definitely modularize some parts of my code into their own functions. You are probably going to want to test this as I'm sure it is breakable at this point and add conditions as necessary. There seems like there should be an easier way to do this but I am could not find one so this is what I went with.

List<bool> isSelected = [];
  List<String> selectedLetters = [];
  Map<GlobalKey, String> lettersMap;

  Offset initialTappedPosition = Offset(0, 0);
  Offset initialPosition = Offset(0, 0);
  Offset finalPosition;

  int intialSquare;
  int crossAxisCount = 4; //whether you use GridView or not still need to provide this
  int index = -1;
  bool isTapped = false;

  String selectedWord = '';

  double width = 50;
  double height = 50;
  Size size;

  List<String> letters = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'b',
    'b',
    'b',
    'b',
    'z',
  ];

  @override
  void initState() {
    super.initState();
    lettersMap =
        Map.fromIterable(letters, key: (i) => GlobalKey(), value: (i) => i[0]);
    isSelected = List.generate(letters.length, (e) => false);
  }

  _determineWord() {
    double differnce;
    int numberOfSquares;

    if ((finalPosition.dx - initialPosition.dx) > 20) {
      print('right');

      //moved right
      differnce = finalPosition.dx - initialPosition.dx;
      numberOfSquares = (differnce / size.width).ceil();
      for (int i = intialSquare + 1;
          i < (intialSquare + numberOfSquares);
          i++) {
        isSelected[i] = true;
      }
      for (int i = 0; i < isSelected.length; i++) {
        if (isSelected[i]) {
          selectedWord += letters[i];
        }
      }
      print(selectedWord);
    } else if ((initialPosition.dx - finalPosition.dx) > 20) {
      print('left');

      // moved left
      differnce = finalPosition.dx + initialPosition.dx;
      numberOfSquares = (differnce / size.width).ceil();
      for (int i = intialSquare - 1;
          i >= (intialSquare - numberOfSquares + 1);
          i--) {
        isSelected[i] = true;
      }
      for (int i = 0; i < isSelected.length; i++) {
        if (isSelected[i]) {
          selectedWord += letters[i];
        }
      }
      print(selectedWord);
    } else if ((finalPosition.dy - initialPosition.dy) > 20) {
      //moved up when moving up/down number of squares numberOfSquares is also number of rows

      differnce = finalPosition.dy - initialPosition.dy;
      numberOfSquares = (differnce / size.height).ceil();

      for (int i = intialSquare + crossAxisCount;
          i < (intialSquare + (numberOfSquares * crossAxisCount));
          i += 4) {
        isSelected[i] = true;
      }
      for (int i = 0; i < isSelected.length; i++) {
        if (isSelected[i]) {
          selectedWord += letters[i];
        }
      }

      print(selectedWord);
    } else if ((initialPosition.dy - finalPosition.dy) > 20) {
      //moved down
      differnce = initialPosition.dy - finalPosition.dy;
      numberOfSquares = (differnce / size.height).ceil();

      for (int i = intialSquare - crossAxisCount;
          i > (intialSquare - (numberOfSquares * crossAxisCount));
          i -= 4) {
        isSelected[i] = true;
        print('$i');
      }
      for (int i = isSelected.length - 1; i >= 0; i--) {
        if (isSelected[i]) {
          selectedWord += letters[i];
        }
      }
      print(selectedWord);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(
        children: <Widget>[
          Center(
            child: Padding(
              padding: const EdgeInsets.all(30.0),
              child: GestureDetector(
                child: GridView(
                  physics: NeverScrollableScrollPhysics(), //Very Important if
// you don't have this line you will have conflicting touch inputs and with
// gridview being the child will win
                  shrinkWrap: true,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: crossAxisCount,
                    childAspectRatio: 2,
                  ),
                  children: <Widget>[
                    for (int i = 0; i != lettersMap.length; ++i)
                      Listener(
                        child: Container(
                          key: lettersMap.keys.toList()[i],
                          child: Text(
                            lettersMap.values.toList()[i],
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              color: Colors.amber,
                              fontSize: 18,
                            ),
                          ),
                        ),
                        onPointerDown: (PointerDownEvent event) {

                          final RenderBox renderBox = lettersMap.keys
                              .toList()[i]
                              .currentContext
                              .findRenderObject();
                          size = renderBox.size;
                          setState(() {
                            isSelected[i] = true;
                            intialSquare = i;
                          });
                        },
                      ),
                  ],
                ),
                onTapDown: (TapDownDetails details) {
                  //User Taps Screen
                  // print('Global Position: ${details.globalPosition}');
                  setState(() {
                    initialPosition = Offset(
                      details.globalPosition.dx - 25,
                      details.globalPosition.dy - 25,
                    );
                    initialTappedPosition = Offset(
                      details.globalPosition.dx - 25,
                      details.globalPosition.dy - 25,
                    );
                    isTapped = true;
                  });
                  // print(initialPosition);
                },
                onVerticalDragUpdate: (DragUpdateDetails details) {
                  // print('${details.delta.dy}');
                  setState(() {
                    if (details.delta.dy < 0) {
                      initialTappedPosition = Offset(initialTappedPosition.dx,
                          initialTappedPosition.dy + details.delta.dy);
                      height -= details.delta.dy;
                    } else {
                      height += details.delta.dy;
                    }
                    finalPosition = Offset(
                      details.globalPosition.dx - 25,
                      details.globalPosition.dy - 25,
                    );
                  });
                },
                onHorizontalDragUpdate: (DragUpdateDetails details) {
                  // print('${details.delta.dx}');
                  setState(() {
                    if (details.delta.dx < 0) {
                      initialTappedPosition = Offset(
                        initialTappedPosition.dx + details.delta.dx,
                        initialTappedPosition.dy,
                      );
                      width -= details.delta.dx;
                    } else {
                      width += details.delta.dx;
                    }

                    finalPosition = Offset(
                      details.globalPosition.dx - 25,
                      details.globalPosition.dy - 25,
                    );
                  });
                },
                onHorizontalDragEnd: (DragEndDetails details) {
                  _determineWord();
                },
                onVerticalDragEnd: (DragEndDetails details) {
                  _determineWord();
                },
              ),
            ),
          ),
          Positioned(
            top: initialTappedPosition.dy,
            left: initialTappedPosition.dx,
            child: Container(
              height: height,
              width: width,
              decoration: ShapeDecoration(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(30),
                  side: BorderSide(
                    color: isTapped ? Colors.blue : Colors.transparent,
                    width: 3.0,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

很高兴与您合作,希望您的项目进展顺利.如果我错过了,我试图清理所有不必要的打印语句.

Pleasure working with you hope your project goes well. I tried to clean up all the unnecessary print statements sorry if I missed any.

这篇关于如何使用 GridView 或 TableView 在颤振中制作填字游戏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆