2010/12/23

DIY iPhone Stylus

1000000255

最近好想畫畫,想用iPhone + Brushes畫畫。但記得上次用手指頭畫的經驗不是很方便。
雖然坊間也有一些iPhone Stylus可買,但都不怎便宜。所以就來DIY一下。


從Google可找到至少三、四種不同的做法,我就挑個最簡單好做的試試

材料:斷水的原子筆一支、Mini士力架一包,如頁首那張照片
(其實是任何有鋁薄包裝的東西就可以了)

把士力架吃掉,並把包裝紙攤平,記得要把裏面擦乾淨
1000000256

包覆到筆上面
1000000257
這邊有個重點是,鋁薄要包長一點,一定要包到手可以握到的地方
因為其原理是利用鋁薄為導體,將手指的靜電傳至筆尖,所以鋁薄一定要包到手會握到的地方

另外有一點是,筆尖的地方也無法做太細太尖,至少要有一點點小平面,所以我塞了一點衛生紙在筆尖處
1000000260

最後用膠帶捆一捆就完工了
1000000263

試畫一下(以下用Brushes示範)
1000000265

1000000266

心得:
比用手指好畫多很多!
不過筆尖如果有辨法修細一點就更好了,不然在一些細微處還是不太好畫。
但還是比用手指好畫,這樣就滿值得了…

以下是其他各種做法的參考資料,有興趣的人自己去看看

日系精緻版


簡易鋁薄版


神奇鈕扣版

3M海綿版


2010/9/10

Flash for iPhone之「回來就好,其他都不重要」

100064263

今早最讓Flash developer們注意的新聞莫過於Apple 對iOS app tools的解禁。有種「沉冤得雪」,或是「回來就好,其他都不重要」(註1)的感覺。在此整理一下個人對這件事的心得及蒐集到的相關資料。

註1:「回來就好」此語出自James在我噗裏的回文,感覺相當貼切微妙。

1.解禁的只是App開發tool,並不是Browser的Flash Player
很多人看到「Apple 對Flash解禁」的標題就會High過頭,但請注意這只是對app開發tool,而不是Browser Plugin。當初在Flash CS5裏的Package for iPhone本來就是配合著iOS的方式,生成符合iPhone格式的.ipa檔案,再用合法的方式上架。基本上對整個App store生態本來就不會有太大的影響(有也只是app量的增加速度),一切其實都很安份合理的,所以這也是當時3.3.1條款出現時,為什麼Flash Developer們很不能認同,因為禁得十分不合理。

而當時賈伯斯則指出,3rd tool效能差等等之類的言論做為解釋。我個人覺得如果效能不好,應該就會被市場機制淘汱了吧,有必要在開發階段就禁止大家用什麼工具嗎?然而最好笑是當時還有不少Apple教義派(註2)跟著幫腔好一陣子。

另一方面,如果今天是說「開放Browser plurgin Flash Player」,我個人覺得這才是比較有影響力的一步。因為這會影響App Store裏許多與現有Web Flash Content類似的App,其次也會影響目前User在選擇購買 iOS與Android間的判斷條件。

註2:當時常有人著文開頭就寫「先聲明我不是蘋果教義派,不過…」但實質上就是在賣一堆蘋果週邊產品的Blog/網站,根本就是超級大信徒,看了就很好笑。

2.Flash做為App開發工具的競爭力又如何?
首先談效能,Flash Package for iPhone(以下簡稱PFI)在3G上實測很差,3Gs上還ok,iPhone4我還沒試過,但如果是以同樣1G cpu的Nexus One來參考的話,個人覺得還算可以期待,至少在開發一些小Game,小Tool時,1G cpu上跑起來還算不錯。

另外我覺得效能問題,也會隨著硬體逐年的加強而慢慢降低,但不絕不會消逝。因為再怎樣Flash永遠比不上原生的obj-c效能好。所以未來有可能會有一大堆Flash做的小品在App Store上,只有大作強作才會是用obj-c來寫。而話說回來,在手機平台上,小品game的市場其實不見得就會比大作來得小。

