前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flutter版合成大西瓜

Flutter版合成大西瓜

原创
作者头像
乂乂又又
修改于 2021-02-22 02:25:13
修改于 2021-02-22 02:25:13
2K0
举报

背景

我一直想做个小游戏,正好年前合成大西瓜火了,所以趁着这次年假,自己在家写了个plus版的合成大西瓜,前后花了大概三天三夜的时间(没错,一直写到大年三十的晚上~),现在写下这篇文章记录下这个过程。

预览

老规矩,先上图,看下这个plus版的合成大西瓜究竟长啥样😊

里面的图片素材可以自己裁剪更换,很方便。

除此之外还支持

  • 自定义背景图
  • 重力感应操控
  • 反向合成小瓜
  • 只生成小/大瓜

并且还内置了多套游戏主题(水果/表情/校徽)

这次让你轻松魔改个够😁

下载地址

网页版:http://v.idoo.top/mix

安卓/iOShttps://www.pgyer.com/Dagua

PS:iOS版安装包需要自签才能使用

开发记录

技术选型

我曾经用Flutter+Flame写过一个Forge2D的开源小游戏:《坠落》

(PS:早期作品,代码写的比较不忍直视,大佬轻喷~)

所以这次,我选择继续使用Flutter+Flame+Forge2D来开发合成大瓜.

后来证明这个选择是非常明智的:

一次开发就可以打包出Web、Android、iOS、Windows、Mac、Linux全端的安装包,非常给力!

开发环境

因为一开始我就打算支持打包成Web应用(甚至是桌面应用),所以需要先把我本地的Flutter环境从stable分支切换到dev分支

在Flutter SDK根目录执行以下命令

代码语言:txt
AI代码解释
复制
#首先把Flutter仓库地址换成清华源到镜像地址,加速下载
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/flutter-sdk.git

#切换分支
flutter channel dev

#更新sdk
flutter upgrade

#开启web,desktop支持
flutter config --enable-web
flutter config --enable-macos-desktop

OK,现在我们就可以用Flutter愉快的开发web跟桌面应用了^^

代码规范

为了规范自己的代码,第一件事就是把 pedantic 加入 dependency

代码语言:txt
AI代码解释
复制
dependencies:
  flutter:
    sdk: flutter
  pedantic: ^1.9.2

#analysis_options.yaml
include: package:pedantic/analysis_options.yaml

pedantic是谷歌内部使用的Dart代码规范,它比 Effective Dart 还要严格一些,有了它就可以安心写代码了。

图片剪裁

这里我选用的图片裁剪插件是 crop,不过它的实现方式是 RepaintBoundary ,所以这丫在Web端不能用(PC上的浏览器可以用,但是在手机上的浏览器就不支持,很迷~),所以没办法,只能退而求其次使用 image 库直接操作图片像素点裁剪图片。

代码语言:txt
AI代码解释
复制
/// Returns a round cropped copy of [src].
Image copyCropCircle(
  Image src, {
  int radius,
  Point center,
}) {
  int min(num x, num y) => (x < y ? x : y).toInt();
  final defaultRadius = min(src.width, src.height) ~/ 2;
  radius ??= defaultRadius;
  center ??= Point(src.width ~/ 2, src.height ~/ 2);
  // Make sure center point is within the range of the src image
  center.x = center.x.clamp(0, src.width - 1).toInt();
  center.y = center.y.clamp(0, src.height - 1).toInt();
  radius = radius < 1 ? defaultRadius : radius;

  final tlx = center.x.toInt() - radius; //topLeft.x
  final tly = center.y.toInt() - radius; //topLeft.y

  var dst = Image(
    radius * 2,
    radius * 2,
    channels: Channels.rgba,
    iccp: src.iccProfile,
  );

  for (var yi = 0, sy = tly; yi < radius * 2; ++yi, ++sy) {
    for (var xi = 0, sx = tlx; xi < radius * 2; ++xi, ++sx) {
      if ((xi - radius) * (xi - radius) + (yi - radius) * (yi - radius) <=
          radius * radius) {
        dst.setPixel(xi, yi, src.getPixelSafe(sx, sy));
      }
    }
  }

  return dst;
}

条件导包

由于dart:io在web端不受支持,所以我们需要使用其它实现来替代dart:io,这就涉及到了如何在dart中实现条件导包

一个简单的文件io的例子

代码语言:txt
AI代码解释
复制
//file/file_io.dart
import 'dart:io';
import 'dart:typed_data';

import 'package:path_provider/path_provider.dart';

