Flutter实现贪吃蛇小游戏

                                 **Flutter实现贪吃蛇小游戏**

在这个小游戏中,玩家需要操纵一条小蛇来吃掉屏幕上的食,随着吃食物的数量增加,小蛇的身体也会不断变长,游戏的难度也会随之增加。

首先,使用Flutter来完成这个小游戏的编译需要使用到 、Flutter提供的一些基本组件,比如Container、Text、Image等。在布局方面,使用Stack来放置小蛇、食物和背景等元素,同时使用Positioned来设置小蛇和食物位置。

接着,需要定义小蛇的移动方式,可以通过定时器来不断改变小蛇的位置来实现移动效果。同时,还需要检测小蛇和食物之间的碰撞,一旦小蛇吃到了食物,需要将其加入到小蛇的身体中,并生成新的食物。

在游戏过程中,还需要考虑玩家失败的情况,例如小蛇撞上了墙或者自己的身体,此时游戏应该即结束并显示失败的提示信息。

最后,在游戏胜利或失败后,可以通过对话框来实现用户与游戏的交互,例如提示玩家重新开始游戏或者分享游戏成绩等功能。

总体来说,使用Flutter来编译一个贪吃蛇小游戏需要涉及到多种技术,包括布局、动画、事件处理等等,但通过合理地运用Flutter提供的基本组件和功能,可以轻松编写出一个有良好交互性和用户体验的小游戏。

定义球和蛇

//球的位置
Offset _ball = Offset.zero;
//贪吃蛇的宽度
const double _snakeSize = 40;
//贪吃蛇的位置
List<Offset> _snakePosition = [
  const Offset(_snakeSize * 2, 0),
  const Offset(_snakeSize * 3, 0),
];
//计时器
late Timer _timer;
Direction _direction = Direction.up;
GameStatus _gameStatus = GameStatus.start;
//贪吃蛇的方向
enum Direction {
  up,
  down,
  left,
  right,
}

//游戏的状态
enum GameStatus {
  over,
  start,
}

绘制蛇

_buildGameStart() {
    return Stack(
      children: _snakePosition
          .map((snake) => Positioned.fromRect(
              //对每一个蛇的身子坐标进行处理
              rect: Rect.fromCenter(
                  center: adjust(snake), width: _snakeSize, height: _snakeSize),
              //从中心点绘制矩形
              child: Container(
                //设置边距为1
                margin: const EdgeInsets.all(1),
                //蛇的身子填充为绿色
                color: Colors.green,
              )))
          .toList() //将处理过的蛇身子坐标转化为静态的组件

        //蛇
        ..add(Positioned.fromRect(
            //处理小球坐标
            rect: Rect.fromCenter(
                center: adjust(_ball), width: _snakeSize, height: _snakeSize),
            child: Container(
              //设置边距为1
              margin: const EdgeInsets.all(1),
              //球的颜色填充为黑色
              color: Colors.black,
            ))),
    );
  }

将蛇移动到下一个位置