再來談對系統API的支援。不知是不是之前被Apple氣到的關係,Flash在轉往Android後,API的加強突飛猛進,尤其近幾個月中加入好幾個實用的API,如相機相簿、WebView、存取檔案、P2P…等等,雖然還是不夠多,但光這些其實就能玩出許多花樣了。
但可惜的是,這些API都是PFI 版所沒有的,查詢一下最後一版的PFI,仍只有Accelerometer, GPS, MultiTouch三個比較能說嘴的API。所以如果要讓PFI成為有競爭力的開發工具的話,至少API的部份要加強到像目前for Android版本一樣才行。這點可以在未來幾個月持續關注Adobe Prerelease網站裏的消息。總之能support的API愈齊,工具的競爭力才愈高,目前的PFI還很弱就是了。

3.真的可以上架了嗎?
也許有些人還會存疑,會不會這只是玩文字遊戲,口頭說不擋,但實際上架時再給你卡關呢?好險賈伯斯霸道歸霸道,說話倒是算話,說禁就是禁,說開就是開,沒在玩文字遊戲。在消息發佈後沒多久,就有Flash Developer在Twitter上寫道之前一直審核不過的Flash app突然過關了。另外像這款這款,也都是Flash開發的,不約而同也都在今天上架/更新了。所以看來應該是無誤的了。

4.所以這之後會有什麼影響
最大受惠當然還是廣大的Flash開發眾,對大家來說是原來被關的門,現在又打開了。這樣的狀況下,可以想見未來會出現許多用Flash開發的小App小Game入侵App Store市場,而這些app會不會表現得很好?到時自然會分明。
目前可以想到的是將來很多Web Flash的案子,客戶可能會多問一句:「能不能做手機版」(其實現在就常在問了),而設計公司可以大聲回答說「ok啊~再加XXXX錢,就可以了」;或是很多原本對Obj-C頭痛(像我),或是根本沒在學Obj-C的人,也開始在個人profile的skill 上多加一條「iPhone app開發能力」,照這樣發展下去,我想iPhone app的外包案件價格也會備受影響吧,以往可能可以報價XXXX錢,之後可能會是XXXX 減 N 的錢了(真是不妙)。

寫一次code可同時跨Web/Android/iPhone,這還是Flash目前最大強項(Unity 3D雖然也有web player,但安裝率太低),所以其實影響比較大還是其他的app開發工具,尤其像是Corona SDK, PhoneGap這類的打著「簡單易學」口號的3rd Tool,都應該會被這事有所影響。未來這些Tools會怎麼樣競爭;Adobe會怎樣重啟PFI的開發,也或者將來又出現什麼更厲害的3rd Tool,則是我個人比較期待的。

2010/5/9

Flash CS5 Accelerometer 範例

Mark Doherty 貼了一段CS5 accelerometer api功能的demo影片

Device Central CS5 - Accelerometer from Mark Doherty on Vimeo.

In this video we look at the Accelerometer API in Flash Player 10.1 and AIR and the integration with Device Central CS5


以下分享一下這個範例的原始碼及心得:


accelerometer就是我們常俗稱的g-sensor,用來測量重力的sensor。
一般來說這種accelerometer都會給三個軸向的數值,分別為x,y,z,且都會是正~負的一個範圍,例如1~-1, 100~-100這種的。
而Flash提供的是1~-1的範圍。以面對手機瑩幕來看,水平線為X,垂直線為Y,穿透瑩幕的縱向為z

在Flash中使用acceleration api其實沒什麼困難,設好update event後,就會持續收到訊號,訊號內容有三個值
accelerationX
accelerationY
accelerationZ
各別都是1 ~ -1的一個值,拿這些值來做應用即可

以下範例是做了一個小鋼珠在桌面滑來滑去的動態,除了用AccelerometerEvent外,另外多加了些摩擦力、慣性的模擬。

在電腦要測的話,可開啟Device Central CS5的3D模擬面板試玩。

最後有一點要注意,Accelerometer的靈敏度,甚至軸向,有時在不同的device上會有所不同,所以一些參數會需要因不同的機子調整,例如這個範例我在iPhone及Nexus One上測試,其X軸的正負值就完全相反,sensor回傳event的靈敏度也不太相同。

以下為範例code:


Flash CS5 multi-touch 範例

Mark Doherty貼了一段Flash CS5 multi-touch的範例影片

Device Central CS5 - Flash Professional Integration from Mark Doherty on Vimeo.

In this video we look at the debugging capabilities using Device Central for mobile projects. The application, PhotoTouch by Maso Lin, demonstrates the multi-touch support added to the tool for testing your applications.


