2018年2月18日 星期日

用 Corona SDK 寫遊戲

Corona SDK 下載
https://coronalabs.com/products/corona-sdk/,需註冊帳號才能下載。Corona SDK為跨平台的開發工具,可用來設計手機與桌上電腦程式。Corona 用的語言是Lua,底下網址提供線上Demo
http://www.lua.org/demo.html

安裝好 Corona SDK後,必須以註冊好的帳戶登入:

登入後,可看到底下畫面,選擇 New Project:

輸入程式名稱並選擇Blank專案:

此時Corona SDK會開啟專案資料夾:

同時會詢問用哪個軟體開始main.lua檔案,筆者是用Visual Studio Code來開啟:

在開始寫程式前,可以在Visual Studio Code裡安裝Corona Tools

在此先以官方提供的BalloonTap範例來講解Corona SDK的遊戲設計觀念,圖檔說明如下:
檔案名稱大小 (寬×高)用途
background.png360 × 570背景圖。
platform.png300 × 50讓氣球停止的平台。
balloon.png112 × 112氣球。
而在程式方面,分為底下步驟來處理:
  1. 讀取背景圖
  2. 讀取平台圖
  3. 讀取氣球圖
  4. 建立物理模擬
  5. 事件處理
  6. 計分


讀取背景圖

程式碼如下:
local background = display.newImageRect( "background.png", 360, 570 )
background.x = display.contentCenterX
background.y = display.contentCenterY

程式碼第一行讀取background.png檔案,結果如下圖,背景沒有填滿整個視窗畫面。
那要怎麼讓背景圖填滿畫面呢?程式碼第二、三行可以幫我們達成這件事:

讀取平台圖

程式碼如下:
local platform = display.newImageRect( "platform.png", 300, 50 )
platform.x = display.contentCenterX
platform.y = display.contentHeight-50

這和讀取背景圖是一樣的觀念,但是我們要將平台往上移動位置,所以就將平台的y座標減掉50,這是因為Corona SDK的座標系統的y座標向上是遞減的。結果如下圖:

讀取氣球圖

程式碼如下:
local balloon = display.newImageRect( "balloon.png", 112, 112 )
balloon.x = display.contentCenterX
balloon.y = display.contentCenterY

此外也可以設定圖片的透明度:
balloon.alpha = 0.2

alpha值越小圖片越透明,結果如下圖:

建立物理模擬

程式碼如下:
local physics = require( "physics" )
physics.start()
physics.addBody( platform, "static" )
physics.addBody( balloon, "dynamic", { radius=56, bounce=0.3 } )

程式碼第一、二行為使用Box2D物理引擎,第三行讓平台不會受物理引擎的影響,第四行讓氣球碰到平台時會彈起來,bounce的值越大,氣球碰到平台彈回的高度就越高。

結果如下:

事件處理

要讓使用者在氣球上點一下時,氣球會往上飛。程式需要處理tap這個事件,以及對應的函式,所以程式碼會類似下面的片段程式碼:
local function pushBalloon()
balloon:applyLinearImpulse( 0, -0.75, balloon.x, balloon.y )
end
balloon:addEventListener( "tap", pushBalloon )

applyLinearImpulse函式的說明請參考:https://docs.coronalabs.com/api/type/Body/applyLinearImpulse.html

結果如下:

計分

使用一個變數來計分,將此變數放在主程式main.lua的第一行。
local score = 0

增加顯示分數的文字widget,須放在讀取背景圖的後面,以免文字被背景圖給覆蓋。
local scoreText = display.newText( score, display.contentCenterX, 20, native.systemFont, 40 )

修改pushBalloon函式,在此筆者是用亂數來設定每一次所增加分數。
local function pushBalloon()
balloon:applyLinearImpulse( 0, -0.75, balloon.x, balloon.y )
score = score + math.random (5)
scoreText.text = score
end

結果如下:


完整程式碼:

參考資料:
[1] https://docs.coronalabs.com/guide/programming/01/index.html