使用Flutter Widget开发游戏”是男人就坚持100秒“,一套代码横跨6端~

简介: 在文章里我说要用Widget再来做一次。现在兑现我的承诺,并且上周日在B站直播了整个开发过程

在Flutter里展示Sprite动画


请看这篇文章《手写一个在Flutter里展示”精灵图“的Widget》


飞机的移动


首先将飞机放置在画面正中,由于Widget的原点统一为左上角,所以要减去飞机图像宽和高的一半。


//获得画布的宽高
Size screenSize = window.physicalSize/window.devicePixelRatio;
//将飞机的x,y坐标设定为画面中心
playerLeft = screenSize.width/2-66/2;
playerTop = screenSize.height/2-82/2;


飞机我们需要捕获到用户的手势事件,使用GestureDetector这个Widget来拖动飞机。


GestureDetector( 
  onPanUpdate: (DragUpdateDetails details) {
    setState(() {
      playerLeft += details.delta.dx;
      playerTop += details.delta.dy;
    });
  },
  child://飞机的Widget
}


image.png


设定FPS


由于没有使用游戏引擎,所以只好自己通过定时器来实现。比如我们要实现60FPS的刷新率,可以将定时器设置为17毫秒,这样的话刷新率约等于59fps。当然可以更精确一些,但没有那个必要。


Timer.periodic(Duration(milliseconds: 17), (timer) {
  gameloop();
});
gameloop(){
    setState(() {
        //触发build方法
    });
}


不过我这里建议设置为每20毫秒刷新一次,原因在后面会讲。


添加子弹


我们建立一个子弹管理数组,将所有子弹的数据都放在数组中


List bulletsData = [];
addBullet(){
    double bulletX;
    double bulletY;
    if (Random().nextBool()) {
      bulletX = Random().nextDouble() * (screenSize.width + bulletSize.width) -
          bulletSize.width;
      bulletY = Random().nextBool() ? -bulletSize.height : screenSize.height;
    } else {
      bulletX = Random().nextBool() ? -bulletSize.width : screenSize.width;
      bulletY = Random().nextDouble() * (screenSize.height + bulletSize.height) -
          bulletSize.height;
    }
    bulletsData.add({
      "x":bulletX,
      "y":bulletY,
      "speed": (1+gameTime/10) + Random().nextDouble()*3,
      "angle": atan2(((bulletY + bulletSize.height/2) - (playerTop + playerHeight / 2)),
          ((bulletX + bulletSize.width) - (playerLeft + playerWidth / 2)))
    });
}


子弹移动


gameloop中遍历数组对子弹进行移动。


for (int i = bulletsData.length - 1; i >= 0; i--) {
      var bulletItem = bulletsData[i];
      double angle = bulletItem["angle"];
      double speed = bulletItem["speed"];
      bulletItem["x"] -= cos(angle) * speed;
      bulletItem["y"] -= sin(angle) * speed;
      if (isHitPlayer(bulletItem["x"], bulletItem["y"])) {
        print("gameOver");
        gameOver();
      }
      if (isNotInScreen(bulletItem["x"], bulletItem["y"])) {
        print("bullet removed");
        bulletsData.removeAt(i);
        continue;
      }
    }
}


子弹展示


上述代码完成后,我们的子弹在数据中就存在了。但是你看不见它们,因为他们没有被绘制到画面中。我们需要利用StackPositioned控件来展示它们。


Stack(
  children: getBulletsWidget(),
)
getBulletsWidget(){
    List<Positioned> bullets = [];
    for(int i = 0;i<bulletsData.length;i++){
      var bulletItem = bulletsData[i];
      // print(bulletItem);
      var bulletWidget = Positioned(
        left: bulletItem["x"],
        top: bulletItem["y"],
        child: bulletImage
      );
      bullets.add(bulletWidget);
    }
    return bullets;
}


image.png


按秒计时


既然游戏标题叫“是男人就坚持100秒”,那游戏中肯定需要一个按秒的计时器。还记得前面为什么我建议将计时器的刷新频率设置为20毫秒吗?这样的话,我们每刷新50次是不是就是1秒钟呢?


Timer.periodic(Duration(milliseconds: 20), (timer) {
  if(timer.tick%50==0){
    gameSeconds+=1;
    //seconds
  }
  loop();
});


在Flutter里我们可以这样做,timer里的tick是一个计时器的执行计数,会不断累计,所以我们只需要对50取余,每次整除50的时候就是1秒钟啦~


跨端


借助Flutter强大的跨端能力,这个游戏我们可以...


运行在Mac桌面


flutter run -d macOS


image.png


运行在浏览器


flutter run -d Chrome


image.png


运行在iOS


flutter run -d 模拟器ID


image.png


还有Linux,Windows,Android我就不一一给大家截图了

项目已开源,请自行运行吧!


相关文章
|
2月前
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
23 1
|
23天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
163 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
122 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
164 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
88 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
26天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
48 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
34 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
Dart Android开发
flutter开发中的几个小技巧
我的tabBar有一个StatelessWidget小部件,其中包含2个statefulWidgets。事实是,当单击管理器以查看我的所有选项卡时(默认情况下在我的第一个选项卡上登陆),tab1小部件生成器一直被调用。
170 0
|
Android开发
flutter开发小技巧
flutter - URL出现在网站名称的位置 从Android Studio运行时:
180 0
|
容器
flutter开发小技巧
粘性标题效果 带有粘性标题的每个部分都应该是带有 SliverPinnedHeader 和 SliverList 的多条。然后将 pushPinnedChildren 设置为 true 应该会提供您正在寻找的粘性标题效果。
177 0

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 4
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 5
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
  • 6
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    flutter3-wetrip跨平台自研仿携程app预约酒店系统模板
  • 9
    通过外部链接启动 Flutter App(详细介绍及示例)
  • 10
    Flutter 61: 图解基本 Button 按钮小结 (一)