以下我分享一下這個範例的原始碼及心得…



Flash目前提供的multi-touch api大致可分成兩種:
.TouchEvent--直接取得各個點的事件
.TransformGestureEvent--只取多點所形成的gesture結果

先說說TransformGestureEvent,它可得到rotate, zoom, pan, swip等事件,如果你的需求是這些的話,用這個就可以了。
TransformGestureEvent另一個好處是,使用macbook/pro開發時,直接在觸控板上做這些gesture,這個api是可以收到訊號的,這樣就可以在電腦上實測了。

而TouchEvent的使用時機,我個人覺得是在TransformGestureEvent無法滿足時再用就可以了。
例如做一個動作遊戲,需要在畫面上做出虛擬手把時 (左邊十字方向鍵,右邊是攻擊、跳…等),就必需要用TouchEvent

最後有一點要注意是,Flash 目前只支援到2點觸控,再多的話就收不到了。 待測...

以下是範例code,大致上是把所有的event列出來而已,並應用在一張照片上,讓它可以zoom in/out、旋轉 ,雙指pan做移動…等





2010/4/20

BaoZi Jump! on Android by Adobe AIR

AIR for Android





I was porting my iPhone game "BaoZi Jump!" to Android, it works fine and smoothly.

This app using the Accelerometer API to control the BaoZi move, and every thing works correctly.

It took me almost 3 hours to compile for Android and modify some accelerometer variables to fit the Nexus One.(there is a little different between the accelerometer sensor of iPhone and Nexus One)

昨天花了約3三小時左右把BaoZi Jump porting成Android版,其實過程很簡單,用的是同一份原始檔,code幾乎沒改。主要時間反而是花在第一次操作Android SDK及一些文件的部署。(如果你已經有開發過Android的話,這部份應該不會花太多時間)

其次是要熟悉Nexus One的accelerometer sensor訊號,它的靈敏度與iPhone有些不同,所以要配合他的靈敏度調了一下參數。

其他的就沒花什麼時間了,一切非常簡單。

接下來就期待Adobe AIR for Android正式release後,廣大的Flash高手們會在Android Market丟出什麼樣的創意了。

2010/3/22

Corona SDK - File I/O 檔案讀寫


在local端 進行檔案讀寫的動作。


先看一下完成後的介面:


由於File 存取必在實機上才能作用,所以我在畫面上半部弄了一個trace box,把一些測試用的訊號印出來看。

中間一條輸入框 input_txt ,給User隨便打字用,打完可存進檔案中

下方三個按鈕:
-Save 會把input_txt中的文字,及一串亂數數字,存進data.txt中
-Clear,會把data.txt中的內容清除,並寫上新的資料"new file, 00000"
-Remove,把data.txt這個檔案刪除掉。

範例code:


利用 file = io.open( path, mode )
即可開出檔案,mode主要有三種"r","w","a"
r : 只做讀取
w : 寫新檔(如果檔案不存在,下w就會建出一個新檔;若本來已有這個檔案,新寫的會覆蓋舊的)
a : 追加 (新寫的內容會加在原來舊資料之後)
另外還有"r+","w+","a+" 三種,但我實際試了一下,還找不出差異性在哪…以後再研究了。
在mode之後也可再加個"b",啟動binary模式,例如"rb", "wb" 這樣



要逐行把資料讀出,可用以下的寫法


要把table的東西逐行寫入檔案,則用以下的寫法


2010/3/18

Corona SDK - PHP+MySQL


我只是想弄個排行榜啊…


簡單測試一下如何上傳資料到PHP+MySQL的server上。
註:這邊只用最簡便的方式,以webPopup開網頁來與php溝通,所以應用層面有限。若要不透過網頁直接溝通的話,就再研究LuaSocket那部份的文件了。

首先先弄好介面:

.分數下面有個Random button,按了之後會亂數出現分數。做為等下要上傳用的成績。
.接下來是user自行輸入id,按Submit後,會連scroe及id一起上傳
.最下面有個High score是看成績用的。



main.lua:


上面可以看到,按submit之後,就會開webPopup連 "addData.php?id=xxxx&score=12345" 來上傳成績,成功的話,會出現網頁:

頁面下方的Close按鈕可關閉webPopup,注意看該button的html code