class FileTool {
  static Future<Uint8List> read(String path) async {
    final directory = await getApplicationDocumentsDirectory();
    var file = File(directory.path + path);
    if (!await file.exists()) return null;
    return await file.readAsBytes();
  }

  static Future<void> write(String path, Uint8List bytes) async {
    final directory = await getApplicationDocumentsDirectory();
    var file = File(directory.path + path);
    if (!await file.exists()) {
      file = await file.create(recursive: true);
    }
    await file.writeAsBytes(bytes, flush: true);
  }

  static Future<void> delete(String path) async {
    final directory = await getApplicationDocumentsDirectory();
    var file = File(directory.path + path);
    if (!await file.exists()) return;
    file.deleteSync();
  }
}

//file/file_web.dart
import 'dart:typed_data';

import '../hive_tool.dart';
import '../image/ui_image_tool.dart';

class FileTool {
  static Future<Uint8List> read(String path) async {
    if (!HiveTool().inited) await HiveTool().init();
    final value = await HiveTool().box.get(path);
    if (value == null) return null;
    return (value as String).toBytes();
  }

  static Future<void> write(String path, Uint8List bytes) async {
    if (!HiveTool().inited) await HiveTool().init();
    await HiveTool().box.put(path, bytes.toBase64());
  }

  static Future<void> delete(String path) async {
    if (!HiveTool().inited) await HiveTool().init();
    await HiveTool().box.delete(path);
  }
}

//file_tool.dart
export 'file/file_io.dart' if (dart.library.html) 'file/file_web.dart';

更新图标

在项目根目录放入1024x1024分辨率的APP图标,命名为 logo.png

代码语言:txt
AI代码解释
复制
dependencies:
  ...
  flutter_launcher_icons: ^0.8.1

flutter_icons:
  image_path: "logo.png"
  android: true
  ios: true

然后运行 flutter pub run flutter_launcher_icons:main 即可

开源地址

本项目开源地址 https://github.com/idootop/watermelon , 欢迎🌟/PR ^^

Web端生成

代码语言:txt
AI代码解释
复制
flutter build web --release

Android端生成

代码语言:txt
AI代码解释
复制
flutter build apk --split-per-abi

PS:亦可支持iOS,Mac,Windows,Linux端,请自行打包

鸣谢

Flutter https://flutter.dev/

Flame https://flame-engine.org/

Forge2D https://github.com/flame-engine/forge2d

合成大西瓜 http://www.wesane.com/game/654/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
The Operation couldn't be completed.(LaunchServicesError error 0.)
问题描述:当运行Xcode6时,编译代码成功,但是登陆模拟器失败,显示错误:The Operation couldn't be completed.(LaunchServicesError error 0.)
用户1451823
2018/09/13
6890
iOS - xcode经常报的经典error解决办法大全
错误原因: 返回cell的代码放在括号的范围不对,看下周围代码的作用域。有时括号太多,容易放错代码。
Kris大鲨
2018/05/04
2.7K3
iOS - xcode经常报的经典error解决办法大全
Xcode报错问题总结
1. InValid Device State 原因:同时安装了Xcode7和Xcode8等多个版本,在交替使用的时候会出现上诉错误提示。 解决:关闭所有Xcode版本和模拟器,重新选择一个Xcod
梧雨北辰
2018/04/24
2.2K0
Xcode报错问题总结
扒虫篇-Bug日志 Ⅱ
事情是这样的:一个风和日丽的下午,我正在 itunesConnect 中注册一个APP,基本信息都保存了,在编辑版本信息时,都弄的差不多了,可是没有保存,结果不巧,停电了......,等来电之后我再次注册时:
進无尽
2018/09/12
6350
扒虫篇-Bug日志 Ⅱ
iOS自动化真机测试验证环境过程中常见问题解析
本章节主要讲解 iOS 自动化真机配置以及在 iOS 真机执行自动化时常见问题与解决方法。
霍格沃兹测试开发
2022/05/06
7470
iOS里的动态库和静态库
静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝(图1所示)
且行且珍惜_iOS
2022/05/13
3K0
iOS里的动态库和静态库
扒虫篇-Bug日志 Ⅲ
解决方法:可能是由于粘贴网页上的代码的时候两行之间的回车引起的,有未识别的回车或者换行,找到,删除掉就 OK了。
進无尽
2018/09/12
1.3K0
扒虫篇-Bug日志  Ⅲ
armv7和arm64区别(armv7s)
================================================
全栈程序员站长
2022/07/28
5.5K0
通过Xcode命令行编译
命令行工具包是一个小型独立包,可供下载独立于Xcode的和允许您执行命令行开发OS X,它由两部分组成:OS X SDK和命令行工具,如Clang的,这是安装在/ usr/ bin中
君赏
2018/08/31
6.4K0
通过Xcode命令行编译
扒虫篇- Bug日志 Ⅷ
不执行的原因是 在VC中使用这个ImageUploaderManager时,需要设置为全局变量,如果是局部变量的话,很快会被销毁掉,其中的代理自然不会执行了。
進无尽
2018/09/12
7890
扒虫篇- Bug日志 Ⅷ
Xcode常用的配置
Header Search Paths与User Header Search Paths
码客说
2019/10/22
1.9K0
iOS_Error(一)
大概步骤就是点击 项目名->Build phases->找到Copy bundle Resources->找到里面的info.plist->选中然后delete,OK搞定!还是要警告大家,系统默认产生的文件比如info.plist文件,最好不要自己乱动,否则就会产生一些莫名其妙的问题。
mikimo
2022/07/20
9920
iOS_Error(一)
基础篇-app上传小准备及上架后搜索不显示
        app上传中会需要准备一些文件,如 icon图标,launch Image ,itunes Contect 中还需要上传不同尺寸的屏幕截图等,下面做一下小节。
