前言

给大家带来一个更劲爆的知识点—— Flutter开发游戏。是的,没错,Flutter也可以用来开发游戏了。有人会问不懂Unity或者Cocos2d也能用Flutter开发游戏吗???是的,你没看错,Flutter就是这么666。

我在pub.dev上面找到了一些有关游戏的第三方开源库,使用它们你就可以轻而易举的实现你的游戏梦(你要说开发王者荣耀、吃鸡那种大型游戏的话就当我前面的话没说)。下面开始今天的干货分享。

1

添加依赖包

首先在pubspec.yaml 里面添加依赖包,如下所示:

dependencies:flutter:sdk: flutterflame: ^0.17.2box2d_flame: ^0.4.4sensors: ^0.4.1+1

2

在main.dart中添加相关设置要素

接下来看看 main.dart 里面的代码,如下所示:

 1import 'dart:async'; 2import 'package:flame/util.dart'; 3import 'package:flutter/material.dart'; 4import 'package:flutter/services.dart'; 5import 'game.dart'; 6 7void main() async { 8  // 启动游戏前要先设置flame的相关属性 9  await setupFlame();10  var game = new FlutterGame();11  runApp(game.widget);12}1314/// 构建Flame所需要的属性设置15Future setupFlame() async {16  // 创建 Util对象17  var flameUtil = Util();18  // 设置全屏19  await flameUtil.fullScreen();20  // 固定为纵向位置,不允许旋转21  await flameUtil.setOrientation(DeviceOrientation.portraitUp);22}

▲ 左右滑动查看更多

首先解释一下每个包的作用:

// MD组件import 'package:flutter/material.dart';

// 我们需要Flame构建游戏import 'package:flame/util.dart';

// setupFlame() 方法中需要用到import 'package:flutter/services.dart';

// 异步支持import 'dart:async';

// 具体的游戏界面import 'FlutterGame.dart';

main()函数用了一个async表示异步,因为这涉及到里面的“setupFlame()”函数。setupFlame()函数是一个异步的,它里面主要是构建Flame所需要的属性设置,我们在启动游戏前要先设置flame的相关属性。

setupFlame() 函数里面做了3件事:

● 创建 Util对象

● 设置全屏

● 固定为纵向位置,不允许旋转

3

游戏部分的代码

接下来看看 game.dart 里面的代码,如下所示:

 1import 'dart:ui'; 2 3import 'package:box2d_flame/box2d.dart'; 4import 'package:flame/flame.dart'; 5import 'package:flame/game.dart'; 6 7class FlutterGame extends Game { 8  static const int WORLD_POOL_SIZE = 100; 9  static const int WORLD_POOL_CONTAINER_SIZE = 10;1011  World world;1213  final Vector2 _gravity = Vector2.zero();1415  FlutterGame() {16    world = new World.withPool(17      _gravity,18      DefaultWorldPool(WORLD_POOL_SIZE, WORLD_POOL_CONTAINER_SIZE),19    );20    initialize();21  }2223  Future initialize() async {24    resize(await Flame.util.initialDimensions());25  }2627  void resize(Size size) {28    super.resize(size);29  }3031  @override32  void render(Canvas canvas) {33  }3435  @override36  void update(double t) {37  }38}

▲ 左右滑动查看更多

解释一下上面的代码的意思:

FlutterGame类是具体游戏功能的实现,继承了Flame提供的Game类,所以可以放心大胆的写我们自己的功能,比如游戏循环或者调整大小事件等。Box2D将负责我们所有与物理相关的操作,这包括处理碰撞,加速/减速物体/质量以及模拟我们游戏中的不同形状/材料。

World是主要物理对象。

gravity 设置向量为0 表示无重力(gravity),Vector2你可以把它看做是平面二维坐标系统内的一个点,每个Vector2都有一个X和一个Y值。我们的gravity向量坐标值为(0,0)手机坐标系统左上角为(0,0),上部水平向右x轴正方向,左侧垂直向下位y轴正方向重力设置位(0,1)表示元素从屏幕顶部掉落到底部。

Box2D 需要用到 这两个常量值,这里面定义了两个,分别是:WORLD_POOL_SIZE和WORLD_POOL_CONTAINER_SIZE。

然后使用World.withPool创建World对象。

接下来调用initialize()方法,初始化我们所有需要的东西,包括:需要调整大小和不需要调整大小的东西。然后它的返回值调用Flame的初始化的方法,一旦Flutter准备就绪,立即调用resize()方法检查显示尺寸。

接下来看看几个函数的说明:

● render:在画布上绘制元素。

● update: 目标是60fps的速度进行,这意味着在一秒内将调用该函数60次。由于并不一直是60fps的速度,time参数会告诉你自上次调用以来经过了多少时间。

4

开启引擎,绘制元素

如果你按照以上步骤都都设置好了,这时候运行程序到你的设备,你会发现是一片黑色或空白的,因为我们还没有绘制任何元素在我们的界面上面。

接下来可以试着画一点东西上去。

新增代码如下所示:

Paint paint;Size screenSize;Rect _screenRect;final int scale = 5;

void resize(Size size) {  paint = Paint();  paint.color = Color(0xffffffff);  screenSize = size;  _screenRect = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);  super.resize(size); }

