2011年1月9日 星期日

Android App 開發筆記 - 2

        原本打算每週生產一個 App 的計畫,第二支 app-「草人扎針」總算在這個週日凌晨發佈上架。雖然拖了超過一個月,但我也從這第二支應用到一些新的技術。

        這次有幾個新嘗試:

  1. 手指塗鴉功能。
  2. 動畫播放功能。
  3. 不同螢幕解析度自動調適。
  4. 漸變動畫技巧。

        以上幾種開發實作的技巧和經過我就紀錄如下:


  1. 手指塗鴉功能:
            這個 app 的特性是讓使用者賦予草人一個你所討厭的人的名字,然後加以插針虐待。曾經考慮過直接提供輸入框讓使用者透過手機內建的輸入法簡單輸入即可,但後來感覺這種做法實在沒有 fu,因為在使用者一筆一畫地「刻出」仇人的名字的過程中,其實也有種洩憤的功用。況且提供手指塗鴉的功能,除了能拿來書寫名字外,還能讓使用者提供額外創意發揮的空間,例如裝飾小人...etc。
            總之,手指塗鴉功能不但符合此程式的特性,且可以讓我學習到貼圖以外的 Android 2D 繪圖的程式開發,是個極好的學習機會。
            由於我手上的書沒有這方面的範例教學,我上網找了幾個參考資料。
            這個 sample code 有問題,一執行就死機,但仍提供了不錯的參考基礎:http://www.hksilicon.com/kb/articles/3686/Google-Android-2D-3D-OpenGL
            後來我在 JavaWorld 論壇找到另一個不完整的 sample:http://www.javaworld.com.tw/jute/post/view?bid=26&id=277811,利用這個去修改上面那個會死機的版本,總算湊出符合我需求的程式碼來。
            重點:手指塗鴉的功能主要是依靠 Canvas 在 Bitmap 上不斷地畫上 Path,而繪圖的方式則是透過 Paint 所儲存的筆刷資訊進行,每次繪圖後,必須透過 View.invalidate() 來迫使 View.onDraw ( Canvas ) 被 Container 再次呼叫更新畫面。

  2. 動畫播放功能:
            最早,我屬意的動畫實做方式是打算直接透過 Animated GIF 檔,感覺這應該是最廣泛且最容易支援的方式,且 GIF 可以透空的特性非常適合遊戲使用。未料, Android SDK 內建的 API 並沒有對 Animated GIF 有任何直接的支援!大驚失色之下,我想網路上一定有人想解決這個問題,所以我搜尋後找到了一個對岸工程師寫的 Open source library - GifViewhttp://code.google.com/p/gifview/
            然而這是該工程師一人獨自進行的半成品,而且該專案似乎已經進入凍結狀態沒有任何後續發展動作,現成的功能也無法解決我的一些需求。如果單純就是播放 GIF 動畫,這個 lib 功能倒是恰到好處,但數量一多除了會出現 OutOfMemory 的錯誤外,不支援動畫播放次數設定和自定動畫播放速度快慢對我來說也是個頭痛的問題。
            嘗試了沒多久,我只好放棄繼續使用這個 lib,改用官方標準的 PNG 串連的做法-Frame animation:http://developer.android.com/guide/topics/graphics/2d-graphics.html
            實作方法就是定義一份 的 XML 來串連所有挪做動畫使用的 PNG 圖檔:
    <animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="true"
        <item
    android:drawable="@drawable/rocket_thrust1" android:duration="200" />
        <item
     android:drawable="@drawable/rocket_thrust2" android:duration="200" />

        <item
     android:drawable="@drawable/rocket_thrust3" android:duration="200" />

    </animation-list>



            這個方式的
    好處是相當彈性,每張圖片的播放長度都可各自設定 duration(單位毫秒),日後要修改動畫內部分的影格內容可以輕易地抽換掉該圖檔即可。壞處是相當麻煩,一個複雜點動畫就會讓圖檔數量暴增且不易管理。所以兩個方式的平衡點就看自己怎麼運用和拿捏了。

  3. 不同螢幕解析度自動調適:
            開發 Android 程式首推第一難纏的問題就是處理不同螢幕解析度的問題了!由於 Android 各種不同螢幕解析度和奇怪的長寬比例組合都有,使用絕對座標進行設計絕對會遇到很棘手的問題。不像 iPhone 就只有單一公板,只要在一支 iPhone 上能跑,八九不離十地在成千上萬的 iPhone 也都能跑。Android App 的開發,已經遇到如同當年 HTML / CSS 碰上不同家的瀏覽器那樣頭痛的問題,而且甚至更嚴重瀏覽器市場當時至少有個 IE 獨大佔八成市場,做 IE only 的網頁也不至於跑掉生意,而目前 Android 機台不但數量多過瀏覽器數量,而且還沒有哪一款手機可以獨大)。
            尤其做遊戲畫面牽涉到貼圖和操控,可不像是做網頁,只要順序對就可以,長寬不夠可以自動延展或是自動斷行,座標觀念仍是必要的設計元素。
            我開發機器用的模擬器設定都是 HVGA ( 320 x 480 ) ,而我的 i9000 就是 WVGA ( 800 x 480 ) ,開發完後要佈署到我真的手機,立刻就會面臨解析度不同的問題。在官方提供的方法內,有個不完整的解決方案,就是使用 dp ( Density-independent pixel ) 來當做程式處理的虛擬像素單位,不過這是 Android 1.6 SDK 之後才提供的方案,對 1.5 以前或是使用真實像素當參數處理的 legacy API 還是沒輒。雖然 AbsoluteLayout 已經被宣告為 deprecated ,但為了方便與統一起見,我還是先使用這個 Layout ,並自己撰寫一支 LayoutParamTransformer 來針對不同的螢幕來自動做轉換。
            至於官方 dp 的用法和觀念,可參考這篇文章-Supporting Multiple Screens: http://developer.android.com/guide/practices/screens_support.html

  4. 漸變動畫技巧:
            嚴格來說,這並不是這次開發所學到的新東西,因為早在之前某個 POC 我就實做過了。利用 Timer 和 Handler 自行處理一些動畫效果,像是移動或是放大縮小。這次就是用在遊戲結束血慢慢滲出的動畫效果(
    其實就是血漬的圖片漸漸放大效果)。
            實做可以參考這篇範例: http://dtmilano.blogspot.com/2009/04/android-frame-by-frame-animations.html

        以上就是簡單記錄這次作品所多用到的一些開發方法,這個 App 照例有放 AdMob 上去,如果願意支持看看這個簡陋的範例作品,請在 Android Market 上搜尋「Torture Villain」找到這個草人扎針的 KUSO game,並給個五分的評價吧? ^_^

Google+ Badge