iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 29
0
Mobile Development

iOS Developer Learning Flutter系列 第 29

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


上一篇
iOS Developer Learning Flutter. Lesson27 Map + Location
下一篇
iOS Developer Learning Flutter. Lesson29 總複習
系列文
iOS Developer Learning Flutter30

尚未有邦友留言

立即登入留言