void render(Canvas canvas) {  if (screenSize == null) {    return;  }  canvas.save();  canvas.scale(screenSize.width / scale);  canvas.translate(_screenRect.width/2, _screenRect.height/2);  canvas.drawCircle(Offset(0, 0), .1, paint);  canvas.restore();  }}

▲ 左右滑动查看更多

这里发生的事情如下:

首先声明一个Paint对象,它是画笔,需要它来画一些东西。

screenSize和screenRect分别用于保存屏幕大小和相关的矩形以供以后使用。在resize()方法中,通过调用Flame的相关API,获得了size和Rect,然后再分别赋值给全局变量screenSize和screenRect。

定义一个比例因子(scale)这个变量来增加我们的应用程序中的元素。后面我们在物理交互中需要用到它。

render()函数内部主要是绘制的过程:

设置screenSize属性,确保我们准备好绘制了。然后保存画布。

调用scale()方法,设置缩放。使用屏幕的宽度除以比例因子,screenSize.width / scale,然后作为参数传入scale()方法。

使用translate()方法将画布的(0,0)点移动到屏幕中心位置。

使用drawCircle()方法,我们使用画图对象在(0,0)处绘制半径为0.1的圆

调用restore()方法将完成我们的渲染循环,仅显示一帧。

立即启动应用程序,应在屏幕中心附近绘制一个小圆圈,如下图所示:

最后我们把绘制部分的代码修改一下,加上重力传感器的代码,最终效果是这样的(具体的请进入Github查看源码),如下图所示:

5

源码及总结

本文的源码来自于GitHub:        

https://github.com/Dev-Owl/Mazeball

最后来一点我的一些个人总结和说明:当然前面这些看似比较基础,但是只要你用心学习,多看看相关API介绍,也可以用它做其它的复杂的的游戏或其他功能,比如:连连看、俄罗斯方块、是男人就下100层、超级玛丽、愤怒的小鸟、接方块、摩拜单车APP的贴纸功能等。当然具体的业务逻辑需要你自己的思考,所有的具体业务功能点都是在核心API的基础之上不断完善的,这里只是给出一些可以研究的相关的方向,感兴趣的朋友们可以试着做一下,这里就不逐个列举了。

---END---转发至朋友圈,是绝对的真爱

让我知道你在看