//更新蛇的位置
      List<Offset> newSnakeList = List.generate(_snakePosition.length, (index) {
        if (index > 0) {
          //蛇的身体部分保持不变
          return _snakePosition[index - 1];
        } else {
          //蛇的头部移动
          final snakeHead = _snakePosition[0];

          switch (_direction) {
            case Direction.up:
              //向上移动,y坐标减去蛇的大小
              return Offset(snakeHead.dx,
                  (snakeHead.dy - _snakeSize + maxHeight) % maxHeight);
            case Direction.down:
              //向下移动,y坐标加上蛇的大小
              return Offset(
                  snakeHead.dx, (snakeHead.dy + _snakeSize) % maxHeight);
            case Direction.left:
              //向左移动,x坐标减去蛇的大小
              return Offset((snakeHead.dx - _snakeSize + maxWidth) % maxWidth,
                  snakeHead.dy);
            case Direction.right:
              //向右移动,x坐标加上蛇的大小
              return Offset(
                  (snakeHead.dx + _snakeSize) % maxWidth, snakeHead.dy);
          }
        }
      }

吃食物

 if (newSnakeList[0] == _ball) {
        //添加一个方块
        newSnakeList.add(_snakePosition[_snakePosition.length - 1]);
        setState(() {
          _ball = randomPosition(maxWidth, maxHeight);
        });
      }

碰撞并结束游戏

//当蛇与自己相撞
      List<Offset> judgeSnakeList = List.from(newSnakeList);
      judgeSnakeList.removeAt(0);
      if (judgeSnakeList.contains(newSnakeList[0])) {
        //游戏结束
        setState(() {
          _gameStatus = GameStatus.over;
          _timer.cancel();
        });
      }
      //更新蛇的位置
      setState(() {
        _snakePosition = newSnakeList;
      }

放置按钮


  Widget build(BuildContext context) {
    return Scaffold(
      // ignore: deprecated_member_use
      body: RawKeyboardListener(
        focusNode: FocusNode(),
        autofocus: true,
        //定义一个onkey事件监听器
        onKey: (event) {
          // ignore: deprecated_member_use
          if (event.runtimeType == RawKeyDownEvent) {
            Direction newDirection = Direction.left;
            switch (event.logicalKey.keyLabel) {
              //向上按钮
              case "Arrow Up":
                if (_direction == Direction.down) {
                  return;
                }
                newDirection = Direction.up;
                break;
              //向下按钮
              case "Arrow Down":
                if (_direction == Direction.up) {
                  return;
                }
                newDirection = Direction.down;
                break;
              //向左按钮
              case "Arrow Left":
                if (_direction == Direction.right) {
                  return;
                }
                newDirection = Direction.left;
                break;
              //向右按钮
              case "Arrow Right":
                if (_direction == Direction.left) {
                  return;
                }
                newDirection = Direction.right;
                break;
            }
            //更新状态,如果方向没有改变,忽略按键事件
            setState(() {
              _direction = newDirection;
            });
          }
        },
        //根据_game Status的状态显示开始游戏的界面或是游戏结束的界面
        child: _gameStatus == GameStatus.start
            ? _buildGameStart()
            : _buildGameOver(),
      ),
      floatingActionButton: _gameStatus == GameStatus.over
          ? Container()
          : Container(
              width: 180,
              height: 240,
              child: Stack(
                alignment: Alignment.topLeft,
                children: [
                  Positioned(
                    left: 60,
                    top: 0,
                    child: Container(
                      width: 60,
                      height: 60,
                      child: IconButton(
                        padding: EdgeInsets.zero,
                        icon: const Icon(
                          Icons.arrow_circle_up_outlined,
                          size: 60,
                        ),
                        onPressed: () {
                          Direction newDirection = Direction.left;
                          if (_direction == Direction.down) {
                            return;
                          }
                          newDirection = Direction.up;
                          //更新状态,如果方向没有改变,忽略按键事件
                          setState(() {
                            _direction = newDirection;
                          });
                        },
                      ),
                    ),
                  ),
                  Positioned(
                    left: 0,
                    top: 60,
                    child: Container(
                      width: 60,
                      height: 60,
                      child: IconButton(
                        padding: EdgeInsets.zero,
                        icon: const Icon(
                          Icons.arrow_circle_left_outlined,
                          size: 60,
                        ),
                        onPressed: () {
                          Direction newDirection = Direction.left;
                          if (_direction == Direction.right) {
                            return;
                          }
                          newDirection = Direction.left;
                          //更新状态,如果方向没有改变,忽略按键事件
                          setState(() {
                            _direction = newDirection;
                          });
                        },
                      ),
                    ),
                  ),
                  Positioned(
                    left: 120,
                    top: 60,
                    child: Container(
                      width: 60,
                      height: 60,
                      child: IconButton(
                        padding: EdgeInsets.zero,
                        icon: const Icon(
                          Icons.arrow_circle_right_outlined,
                          size: 60,
                        ),
                        onPressed: () {
                          Direction newDirection = Direction.left;
                          if (_direction == Direction.left) {
                            return;
                          }
                          newDirection = Direction.right;
                          //更新状态,如果方向没有改变,忽略按键事件
                          setState(() {
                            _direction = newDirection;
                          });
                        },
                      ),
                    ),
                  ),
                  Positioned(
                    left: 60,
                    top: 120,
                    child: Container(
                      width: 60,
                      height: 60,
                      child: IconButton(
                        padding: EdgeInsets.zero,
                        icon: const Icon(
                          Icons.arrow_circle_down_outlined,
                          size: 60,
                        ),
                        onPressed: () {
                          Direction newDirection = Direction.left;
                          if (_direction == Direction.up) {
                            return;
                          }
                          newDirection = Direction.down;
                          //更新状态,如果方向没有改变,忽略按键事件
                          setState(() {
                            _direction = newDirection;
                          });
                        },
                      ),
                    ),
                  ),
                ],
              ),
            ),
    );
  }

游戏结束


```dart
//游戏结束时调用,监听用户的手势操作 其中只有一个onTap事件,用户点击屏幕时会执行一个空函数
  GestureDetector _buildGameOver() {
    return GestureDetector(
      onTap: () {},
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextButton(
              child: const Text("观看广告,继续游戏"),
              onPressed: () {
                setState(() {
                  _gameStatus = GameStatus.start;
                  reSetGame();
                });
              },
            ),
            TextButton(
              child: const Text("重新开始游戏"),
              onPressed: () {
                setState(() {
                  _gameStatus = GameStatus.start;
                  _direction = Direction.up;
                  _snakePosition = [
                    const Offset(_snakeSize * 2, 0),
                    const Offset(_snakeSize * 3, 0)
                  ];
                  reSetGame();
                });
              },
            )
          ],
        ),
      ),
    );
  }

联系方式:13916094082@163.com

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值