首页 > 其他分享 >Flutter实现贪吃蛇小游戏

Flutter实现贪吃蛇小游戏

时间:2024-03-21 14:59:00浏览次数:21  
标签:Direction return child direction Flutter 60 小游戏 贪吃蛇 newDirection

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

放置按钮

@override
  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();
                });
              },
            )
          ],
        ),
      ),
    );
  }

标签:Direction,return,child,direction,Flutter,60,小游戏,贪吃蛇,newDirection
From: https://blog.csdn.net/m0_73684468/article/details/136594495

相关文章

  • 如何在Flutter中实现一键登录
    获取到当前手机使用的手机卡号,直接使用这个号码进行注册、登录,这就是一键登录。可以借助极光官方的极光认证实现1、注册账户成为开发者2、创建应用开通极光认证(注意开通极光认证要通过实名审核)3、创建应用获取appkey、MasterSecret4、开通一键登录功能提交审核5、flu......
  • 如何在Flutter中实现支付功能?请解释一下支付宝和微信支付的集成方法
    支付宝支付:支付宝支付比较复杂的就是服务端这块,客户端比较简单,获取服务器接口生成预支付信息,调用插件传入预支付信息就可以实现支付了。1、在支付宝开放平台创建应用生成签名提交审核2、服务器端调用支付宝sdk生成订单信息3、Flutter中集成Tobias,调用服务器端接口生成订......
  • c语言运用,猜数字小游戏设计
    我们要用c语言做一个猜数字小游戏,就是在1-100的数字中随机生成一个数字,然后我们去猜测那个生成的数字。做这个游戏,那我们需要的是一个整体的思想,做一个游戏需要有哪些部分?一开始可能会没有头绪,但是只要顺着一条线的思维,想一想要做的游戏刚开始是什么样子,玩的时候是什么样子,游......
  • 社交小游戏方案大比拼:即构、声网、融云和云信的全面对比
    ​前言:上一篇文章我们主要介绍社交游戏化趋势,并分析了直播平台面临的买量贵、变现难等问题,探讨了小游戏作为新的运营变现玩法的优势。同时还列举了各大直播平台TOP5的小游戏。今天我们继续介绍小游戏系列内容,本文是该系列的第二篇文章-方案选型篇,接下来我们分享小游戏如何做技术......
  • flutter本地数据储存 sqflite
    依赖sqflite:^2.3.2#本地数据储存获取数据库路径//定义一个异步函数来获取数据库路径Future<String>getDatabasePath(StringdbName)async{//获取应用的文档目录finaldirectory=awaitgetApplicationDocumentsDirectory();//拼接路径finalpath=j......
  • C#实现贪吃蛇游戏
     定义贪吃蛇和游戏逻辑定义数据结构:创建一个类来表示贪吃蛇的每个部分(通常是一个具有X和Y坐标的结构体或类)。定义游戏状态:包括蛇的位置、方向、长度以及食物的位置。处理键盘输入:重写窗体的键盘事件处理函数,以便玩家可以使用键盘控制蛇的移动方向。更新游戏状态:在每个游戏循......
  • flutter中Map<String, dynamic>与Map<String, String>的区别
    在Flutter中,Map<String,dynamic>和Map<String,String>都是Map类型的数据结构,但它们之间有一些重要的区别: 1.Map<String,dynamic>:这种Map的值可以是任何类型,包括基本数据类型(如int,double,String等),List,Map以及自定义对象。使用dynamic类型会导致更灵活的数据处理,但在编码时......
  • flutter 嵌套web网页
    添加依赖flutter_inappwebview:^6.0.0#嵌套网页代码classPictureWebUrlextendsStatefulWidget{finalStringweburl;PictureWebUrl({Key?key,requiredthis.weburl}):super(key:key);@overrideState<PictureWebUrl>createState()=>_PictureW......
  • Flutter开发多端天气预报App:一场奇妙的编程之旅
    在这个信息爆炸的时代,我们渴望获取最新的天气信息,以便更好地规划我们的生活。而作为程序员的我们,又怎能错过用技术手段打造一款个性化、便捷的天气预报App呢?在本篇博客中,我将带你踏上一场奇妙的编程之旅,使用Flutter框架开发一款支持多端的天气预报App。前言作为一名小白,你......
  • Flutter安装
    文档地址:https://docs.flutter.dev/get-started/install/windows/mobile?tab=download#later-starthttps://flutter.cn/community/china下载地址:https://docs.flutter.dev/release/archive?tab=windowshttps://flutter.cn/docs/release/archive?tab=windows1.下载Flutter......