寫資料沒問題後,接著是讀資料。一樣用PHP把資料呈現出來


php code:


2010/3/17

Corona SDK - Misc. 雜項筆記


寫著寫著,偶爾會發現一些語法或邏輯上的小重點,單獨寫一篇不太像樣,所以集中整理於本篇。



動態取名
在AS上,會用_root["mc_"+i]類似這樣的方式動態取對象名稱。在Corona裏則是_G["mc_"..i]這樣的寫法
(_G類似於_root,而有沒有this, parent這類的,我還沒試過)



function裏用到的所有變數需先宣告好
例如以下


buttonHandler裏用到了label_1,但label_1的宣告是在buttonHandler之後,這樣寫的話仍可正常build出程式,也能執行,但到了buttonHandler裏的label_1.text=event.phase就會有問題了,自這行之後的code就都會沒有作用。
發生此問題時會一直找不到錯誤,因為build code都顯示為正常。所以要改成:




native.newTextField listener補充
1.1的文件上對TextField只提到有listener,但未對listener的用法加以說明。
其listener可得到三種事件:began, submitted, ended,用法如下:




math.random()在device上測試時的問題
math.random()放到device上測試時,會發生一直取到一樣數字的問題。
例如我們下 math.random(10000),並寫一個button,每按一下就執行一次math.random(10000),把結果秀在畫面上。
在simulator上,都會正常地出現不規則的亂數。但在device上,就會依序出現1,1316, 7557, 4587, 5328....
就此看來似乎是沒什麼問題,但關掉app再開後,卻發現仍然是1,1316, 7557, 4587, 5328....
不論試幾次都是一樣的結果。

要解此問題,需在使用math.random之前,先用一次
math.randomseed( os.time() )
(*在程式開始處設定一次即可)

看起來似乎是設定不同的randomseed,才能得到不同的亂數,所以官方回筈是說用os.time()可讓app每次得到不同的randomseed。
就我實際測來,確實有改善問題,每次能得到不同的亂數。但時間相近時,卻會得到"相近"的亂數…
例如現在測第一次math.random(10000)得到"5884",關掉app後馬上打開再測,會得到"5889"
猜想是os.time()得到的數字相近的結果。這點暫時看來無解…不過至少這樣的math.random()還能堪用就是了…



關於for loop

lua也有類似於AS的for(var i in obj)的用法。不過目前我只於table中使用,其他的object是否也能使用,就要再試試看了。lua的寫法如下

上面i會是index名稱,k則是內容的值,也就是tb[i]的內容。(index會從1開始)

除了ipairs外,也可以用pairs,兩者差別請看下面的code

用pairs的話,會依序print出 1,2,3,4,a
用ipairs的話,只會print出 1,2,3,4 也就是只有index為integer的東西
就視狀況看要用哪一種了。


2010/3/12

Corona SDK - Accelerometer


Accelerometer重力加速計,也就是一般俗稱的G-sensor

Corona SDK所提供的Accelerometer十分週全,並非只有三個重力計的指數而已。(不像某知名品牌… XD)
主要由兩種event取得
.orientation
.accelerometer


Orientation比較單純,是當手機擺放角度改變時,才會通知,適合用在像瀏灠器轉向時,網頁自動轉面的這種應用。Orientation可從event.type得知目前手機被擺成哪一面,共有六種可能性:
.portrait
.landscapeLeft
.portraitUpsideDown
.landscapeRight
.faceUp
.faceDown
範例


注意:faceUp, faceDown這兩種要在實機上能得到。


Accelerometer則是隨時監聽所有的變化,能取得sensor所有數值

.event.xGravity -- x軸重力值,範圍 1至-1
.event.yGravity -- y軸重力值
.event.zGravity -- z軸重力值

.event.xInstant -- x軸瞬間加速值,範圍 1至-1
.event.yInstant -- y軸瞬間加速值
.event.zInstant -- z軸瞬間加速值
.event.isShake -- 搖動,以true/false表示
x, y, zGravity比較單純,就是看手機目前的傾斜狀況來反映
x, y, zInstant則是瞬間加速值,平常得到的值都很小,但當手機有快速晃動、甩動時,才會表現出來

範例:

注意:Accelerometer及native.newTextBox要在實機上能作用。

