iOS Developer Learning Flutter. Lesson28 打包上架

本来是这麽打算的啦

但翻了一下文件(iOS, Android)
应该是跟以前打包方式差不多
顶多就是多了

flutter build ios

flutter build appbundle
//-
flutter build apk 

然後Android记得要多加android.permission.INTERNET

所以今天打算来讲点有意思的(这不是标题杀人吗)

其实今天要讲的是这个

Zonble大大的flutter_turtle

以前Objective-C时代就很感谢他公开KKBOX的内部教材造福广大iOS Developer
现在他成为了Flutter的GDE
也分享了许多Flutter的经验
更提供了这个package
在此致上敬意与谢意?

详细介绍可以看看他本人写的这篇Medium
今天就聊聊这个美丽又有趣的小乌龟的

  1. 使用简介
  2. 看看可不可以画出我想要的图形

1. How to use

因为我没玩过LOGO语言
所以一步一步从最基本说起

1.1 Commands

想像在图的中间有只小乌龟
他的X头朝向漂向北方
所以打Forward((_) => 100)牠就往前走100步
注意
如果这时候打Right((_) => 50)
不是往右走50步五十步笑百步
而是右转50度
我们可爱的小乌龟只会往前走或往後走(就跟象棋里的兵一样)
所以要常常注意牠的方向

有个这个观念後
我们就可以来看所有的指令了

/* Turtle motion */

///绘图系
PenDown //开始绘画
PenUp //结束绘画
SetColor //设定轨迹颜色
SetStrokeWidth //设定轨迹宽度

///移动系
Forward //往前走
Back //往後走
GoTo //直接移动到指定座标(不是流程控制的那个GoTo), 会留轨迹
ResetPosition// 回到起始座标Offset.zero, 不留轨迹

///转向系
Left //左转
Right //右转
ResetHeading //直接转到起始方向(北方)

///文字系
Label //在根据画面显示文字
SetLabelHeight //设定文字大小(预设应该是12)

///新功能?
Log //就是print

小乌龟里面也可以写一些流程跟巨集
其中重复是最常使用的
见下方范例

/* Flow control  */

//这样代表重复10次阵列里的指令, 所以等於往前走10步
Repeat((_)=>10, [
    Forward((_)=>1)
  ]
)

//要嘛往前10步, 要嘛往後10步
IfElse((_)=>true, 
  [Forward((_)=>10)],
  [Back(()=>10)]
)

/* Macros(类似函数的用法) */

//先定义直走巨集
SetMacro('straight', [Forward((_)=>_['distance'])])
//执行直走巨集走10步
RunMacro('straight', (_)=>{'distance': 10})

///根据实测RunMacro完之後, 会回到RunMacro之前的位置
//例如下面这组指令
//原本预期牠会先往後走, 然後重叠往前走, 看起来只有一段线
//实际上会先往後走, 回原点, 再往前走, 共两段线
SetMacro("goBack", [
  Back((_) => 100)
]),
RunMacro("goBack", (_) => {}),
Forward((_) => 100),

1.2 Widget
  1. TurtleView
    显示小乌龟留下的痕迹
  2. AnimatedTurtleView
    带动画的TurtleView, 可指定animationDuration
  3. ControllableTurtleView
    可透过AnimationController控制动画的TurtleView
    例如:程序码范例效果范例
1.3 一些超简单范例
  1. 三角形
        GoTo((_) => Offset(-50, 33)),
        PenDown(), //开始

        Right((_) => 30),
        Forward((_) => 100),
        Right((_) => 120),
        Forward((_) => 100),
        Right((_) => 120),
        Forward((_) => 100),

        PenUp(), //结束

  1. 正方形
        GoTo((_) => Offset(-50, 50)),
        PenDown(), //开始

        Repeat((_) => 4, [
          Forward((_) => 100),
          Right((_) => 90)
        ]),

        PenUp(), //结束

  1. 圆形
    复习国小数学
        GoTo((_) => Offset(-57.5, 0)),
        PenDown(), //开始

        Repeat((_) => 360, [
          Forward((_) => 1),
          Right((_) => 1)
        ]),

        PenUp(), //结束

  1. 波浪
    好久没冲浪了喔...(因为我根本不会冲浪)
        Left((_) => waveHeight / 2), //初始角度须为浪高的一半, 才会笔直往上
        PenDown(), //开始

        //step3. 总共几波
        Repeat((_) => 3, [
          
          //step1. 浪打过来~
          Repeat((_) => waveHeight, [
            Forward((_) => waveWidth),
            Right((_) => 1) //往右偏其实是画左浪
          ]),
          
          //step2. 浪打过去~
          Repeat((_) => waveHeight, [
            Forward((_) => waveWidth),
            Left((_) => 1) //反方向
          ]),
        ]),

        PenUp(), //结束

