2013年5月1日 星期三

看 Corona SDK DEMO 學 API (2)



我個人學 Corona SDK 時,官網上面資料不多,更不像現在有上百篇那麼多的 tutorial 文章,所以看 Sample Code 變成最快也是唯一的自學竅門,不過那時候不像現在有講國語的社團(歡迎加入 https://www.facebook.com/groups/corona.taiwan/可以發問,沒人可以問要一直試驗很辛苦,我現在寫這 blog 也是想幫到更多想學 Corona SDK 卻苦無中文資料的朋友(你知道嗎?現在小學生也學寫 App 哩!)

我們之前看過了 FrameAnimation1 的程式,今天我們來看這叫 Clock 的範例:

(PS:這個 project 的資料夾在 Corona SDK 路徑裡面 /SampleCode/GettingStarted/Clock/ 裡面)


display.setStatusBar( display.HiddenStatusBar )

local clock = display.newGroup()

local background = display.newImage( "purple.png" )
clock:insert( background, true )
background.x = 160; background.y = 240

-- Set the rotation point to the center of the screen
clock:setReferencePoint( display.CenterReferencePoint )

-- Create dynamic textfields
-- Note: these are iOS/MacOS fonts. If building for Android, choose available system fonts, 
-- or use native.systemFont / native.systemFontBold

local hourField = display.newText( "", 0, 0, native.systemFontBold, 180 )
hourField:setTextColor( 255, 255, 255, 70 )
clock:insert( hourField, true )
hourField.x = 100; hourField.y = 90; hourField.rotation = -15

local minuteField = display.newText( "", 0, 0, native.systemFontBold, 180 )
minuteField:setTextColor( 255, 255, 255, 70 )
clock:insert( minuteField, true )
minuteField.x = 100; minuteField.y = 240; minuteField.rotation = -15

local secondField = display.newText( "", 0, 0, native.systemFontBold, 180 )
secondField:setTextColor( 255, 255, 255, 70 )
clock:insert( secondField, true )
secondField.x = 100; secondField.y = 390; secondField.rotation = -15

-- Create captions
local hourLabel = display.newText( "hours ", 0, 0, native.systemFont, 40 )
hourLabel:setTextColor( 131, 255, 131, 255 )
clock:insert( hourLabel, true )
hourLabel.x = 220; hourLabel.y = 100

local minuteLabel = display.newText( "minutes ", 0, 0, native.systemFont, 40 )
minuteLabel:setTextColor( 131, 255, 131, 255 )
clock:insert( minuteLabel, true )
minuteLabel.x = 220; minuteLabel.y = 250

local secondLabel = display.newText( "seconds ", 0, 0, native.systemFont, 40 )
secondLabel:setTextColor( 131, 255, 131, 255 )
clock:insert( secondLabel, true )
secondLabel.x = 210; secondLabel.y = 400


local function updateTime()
 local time = os.date("*t")
 
 local hourText = time.hour
 if (hourText < 10) then hourText = "0" .. hourText end
 hourField.text = hourText
 
 local minuteText = time.min
 if (minuteText < 10) then minuteText = "0" .. minuteText end
 minuteField.text = minuteText
 
 local secondText = time.sec
 if (secondText < 10) then secondText = "0" .. secondText end
 secondField.text = secondText
end

updateTime() -- run once on startup, so correct time displays immediately


-- Update the clock once per second
local clockTimer = timer.performWithDelay( 1000, updateTime, -1 )


-- Use accelerometer to rotate display automatically
local function onOrientationChange( event )

 -- Adapt text layout to current orientation 
 local direction = event.type

 if ( direction == "landscapeLeft" or direction == "landscapeRight" ) then
  hourField.y = 120
  secondField.y = 360
  hourLabel.y = 130
  secondLabel.y = 370
 elseif ( direction == "portrait" or direction == "portraitUpsideDown" ) then
  hourField.y = 90
  secondField.y = 390
  hourLabel.y = 100
  secondLabel.y = 400
 end

 -- Rotate clock so it remains upright
 local newAngle = clock.rotation - event.delta
 transition.to( clock, { time=150, rotation=newAngle } ) 
end

Runtime:addEventListener( "orientation", onOrientationChange )

首先我們先執行一下這個程式,很簡單,就是一個在螢幕裡的數位型時鐘。我們來看看『程式部分』,有幾個重點:
第 1 行:
display.setStatusBar( display.HiddenStatusBar )

這個 API 呼叫是說,在程式一開始把 StatusBar 這個東西藏起來。我們都知道手機螢幕最上方有條橫欄,裡面有現在的時間,Wifi或3G連接,電力等等訊息。如果我們要做像電玩類的 APP,我們也許不需要這條橫欄,所以我們可以把它藏起來。

PS:順便一提,這個橫欄的高度在 iPhone 時是 20 pixels 高。(可參考文件:http://www.idev101.com/code/User_Interface/sizes.html
但是在 android 時它會因為螢幕解析不同,有不同的高:
> 240x320 LOW_DPI_STATUS_BAR_HEIGHT = 19;
> 320x480 MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;
> 480x800 HIGH_DPI_STATUS_BAR_HEIGHT = 38;


第 10 行:
clock:setReferencePoint( display.CenterReferencePoint )

這個 API 呼叫是說,把 clock 這個圖形群組的『繪圖參考點』設在該圖形群組的中央。什麼,原來 Corona SDK 有『繪圖參考點』這個東西喔!是的,你可以用你最熟悉的方式去選擇你的座標系統,然後以這個例子來說,你看到畫面上那三個『時』『分』『秒』的數字,是不是有個 15 度的傾斜。原來你可以對任何繪圖物件(包括文字 display.newText),設定它的 rotation 角度。

第 49 行:
local time = os.date("*t")

這個 API 呼叫是用來取系統時鐘的資訊,它回傳的結果是一個 table, table 裡面有時間的資訊像 time.hour/time.min/time.sec 這種東西。其他還包括有 year (4位數), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (星期幾, 以星期天為 1 開始), yday (今年的第幾天), 和 isdst (日光節約時間,一個 true/false 值)。(請參考http://docs.coronalabs.com/api/library/os/date.html)

第 68 行:
local clockTimer = timer.performWithDelay( 1000, updateTime, -1 )

這個 API 呼叫是說,每隔 1000 毫秒,執行一次 updateTime 這個函式,-1 是指『無限次』

所以這整個程式就是把一個底圖載入畫面中央,把時間的文字欄位輸出在想要的位置,把時間的數字欄位傾斜 15 度。最後,每隔一秒去更新一次時間的欄位就好了。
等一下,還有一行第 94 行,呼叫 Runtime:addEventListener( "orientation", onOrientationChange )
這是用來處理,萬一用戶把手機打橫時,你的程式會收到一個 onOrientationChange 的 event 事件,如果你的程式夠聰明就像這個程式一樣,你應該去處理偵測用戶目前是橫向哪一邊,然後調整整個 UI 輸出的位置與顯示方式,就像在 72 行那個函式處理的那樣。

所以你現在看到一個在螢幕裡的數位時鐘,它會一直更新。很簡單吧,下回我們要來看一看 event 事件這個東西。

待續...