flutter能开发游戏吗_Flutter开发游戏初体验,喜大普奔相关推荐

  1. 飞机大战小游戏源码---飞机大战初体验

    开发环境: Windows10,pycharm,python3 源码使用教程: 打开pycharm,创建一个新的项目,文件-->新建项目 项目命名:飞机大战初体验,基本解释器选择python3版 ...

  2. 微信小游戏-海盗来了打金初体验

    引子 假期在家空余时间, 发现微信小游戏突然火了, 群友推荐一款名为: 海盗来了 的小游戏 稍微体验了一把感觉很不错, 真正实现了微信对小程序的期望 -- 取代原生 app 得益于日益强大的 js 引 ...

  3. Android开发学习之路--Notification之初体验

    一般当我们收到短信啊,微信啊,或者有些app的提醒.我们都会在通知栏收到一天简单的消息,然后点击消息进入到app里面,事实上android中有专门的Notification的类能够完毕这个工作,这里就 ...

  4. Android开发学习之路--Camera之初体验

    顾名思义Camera就是拍照和录像的功能,像微信里面,我们想拍照传一下照片,就能够通过camera来拍照,然后存储照片.发送给好友.那么微信的app里面是不会直接通过camera api来实现的,由于 ...

  5. flutter能开发游戏吗_Steam上架游戏开发软件,不用代码也能制作游戏,而且还是免费的...

    时代在变化,科技在进步,曾几何时我们一度以为的高科技,在现在看来也不过是平常到不能再平常的东西.游戏开发也一样,以前需要代码才能开发制作而成,现如今都不需要了,直接编辑就OK, Steam商城这次就上 ...

  6. flutter开发桌面应用_Flutter应用开发十大公司

    flutter开发桌面应用 Well, if you've already clicked on the link, there's no need to tell you what Flutter ...

  7. 【CSON原创】HTML5游戏框架cnGameJS开发实录(外部输入模块篇)

    返回目录 1.为什么我们需要外部输入模块? 在游戏中我们常常用到类似这样的操作:鼠标点击某位置,玩家对象移动到该位置,或者按鼠标方向键,玩家向不同方向移动,等等.这些操作无一不用与外部输入设备打交道. ...

  8. os-cocos2d游戏开发基础-进度条-开发笔记

     os-cocos2d游戏开发基础-进度条-开发笔记(十)   ios-cocos2d游戏开发基础-游戏音效-开发笔记(九)       ios-cocos2d游戏开发基础-CCLayer和Touch ...

  9. java游戏_java开发的七个金典游戏你小时候肯定玩过

    相信很多刚接触编程的同学,对于Java开发能做些什么.做过哪些游戏, 并不是特别清楚.那么今天小编就为大家分享下, 万能的Java开发过的那些经典游戏吧! 手机上的Java即J2ME(Java 2 M ...

  10. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

最新文章

  1. vue @click 绑定多个方法 执行顺序_Vue干货,学完这些就够用了
  2. sscanf简单用法
  3. 华为SAP解决方案为海澜之家带来新的科技创新
  4. idea下的application.properties下写汉字乱码问题
  5. 语言舒尔特方格程序_有效提升孩子注意力的方法,舒尔特方格训练法,简单有效...
  6. w10家庭版安装java不_小编为你分析win10系统安装不了java的设置办法
  7. bzoj3389:[Usaco2004 Dec]Cleaning Shifts安排值班
  8. hadoop yarn 获取日志_Hadoop YARN配置参数剖析(2)—权限与日志聚集相关参数
  9. impdp时报错ORA-39082的原因
  10. mysql之index
  11. membership.findusersbyname模糊匹配的写法
  12. hdu 2046 骨牌铺方格
  13. Spring之容中的工厂Bean
  14. LCT动态树【史上最精简易懂的LCT讲解】
  15. c++值传递和引用及指针传递区别
  16. 百兆网络变压器:H81601S产品规格及建议配置的芯片型号
  17. sql sever中计算百分比
  18. vuejs --- 父组件向子组件传值(父传子)
  19. 钟汉良日记:做短视频和直播的基础能力
  20. 2021年危险化学品生产单位安全生产管理人员考试题库及危险化学品生产单位安全生产管理人员最新解析

热门文章

  1. Hadoop2.7.4 HA centos6.8
  2. react native android 通知栏
  3. 5道经典面试题【转载】
  4. indexOf 和 lastIndexOf 使用
  5. 强人Hibernate文档笔记(下)
  6. Delphi – TCanvas.CopyRect方法中参数CopyMode的意义
  7. cout一位小数_C++ cout 如何保留小数输出
  8. 空间数据引擎oracle_Oracle-Spatial空间数据库基础
  9. redis zset怎么排序_关于Redis(一)
  10. NYOJ 37 动态规划 回文字符串