補充:system.setAccelerometerInterval是sensor靈敏度之設定,可設10~100,數字愈大靈敏度愈高。需注意有時設太高會跑不動(app直接跳掉)


做一個小球滾來滾去的範例:




2010/3/11

Corona SDK - StatusBar


Corona SDK可對系統StatusBar做控制

StatusBar的控制要用display.setStatusBar( 模式 )這個指令來達成
而模式有四種可以設
. display.HiddenStatusBar 隱藏,要做fullscreen app就要設這個
. display.DefaultStatusBar 白色款
. display.TranslucentStatusBar 半透明款
. display.DarkStatusBar 黑色款

以下範例用四個按鈕來切換不同的StatusBar款式


Corona SDK - Alert & Activity Indicator


native Alert 視窗及Activity Indicator控制
(*Activity Indicator就是平常loading時那個旋轉小菊花符號)


Alert
在Corona裏用native.showAlert就可以叫出系統的Alert視窗了


要注意是按鈕設定是以 { } 把要加的按鈕加進去(不限定二個)。

實際範例如下

這邊要注意的是加按鈕用的table,如上面的code中 {"取消", "好" }, 在Simulator中出現的樣子會是

按鈕是由右至左排列,但在實機上則是

實機是由左至右排列,與Simulator上是相反的,這點需要稍微注意一下。

在Corona裏Alert的設定邏輯是,不論按哪個按鈕,都會關閉視窗,並執行我們指定給它的function,如上範例則為"onComplete"這個function

在onComplete裏可從event.index取得被按到的按鈕index(從1開始),藉此可去設定不同的後續動作。

除了等user按按鈕外,也有指令可立即把Alert關閉掉

上面範例會在5秒後自動把Alert關閉掉,在此可順便看到onComplete中取得的event.action,若為"clicked"則表示是user按了某按鈕;若為"cancelled",則表示是由native.cancelAlert(alert)來關閉的


Activity Indicator

Activity Indicator的控制只有"顯示"、"隱藏"兩種設定,用native.setActivityIndicator(true/false)來達成

以下範例為一開始時出現Activity Indicator,在5秒後自動消失


Corona SDK - Button Event




Corona SDK的button基本操作很簡單,大致上只有PressRelease兩個Event,這是基於Corona SDK 提供的ui library中的Button 物件。

從Sample code裏找到ui.lua這個檔,copy到你的project目錄中,並在你 的main.lua裏第一行寫

之後便能調用Button物件,如下

從上面的code可看到, 在newButton時,設定default, over兩個圖,它就會自動做按下、放開換圖的動作,連mouseOut也會換圖。(但沒有mouseOver)
onPress=onRelease=則可指定兩個function給它做動作。如此便是最基本的button設定了。


除了用onPress, onRelease外,也可用onEvent一個function來實做, 如下


透過event.phase得知event type,便能利用onEvent做不同的控制


event裏除了phase外,也包含了觸發對象的id,如下範例



若想了解ui library裏button物件的運作原理,可打開ui.lua這個檔去研究。不過我大致看一下內容,似乎也沒什麼值得抓出來用的東西…

2010/3/10

Corona SDK - Basic Animation 基本動畫控制


Corona SDK 也有類似enterFrame或Tween這類的控制


tween的控制方式如下

可在一行內做多個屬性設定
利用上一節的button,可以做一個簡單的demo





除了transition的用法外,也可用類似enterFrame的控制



如此可以簡單做一個彈射球的demo

*注意上面最後的註解,屬性控制也可用translate這個函式寫成一行,方便。

2010/3/9

Corona SDK-基本sprite屬性操作

CoronaSDK basic sprite control from maso on Vimeo.


練習一下基本的sprite屬性操作



main.lua內容如下:
*註:此練習需配合ui.lua才行,在官方sample code中的"Movieclip"裏可找到


2010/3/8

Corona SDK 初試-Hello World

試用了Corona SDK一陣子,感覺不錯用,但畢竟目前不是以此為業,只是利用工作閒暇時間試著玩,所以很有可能一段時間沒用就會忘光光。決定來寫些筆記以防忘記。


前言:
之所以會注意到CoronaSDK要從Adobe Photoshop 20週年活動說起,Russell Brown為了PS 20週年,找了Ansca Mobild team合作一個iPhone版的Photoshop 1.0.7復刻。影片如下