進无尽
2018/09/12
1.2K0
基础篇-app上传小准备及上架后搜索不显示
React-Native 遇到的错误1. React-Native 部分组件在debug模式下打包在iOS真机上可以显示,但是release模式下打包在iOS真机上不显示2. React-Native
这段代码在release包的情况是,buttons是空的,是由于if (child.type.name === 'FlowSendButton')这是判断根本不会为true,因为在release模式下,child.type根本没有name这个属性,只有在debug模式下才有,所以这样来进行判断的 ,统统不会有true的情况,自然buttons中没有值,也就不会展示了。
贺贺V5
2018/08/21
2.2K0
React-Native 遇到的错误1. React-Native 部分组件在debug模式下打包在iOS真机上可以显示,但是release模式下打包在iOS真机上不显示2. React-Native
给 iOS 模拟器 “安装”app 文件
刚刚接触iOS的时候,我就一直很好奇,模拟器上面能不能直接安装app呢?如果可以,我们就直接在模拟器上面聊QQ和微信了。直到昨天和朋友们聊到了这个话题,没有想到还真的可以给模拟器“安装”app!
一缕殇流化隐半边冰霜
2018/08/30
6.4K0
ViewController及View的生命周期1. 起因2. Controller的生命周期3. View的生命周期4. 内存警告
1. 起因 我们经常能够在第三方库的源码中看到很多loadView、willMoveToParentViewController:、viewDidLayoutSubviews 等等诸如此类的并不是十分常见的方法。这让永远都只在viewDidLoad写作的童鞋们情何以堪吶。 这些其实都和生命周期有关,和viewController以及view的各种加载顺序有关。这篇文章就小小撸一下这中间的关系和顺序。 2. Controller的生命周期 系统提供了控制器从显示到消失的四个方法。 千万不要看到方法名中间出现了
stanbai
2018/06/28
1.6K0
【IOS开发基础系列】地图开发专题
http://www.cnblogs.com/syxchina/archive/2012/10/14/2723522.html
江中散人_Jun
2023/10/16
4750
【IOS开发基础系列】地图开发专题
工程化(一)——Xcode工程探究
如果我们是通过 CocoaPods 引入第三方,那么在命令行执行 pod install 之后,查看项目目录就可以看到多了一个 xcworkspace 文件,如下:
拉维
2023/03/09
3.3K1
工程化(一)——Xcode工程探究
抓住iOS的未来 - 30天学习编写30个Swift小程序
=======================================================
nimomeng
2018/09/13
2.6K0
抓住iOS的未来 - 30天学习编写30个Swift小程序
扒虫篇-崩溃日志解读及Crash收集
崩溃是让发人员比较头痛的事情,app崩溃了,说明代码写的有问题,这时如何快速定位到崩溃的地方很重要。调试阶段是比较容易找到出问题的地方的,但是已经上线的app并分析崩溃报告就比较麻烦了。最终,我们可以通过iOS崩溃日志在大多数情况下,你能从中了解到关于闪退的详尽、有用的信息。线上崩溃可以通过 iTunesConnect 中心的Cash收集,也可以通过第三方Cash收集工具,亦或自己在工程中手动收集崩溃日志上传到服务器中,本文做个小结,希望对初入者能有些帮助。
進无尽
2018/09/12
3K0
扒虫篇-崩溃日志解读及Crash收集
推荐阅读
相关推荐
The Operation couldn't be completed.(LaunchServicesError error 0.)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档