//浪高
waveHeight = 90……………………………90………………………………180
//浪幅
waveWidth = 1.0……………………………0.5………………………………0.5

  1. 椭圆
    椭圆其实很难好吗QQ
    光看维基百科我就快吐了
    我是先用四分之一圈去想
    然後每四分之一圈再去分成三段
    但是怎麽觉得画出来怪怪的(不管了)
    final ovalCompression = 0.5; //需小於2, 不然会画出奇妙的图形喔XD, 越靠近1越像正圆

        GoTo((_) => Offset(-42, 0)),
        PenDown(),

        //step3. 两个半圆
        Repeat((_) => 2, [

          //step1. 往外画
          //长一点 直一点
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => ovalCompression)
          ]),
          //正常弧度
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => 1)
          ]),
          //短一点 歪一点
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => 2 - ovalCompression)
          ]),

          //step2. 往内画
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => 2 - ovalCompression)
          ]),
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => 1)
          ]),
          Repeat((_) => 30, [
            Forward((_) => 1),
            Right((_) => ovalCompression)
          ]),

        ]),

        PenUp(), //结束

实验过程中总是会有一些奇怪的产物XD

2. Try it

想了个几个想画的

  1. 第一个想到的是这个万花尺(好像是钞票上面会出现的图案XD)
    来源
    昨天晚上研究一整晚 => 失败 => 果断放弃
    至少我们有网页版(可以用键盘画好爽)
    PS. 原理一原理二

  2. 上面是一笔画的版本
    再来想挑战看看比较简单的重复版本看看(但不要圆角, 圆角好难画)


    ~结果~
    正方形是有做到根据圆心旋转啦...

    但是星星转不起来...
    (;´༎ຶД༎ຶ`)

    最後用一颗一星球结束这回合

  3. 或是这个

    人家是有名字的喔
    巴斯卡三角形?不是~莱布尼茨三角形?不是~
    它叫谢尔宾斯基~它是一种碎形
    (人家用手都能画了)
    ~结果~
    做到一半才发现不是往中间画XD

    而是应该往三个方向长

    最後会像这样

    但这样还是不对
    例如黄色三角形应该要有9个, 绿色27个
    其实要用递回写才对
    不过今天就先到这边吧

3. 结语

  1. 小技巧, 前面有提过, 由於小乌龟是不可见的
    所以很难掌握牠的方向
    这时我们可以利用Label指令
    就可以在画面显示出方向
    方便debug

  2. 之前不是有个Flutter Clock Challenge
    我觉得办个Flutter Turtle Challenge好像也不错XDD
    (有兴趣请留言+1, 认真)


本集内容(打包上架)Android版请见:iOS Developer Learning Android. Lesson 29

下集预告:完赛啦~

最後提供一下github.com/mark33699/IDLF


<<:  二、教你怎麽看source code,找到核心程序码 ep.22:Deeplab的model 部署

>>:  HERE API Example - 在执行期间变更地图样式

那些被忽略但很好用的 Web API / 拖拉式待办清单

就算拖拖拉拉,也可以把待办事项处理好 昨天虽然已经知道该如何使用 Drag & Drop ...

Day31 - JS30 - 16 - Mouse Move Shadow

参考资料: Alex老师教学 pjchender笔记 JS30-Day16-Mouse Move S...

伸缩自如的Flask [day 30] 结语

好了,这个系列最後一篇,应该会休息一下,做点别的专案。 其实还是会有套件遗漏掉没有介绍到的,毕竟py...

Day_23 WireGuard

延伸昨天OpenVPN,介绍另一个VPN点对点的连接技术"WireGuard"。...

[day-13] Python 内建的数值类函式

Python 内建的数值类函式 数值类函式 执行结果 功能 abs(-10) 10 取绝对值 min...