之後又google一下相關資料,找到這篇
Eating Our Own Dogfood: How we built the Photoshop 20th Anniversary App in Three Days

才知道這是用CoronaSDK開發,而且只花三天就移殖好,這點引起了我不小的興趣,決定找來試玩看看。

*順一提,原來Ansca Mobile是Adobe離職員工出來開的
*另外Flash Magazine這篇Mobile development alternatives,比較幾個目前已知的3rd iPhone開發工具,也可看看


先把相關資料蒐齊:
Corona SDK 官網
30天試用下載
文件
論壇
Blog
一些已在app store上的showcase

試用版抓下來後,照著GettingStartedGuide.pdf這分文件,就可以做出一個簡單的Hello World並丟進手機玩了。不過打包時會要求連上網路,這點有些小麻煩…

此外,一般iPhone開發工具要產生能丟進手機的測試檔時,都會要求填入iPhone Developer program的相關認証檔,corona sdk則不需要。猜想可能他是從xcode裏去抓,或是上網去check…。不過這樣倒是方便不少。

打開Corona simulator,立刻會跳出一個選檔案的視窗,此時選擇你要試的sample的資料夾(不是.lua檔哦),就可以看到simulator畫面了。

若要丟手機的話,開好Corona後,在上方的menu bar選File-> Open for build...,之後同上述步驟。但輸出前會多請你設定版號、要測的機子。之後就會build出 app檔。app檔直接拉進iTunes後同步即可。
*這邊因為我是JB過的iPhone,所以就直接拉了。我沒試過未JB的是否可以這樣用…

成功完成一次丟進手機的測試後,就可以把試用版裏包含的sample code一一丟進測試了。


玩Sample Code初步心得
.因為檔案小,預覽、打包、甚至傳進手機,速度都很快,這點不錯。
.圖形表現、Frame rate、效能表現良好 (on iPhone 3G)
.api 支援算高,除Multi-touch未支援外,很多一般app需要的api都有提供:GPS, Accelerometer, native web view, status bar control, camera, camera roll, read/write files, video player...等
(官方說法:multi-touch及新的game framework會在下一版支援)
.用Lua語法,好學易上手
.可用任何你熟悉的文字編輯器來開發
.沒有視覺化的IDE,在排Layout時會比較辛苦些。(要用coding方式來排layout)
.目前只有mac版,很多win的朋友無法來玩…(這影響此技術的推廣啊…)


Hello World動手做看看
快速弄一個Hello world,開一個資料夾,建一個main.lua的文字檔(存UTF8格式)
裏面寫


這樣就能生出一個Hello world了

若直接丟手機的話,會發現 icon是白的,且launch app時也是一片黑暗。此時可以在你的project folder內放一張320x480的Default.png,及 57x57的 icon.png,來做splash screen及icon圖。


Debug
要做類似Flash 上的trace也很容易。先關掉Corona Simulator,改開啟Corona terminal,接下來都一樣的步驟。coding時用print("這是一個測試") 就可以了。

2010/2/23

教學:3D選單

多年前教書用的教案,轉貼過來
課程目標
-學習用 Action Script 虛擬3D空間
-利用3D技術擴展視覺效果
-製作3D選單




00.課前準備知識
Flash本身是2D多媒體開發工具,其座標系統只有X及Y兩個座標軸。但3D空間需要X、Y及Z三個軸向才可實現,因此首要任務便是利用Action Script在Flash中虛擬一個3D空間,讓每個物件皆包含X、Y及Z三個座標值。

設定好3D座標後,便要考慮如何將3D座標投影至電腦畫面上的2D座標,此為虛擬3D技術的第一個重點。

以下圖說明之:


Viewpoint指的是觀賞者視點。
Projection plane 是指投影平面,也可說是電腦螢幕。
d 是視點到投影平面的距離。
z 是視點到虛擬物的距離
仔細看X1及X2字下方的黑點,假設虛擬空間中存在一個黑點(point in space),它在虛擬空間中的x座標為X2,當觀賞者透過螢幕看這個黑點時,黑點的影向是投射在螢幕上(point projected on projection plane)的x座標為X2。

透過上述原理,再利用斜率一致的特性,可知:
X1/d=X2/z
得 X1=X2*(d/z)
同理 Y1=Y2*(d/z)

