Flutter 网格视图构建器

Flutter Grid View builder

我正在开发这款与 Principe of Qix 游戏相同的简单游戏。

我成功地让我的对象按照我想要的方式移动,现在我需要在对象移动时感受场,例如当对象移动到位置 142 时对象位于位置 161,那么块 161 应该是彩色的。

我正在使用这个网格视图让对象移动 这是反对移动的方法

//Movemoent Functions
  void moveUp() {
    if (myField.contains(playerPosition - numberInRow)) {
      setState(() {
        playerPosition -= numberInRow;
      });
    }
  }

  void moveDown() {
    if (myField.contains(playerPosition + numberInRow)) {
      setState(() {
        playerPosition += numberInRow;
      });
    }
  }

  void moveLeft() {
    if (myField.contains(playerPosition)) {
      if (leftCorner.contains(playerPosition)) {
      } else {
        setState(() {
          playerPosition--;
        });
      }
    }
  }

  void moveRight() {
    if (myField.contains(playerPosition)) {
      if (rightCorner.contains(playerPosition)) {
      } else {
        setState(() {
          playerPosition++;
        });
      }
    }
  }

对于 UI 我是这样建立我的领域的

Expanded(
                flex: 5,
                child: GridView.builder(
                  physics: const NeverScrollableScrollPhysics(),
                  itemCount: numberOfSquares,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: numberInRow,
                  ),
                  itemBuilder: (context, index) {
                    if (playerPosition == index) {
                      return MyPixel(
                        color: Colors.transparent,
                        child: const Myplayer(),
                      );
                    } else {
                      return MyPixel(
                        color: Colors.transparent,
                        child: Text(index.toString()),
                      );
                    }
                  },
                ),
              ),

我正在使用从 0 到 170 的所有数字的列表来移动 myField 是一个列表。

完整小部件:

class Mygame extends StatefulWidget {
  const Mygame({Key? key}) : super(key: key);
  static String route = "mygame";
  @override
  State<Mygame> createState() => _MygameState();
}

class _MygameState extends State<Mygame> {
  //variables
  static int numberInRow = 19;
  int numberOfSquares = numberInRow * 10;
  int playerPosition = Random().nextInt(171);
  String direction = "right";
  Color color = const Color.fromARGB(0, 250, 250, 250);
  //variables
  //
  //Functions
  void startgame() {
    Timer.periodic(
      const Duration(milliseconds: 1000),
      (timer) {
        switch (direction) {
          case "up":
            moveUp();
            break;
          case "down":
            moveDown();
            break;
          case "left":
            moveLeft();
            break;
          case "right":
            moveRight();
            break;
        }
      },
    );
  }

  //Functions

  //Movemoent Functions
  void moveUp() {
    if (myField.contains(playerPosition - numberInRow)) {
      setState(() {
        playerPosition -= numberInRow;
      });
    }
  }

  void moveDown() {
    if (myField.contains(playerPosition + numberInRow)) {
      setState(() {
        playerPosition += numberInRow;
      });
    }
  }

  void moveLeft() {
    if (myField.contains(playerPosition)) {
      if (leftCorner.contains(playerPosition)) {
      } else {
        setState(() {
          playerPosition--;
        });
      }
    }
  }

  void moveRight() {
    if (myField.contains(playerPosition)) {
      if (rightCorner.contains(playerPosition)) {
      } else {
        setState(() {
          playerPosition++;
        });
      }
    }
  }
  //Movemoent Functions

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          decoration: const BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/bg.png"),
              fit: BoxFit.cover,
            ),
          ),
          child: Column(
            children: [
              Expanded(
                flex: 5,
                child: GridView.builder(
                  physics: const NeverScrollableScrollPhysics(),
                  itemCount: numberOfSquares,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: numberInRow,
                  ),
                  itemBuilder: (context, index) {
                    if (playerPosition == index) {
                      return MyPixel(
                        color: Colors.transparent,
                        child: const Myplayer(),
                      );
                    } else {
                      return MyPixel(
                        color: Colors.transparent,
                        child: Text(index.toString()),
                      );
                    }
                  },
                ),
              ),
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Row(
                      children: [
                        RoundIconButton(
                          icon: Icons.arrow_upward,
                          onPress: () {
                            direction = "up";

                            startgame();
                          },
                        ),
                        RoundIconButton(
                          icon: Icons.arrow_downward,
                          onPress: () {
                            direction = "down";

                            startgame();
                          },
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        RoundIconButton(
                          icon: Icons.arrow_back,
                          onPress: () {
                            direction = "left";

                            startgame();
                          },
                        ),
                        RoundIconButton(
                          icon: Icons.arrow_forward,
                          onPress: () {
                            direction = "right";

                            startgame();
                          },
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

所以我通过创建一个空列表解决了这个问题,只要对象索引等于框索引,索引就会添加到列表中

if (playerPosition == index) {
if (feelField.contains(index)) {
} else {
 feelField.add(index);
 }
}

并且我创建了一个新的小部件来替换当前的小部件

import 'package:flutter/material.dart';

class FeelField extends StatelessWidget {
  const FeelField({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(1.0),
      child: Container(
        color: const Color.fromARGB(155, 244, 67, 54),
      ),
    );
  }
}

在网格视图中我返回了这个:

if (feelField.contains(index)) {
 return const FeelField();
} else {
 return MyPixel(
color: Colors.transparent,
);

UI 看起来很丑哈哈但这是一个解决方案。现在体育场看起来像这样