X2、Y2都是虛擬空間中的座標,因此只要乘以(d/z)即可知道投影到畫面上的X1及Y2。
z是物體的z座標,由我們自訂。
而d是視點到投影平面的距離,d也可由我們自訂,不過不同的d值會有不同的效果,就像鏡頭前進或後退的差異,可在開發過程中視狀況調整。

除了x、y需要設定外,還需要設定_xscale、_yscale,以表現近大遠小的縮放效果。_xscale及_yscale的縮放原理就跟x、y換算一樣,利用(d/z) 來計算。

_xscale = _yscale=100*(d/z);

整理上述,可歸納如下:



接下來我們只要設定好物體在虛擬空間中的x、y、z,不論位在何處,皆可換算出它投影到螢幕上的座標及大小。



01.產生3D投影
首先任意畫一個圓形圖案,可加入少許立體效果,畫好後轉換成MC,並設好Linkage名稱”ball"

主場景上不放任何物件,在Frame上撰寫AS:

cx、cy是畫面中心點,各是stage長寬(550x400)的一半。
eyeD是視點到投影平面的距離,此範例設500,學員可自行調整看效果差界,但記得不要設為負數。
setBallPos函式則是上一節所得到的換算公式。
最後產生球體,以attachMovie產生,同時設定它的x、y、z。此範例以亂數設定,學員也可自行設定到特定位置,並發佈測試比較不同位置呈現的效果。

單純把球體畫在畫面上,可能感受不到明顯的立體效果,若是球體能在空間中移動,應該就能觀察出空間感。

我們加入簡單的移動功能,以方向鍵及「-」「+」鍵來控制球的六方向移動:


關於鍵盤控制,在此不多贅述,但請記得每次移動球體後,都要做setBallPos(ball)的動作,畫面上的球體才會更新位置大小。

發佈測試結果,以鍵盤控制球體,觀察球體移動及大小的變化。
檔案:01_產生3D投影.fla



02.產生多個球體
利用上一節的原理,試試一次產生多個球體:

程式碼如下:

與上一節範例十分類似,唯一不同在一開始多了個sum變數,決定要產生幾個球體,setBallPos函式與上節範例相同,而最後產生球的部份改以for廻圈產生sum設定的球體數量。

發佈測試結果
檔案:02_產生3D投影多捄.fla



03.旋轉
在01的範例中,我們試著用鍵盤控制六方向移動,但都是直線行進;若是能弧形移動,則更能表現虛擬空間的立體感。

假設我們知道物體離圓心的距離,也知道旋轉的角度,那該如何算出它的x、y位置?

sinθ=y/r
cosθ=x/r
y=r* sinθ
x=r* cosθ



透過上述原理,瞭解三角函數與座標計算的關係。

下圖表示一個座標值以弧形移動的狀況


(x,y,0)是第一個位置,它是位在角度a的位置上,接著它以z為軸心,向上移動了角度b,來到(x’,y’,0)的位置。

x= r * cos(a)
y= r * sin(a)
z=0

x’= r * cos(a+b)
y’= r * sin(a+b)
z’=0

根據三角函數公式,可再換算成:
x’= r * cos(a+b) = r * (cos(a)*cos(b) – sin(a)*sin(b)) = x * cos(b) – y * sin(b)
y’= r * sin(a+b) = r * (sin(a)*cos(b) + cos(a) *sin(b)) = y * cos(b) + x * sin(b)
z’=0

以上是以z軸旋轉的公式,整理三個軸向公式如下:

X軸旋轉
x’=x
y’=y*cosθ+z*sinθ
z’=z*cosθ-y*sinθ

Y軸旋轉
x’=x*cosθ-z*sinθ
y’=y
z’=z*cosθ+x*sinθ

Z軸旋轉
x’=x*cosθ-y*sinθ
y’= y*cosθ+x*sinθ
z’=z


利用上述原理,我們實作一個沿x軸旋轉的範例,每次旋轉5度。

檔案:03_多球單軸自轉.fla



04.手動旋轉
上一節學會了旋轉的原理,接下來可試著將旋轉功能轉變成手動旋轉。這一節與上一節大致相同,唯一不同是利用滑鼠位置來設定旋轉角度。

檔案:04_多球單軸手動轉x.fla



05. Y軸轉動
同樣之前的做法,改以Y軸轉動。

檔案:05_多球單軸手動轉y.fla



06. 多軸向旋轉
利用之前介紹的公式,即可設定X軸及Y軸的旋轉,不過要注意當雙軸同時轉動時,必需先計算一個軸向,再以此結果套入第二個軸向的公式。
可以視為先轉其一再轉其二來看待。



檔案:055_多球雙軸手動轉xy.fla
檔案:06_大球體旋轉.fla



07. 3D旋轉選單
利用上述所學,可以輕鬆做出如下3D選單。

檔案:07_球體選單.fla




08. 無限飛行
除了弧形旋轉外,也可累加z值,以製造無限Zoom in 的效果

檔案:08_zoomIn飛行.fla



09. Zoom In 選單
上一節的飛行效果,也可製作成選單,以滑鼠點選黑球來控制鏡頭前進。
檔案:09_zoomIn選單.fla


drawTriangles+UV貼圖筆記


寫給自己的筆記,很粗淺。

昨天研究了一下drawTriangles,直接google這關鍵字可查到最基本的官方教材
關於使用 drawTriangles()
接著也會看到這篇
UV 對應

照著UV對應這篇很快就能弄出一個3D旋轉的範例,如下
.Demo:Spinning3dOcean.swf

這個旋轉教學很簡單,但也有點小複雜,因為他同時使用了3D投影及triangle UV貼圖兩件事。原因是Flash的UV貼圖功能是包含了3D透視比例(就是裏面那個T變數)。所以這篇教學才需要一次介紹這麼多。


不過我個人偏好把東西再分得清楚些,且有很多時候我需要UV變形,但不見得同時也需要3D座標。

所以,以下我先不管3D座標,所有T值都帶1,單純把UV變形的部份練習一下。如下

.Demo: UVT_test_0.swf

這個測試是從上面的官方教學修改而來,並加入線條顯示,及四角控制點。拖拉四個角,可任意變形圖片。唯一問題是變形會像是兩個三角面在折來折去,而不是很smooth的3D傾斜,原因就在我前面說的T值目前都帶1,暫時不考慮3D因素所致。(關於3D問題,將補充說明在最後面)

.Source code



上面的練習只切了兩片三角面,接著我就想試多切幾面的效果,先試試切8片的效果:

.Demo: UVT_test_1.swf

切愈多面可使變形效果較smooth,不過仍與套用3D T值的效果不太相同,目前這種會比較像是2D的網面效果
.Source code



上面的練習是用手動的方式key入9個節點,很弱,所以接下來要設計成用迴圈自動運算節點座標的方式:

.Demo: UVT_test_2.swf

不過demo裏我沒有再做一個UI介面讓人動態去改切割數了,太花時間了。有興趣的人,在source code裏去調整slice這個變數即可。

.Source code



練習至此,就可以利用drawTriangles及UV貼圖的技巧來做許多事了,例如以下的精靈效果:

.Demo: UVT_genie.swf


關於3D的補充說明
使用UV貼圖時,那個T變數,最佳的解決方式就是用3D座標的方式來算,就如同最上面那個官方範例一樣。這點對已熟知3D投影算法的人來說,並不是什麼大問題。也因此這篇筆記才沒對此特別著墨。

而有興趣瞭解3D投影的人,可參考這篇:3D選單教學裏最前面的原理說明部份。

除了直接算出3D標座外,也有神人提出別種解法,請看這篇The best drawPlane/distortImage method, ever
文中作者用兩條對角線,再配合很神妙的公式,算出合理的3D T值,而不用透過真實的3D座標計算。
比較可惜是作者並沒有說明這公式的導出原理。(可能是硬湊出來的,因為他說他花了很多時間try & error & beer XD)
且這方式只能用在只有四個頂點的UV變形裏。其他狀況就完全不適用了。

所以我個人的結論是,單純要做UV變形的話,我會先不考慮T值,能弄出需要的效果就好。假若遇到需要實際3D表現的話,再視情況寫一個3D座標系統配合使用。而上面神人導出的奇妙公式,有出現剛好的使用時機才會考慮使用了。


2010/1/25

BaoZi Jump!

My first iPhone game "BaoZi Jump!"
photo






How to Play:

It's a simple jumping action game.Tilt the iPhone to move the little baozi left or right and go up higher.
Any update about "BaoZi Jump!" will announce in this entry.