introduction to corona sdk

Post on 26-Jan-2015

39.153 Views

Category:

Technology

12 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Introduction to Corona SDKCooper Maa

2013/9

Who am I?

• 本名:馬萬圳 (Cooper Maa)

• 現任於 :

• 擅長 Arduino 、嵌入式系統韌體研發、物聯網及網路通訊協定

Agenda

• Corona SDK Overview

• Quick Start

• Corona SDK Framework

– Text, Shapes, Images, Audio

– Events and Listeners

– Physics

– Storyboard

– Widget

Corona SDK Overview

What is Corona SDK?

• 程式語言很簡單 (Lua)• 很快就可以上手• 開發跨平台 Apps (iPhone, iPad, Android)

A piece of cake

好比剪貼勞作用 Corona SDK 寫 Game 就這麼簡單

Cross Platform Development

xcode + Objective-C

之前兩套都要學,而且都不容易學

eclipse + Java

Notepad++ and Corona SDK

現在只要會 Lua ,既簡單又輕鬆

有 Free 版可用 (Starter)

誰在用 Corona SDK ?

and more…

High Performance

30 fps: 預設每秒 30 個 frames

不只可以寫遊戲

What is Lua?

• Scripting Language• Small and Simple• Extensible• Portable

Lua v.s Othe Languages

if not carMoving then -- do somethingelseif noGas then -- do something elseend

for i = 1,10 do print(i)end

for j = 100,1,-1 do print(j)end

if (!carMoving) { // do something} else if (noGas) { // do something else}

for (i=1; i<=10; i++) { print(i);}

for (j=100; j>0; j++) { print(j);}

Lua objects are Tables

array = { "a", "b", 100, "hello" }dictionary = { x=5, y=7, name="Coopermaa" }

t = {} -- empty tablet[1] = "a" -- numerical indext["x"] = 5 -- key indext.x = 5 -- equivalent property access key = "x"t[key] = 5 -- any type can be a key

t["printCooper"] = function print("Cooper") end

Object methods

-- create empty tablelocal o = {}

-- add methodfunction o:saySomething(something) print(something)end

-- output 'hi'o:saySomwthing("hi")

The ':' is syntactic sugar

-- create empty tablelocal o = {}

-- add methodfunction f(self, something) print(something)endo.saySomething = f

-- output 'hi'o.saySomething(o, "hi")

Arrays are 1-based-- Lua: index begins with 1local array = {'a', 'b', 'c'}

for i=1,#array do print(array[i])end

// Other languages: index begins with 0array = ['a', 'b', 'c'];for (var i=0; i<arr.length; i++) { console.log(array[i]);}

Features of Corona SDK• OpenGL graphics• OpenAL audio• Box2D Physics• Texture atlases, sprites• Networking• GPS, multi-touch, accelerometer, camera, video• Widgets library and native web views, textfields• Services: ads, analytics, IAP• Game networks: Game Center (iOS) and Google Play Game Services

for achievements, leaderboards, real-time multiplayer games• Corona Cloud (shutdown) : multiplayer support, leaderboards, chat,

push notification, game analytics

Community• http://www.coronalabs.com/community/ - 官方社群• http://docs.coronalabs.com/ - 官方文件• http://www.youtube.com/user/CoronaLabs - 官方 Youtube• https://github.com/coronalabs - 官方 github• http://www.youtube.com/user/CoronaGeek

Quick Start

註冊帳號

http://bit.ly/QTRjWG要先註冊帳號才能下載 Corona SDK

下載 Free 版 Corona SDK

注意! Windows 版只能 Build Android App

安裝 Corona SDK

按照慣例,都是按 [Next] 一路到底即可

安裝 XCODE (Mac only)

https://developer.apple.com/xcode/裝了 XCODE 才能 Build 出 iOS App

安裝 JDK 6 (32-bit)

http://bit.ly/nYenCt裝了 JDK 才能 Build 出 Android App (.apk 檔 )

打開 Corona Simulator

點按 [Corona SDK > Corona Simulator]

啟動 ( 激活 ) Corona SDK

第一次開 Corona Simulator 要先輸入帳號啟動軟體

Corona Simulator

之後都是用 Corona Simulator 來跑程式

Corona Simulator Output 視窗

這個視窗提供偵錯用的訊息

Sample Apps

點按 Corona Simulator 的 [Sample Apps]裏面有很多分類好的範例,都有程式碼可供學習

Step-by-step example

點按 [Demo] 有幾個一步步教學

Playing Corona Demos

Demo: Images & Text

Demo: Touch & Sound

Demo: Physics

Text Editor

TextMate for MacNotepad++ for Windows

Project Structure• Project_Folder (top-level)– images (folder)– audio (folder)– videos (folder)– data (folder, read-olny files, e.g. json and xml, fonts)– scripts (folder, other Lua files, apart from main.lua)– main.lua (every project must contain a main.lua)– config.lua (Configuration settings for an app)– build.settings (Build-time settings for an app)– Icon-hdpi.png, Icon-mdpi.png, Icon-ldpi.png

一定要有 main.lua ,其它檔案可有可無

實作: Hello World

體驗活動

HelloWorld

進行流程

建立 HelloWorld 資料夾1

編輯 main.lua2

用 Corona Simulator 載入 main.lua

3

Build 出 Android .apk 檔4

編輯 main.lua

-- print 會把字串印到 Corona Simulator Output 視窗print("Hello World")

-- 建立 "Hello World" 文字-- 語法 : display.newText([parentGroup], string, left, top, font, size)local myText = display.newText("Hello World!", 50, 50, "Arial", 60)

-- 設定文字顏色為紅色-- 語法 : [object]:setTextColor(R, G, B)myText:setTextColor(255, 0, 0)

本例會在畫面上產生一個 Hello World 的文字也會在 Corona Simulator Output 視窗印出 Hello World

2

用 Corona Simulator 載入 main.lua3

Build Android .apk

點按 [File > Build for Android (Ctrl + B)]在 [Save to Folder] 欄位輸入存放 .apk 檔的資料夾

4

在手機上安裝並執行 App

Text, Shapes, Images, Audio

Text and Image

local background = display.newImage( "world.jpg" )

local myText = display.newText( "Hello, World!", 0, 0, native.systemFont, 40 )myText.x = display.contentWidth / 2myText.y = display.contentWidth / 4myText:setTextColor( 255,110,110 )

點按 [Sample Apps > Getting Started > HelloWorld]注意! myText 的 x, y 是自己的中心點,不是 left 和 top

座標系統

(x, y): x 是水平位置, y 是垂直位置左上角的座標是 (0, 0)

iPad768x1024

iPhon4640x960

Galaxy SIII720x1280

Nexus One480x800

解析度百百種

自動縮放

TIDA

Content Area

-- config.luaapplication = {

content = {

width = 320,height = 480, scale = "letterbox"

}}

在 config.lua 裏定義 Content Area 的寬和高在不同的裝置上, Corona 會自動縮放 Text, Image, Vector

Scale methods

模式 說明

letterbox 等比例縮放。整個 Content Area 都會在 Screen 裏,但是設備的畫面比例如果跟 Content Area 不一樣,畫面可能會產生黑邊。黑邊還是可以利用,只要把視覺元素放到 Content Area 外即可。

zoomEven 等比例縮放。但設備畫面比例如果跟 Content Area

不一樣,部份內容可能會被犧牲掉 ( 被裁減掉 ) 。

zoomStrech 填滿整個 Screen 。預設的 method 。畫面會撐開導致內容變形。因為會扭曲 Content Area ,所以不建議用這種模式。

實作:認識 Scaling

體驗活動

Fishes - 水族箱

點按 [Sample Apps > Graphics > Fishes] 開啟範例點按 [ViewAs > iPhone 5] 模擬 iPhone 5

Droid

開啟 config.lua

-- config.luaapplication = {

content = {

width = 320,height = 480, scale = "letterbox"

}}

點按 [File > Show Project Files ] 打開專案資料夾然後用編輯器打開 config.lua ,原始內容如上

刪除 Content Area 的設定

-- config.luaapplication = {}

Content Area 解析度會變成 iPhone 5 的 640 x 1136因為水族箱沒有等比例縮放,所以魚跑出去了

letterbox 模式

letterbox 會等比例縮放但因為 iPhone 5 畫面比例不一樣,所以上下有黑邊

-- config.luaapplication = {

content = {

width = 320,height = 480, scale =

"letterbox"}

}

zoomEven zoomStrech

zoomEven: 等比例縮放,但內容被切掉了一部份zoomStrech: 填滿整個 Screen ,不過內容變形了

Shapes

display.newline() - 線display.newRect() - 矩形display.newRoundedRect() - 有圓角的矩形display.newCircle() - 圓形

實作:認識 Shapes

體驗活動

Shapes

建立 config.lua

-- config.luaapplication = {

content = {

width = 320,height = 480, scale = "letterbox"

}}

輸入上列內容以設定 Content Area 與 Scaling

畫出三角形

_W = display.contentWidth_H = display.contentHeight

-- 利用 newLine() 畫出三角形 , 框線寬度為 3 ,框線顏色為白色-- 語法 : display.newLine([parentGroup], x1, y1, x2, y2)local l = display.newLine(_W/2, 0, 0, _H/4)l.width = 3l:setColor(255, 255, 255)

-- 畫出三角形另外兩條邊-- 語法 : lineObject:append(x, y, [x2, y2...])l:append(_W, _H/4, _W/2, 0)

建立 main.lua ,然後輸入上列程式碼以畫出三角形

畫出矩形

-- 利用 newRect() 畫出矩形,填充顏色為黃色,-- 白色筆刷,寬度為 3-- 語法 : display.newRect([parentGroup], left, top, width, height)local r = display.newRect(0, _H/4, _W, _H*3/4)r:setFillColor(255, 255, 0)r.strokeWidth = 3r:setStrokeColor(255, 255, 255)

畫出圓形

-- 利用 newCircle() 畫圓,半徑為 80 ,-- 填充色為綠色,黑色筆刷,寬度為 4-- 語法 : display.newCircle([parentGroup,] xCenter, yCenter, radius)local c = display.newCircle(_W/2, _H*3/5, 80)c:setFillColor(0, 255, 0)c.strokeWidth = 4c:setStrokeColor(0, 0, 0)

實作:翻滾吧!小魚

體驗活動

HelloTransition

簡易動畫說明

讓魚游到右上角1

移動時魚要翻滾2

載入背景及魚的圖檔1

-- 載入水族箱背景local background = display.newImage("bkg.jpg")-- 載入魚的圖檔local fish = display.newImage("fish.png", 30, 220)

加上簡單的動畫2

-- 載入水族箱背景local background = display.newImage("bkg.jpg")-- 載入魚的圖檔local fish = display.newImage("fish.png", 30, 220)

function listener(object)print("I am here!!!")

end

-- 讓魚花 3.5 秒鐘的時間移動到右上角-- 移動時要翻滾 360 度 , 快要到達時減速-- 完成移動後就呼叫 listener()transition.to(fish, {time=3500, x=250, y=80,

rotation=360, transition=easing.outExpo, onComplete=listener})

移動完成時, Output 視窗會印出 "I am here!!!"

transition.to()在指定時間內轉換 display object 的狀態,例如移動位置 (x and y)、透明度 (alpha)、大小(width and height)、縮放比例 (xScale, yScale) 等

功能說明

transition.to( target, params )語法

Control Property 說明time 指定轉換的時間,預設是 500 ( 單位: milliseconds)delay 指定轉換前的延遲時間,即多久後開始轉換,預設是 0delta false 表示 target property 為指定值, true 為變動值。

例如 y=100 , false 時會移動到 100 , true 是往下移動 100 單位

transition 設定轉換的 easing function ,見下頁說明onStart 轉換開始會呼叫的 listener function , target 會傳給

listeneronComplete 轉換完畢會呼叫的 listener function , target 會傳給

listener

Easing Functions

Easing Functions 是緩和用的函式,可以讓動畫變得比較平滑緩和一點功能說明

Easing Function 說明easing.inExpo() 開始速度為 0 ,然後才加速。內插值算法為指數函數easing.inOutExpo() 開始速度為 0 ,接著加速,然後再放慢速度。內插值算

法為指數函數easing.inOutQuad() 開始速度為 0 ,接才加速,然後再放慢速度。內插值算

法為二次函數easing.inQuad() 開始速度為 0 ,然後才加速。內插值算法為二次函數easing.linear() 使用線性函數計算內插值,預設的 easing functioneasing.outExpo() 開始速度很快,快到達時減速。內插值算法為指數函數easing.outQuad() 開始速度很快,快到達時減速。內插值算法為二次函數

Easing Functions 的比較

點按 [Sample Apps > Graphics > Easing Examples] 打開範例

認識 Display Group

體驗活動

HelloDisplayGroup

Display Group

Display Group 可以包含其它 display objects ,方便管理一群 display objects ,例如一起移動一群 (組 )物件。

Display Group 很類似 Photoshop 圖層的概念

遊戲載入後titleScreen 會往上移然後開始進行遊戲

遊戲流程

往上移動 titleScreen 1

移動完成後開始遊戲讓小魚進行翻滾

2

載入背景及魚的圖檔1

-- 載入水族箱背景local background = display.newImage("bkg.jpg")-- 載入魚的圖檔local fish = display.newImage("fish.png", 30, 220)-- 載入音效檔local bubble = audio.loadSound("bubble.wav")

-- 開始進行遊戲function startGame() -- 讓魚花 3.5 秒鐘的時間移動到右上角 -- 移動時要翻滾 360 度 , 快要到達時減速 transition.to(fish, {time=3500, x=250, y=80, rotation=360, transition=easing.outExpo})

audio.play(bubble)end

顯示 titleScreen2

-- 顯示 titleScreen Display Groupfunction showTitleScreen() -- 建立 titleScreen Display Group local titleScreen = display.newGroup()

-- 產生兩個 display objects 並放入 titleScreen display.newText(titleScreen, " 開心水族箱 ", 20, 110, "Arial", 50) display.newText(titleScreen, "Start", 120, 280, "Arial", 40)

-- 花 1.2 秒把 titleScreen 往上移, 1 秒後開始動作 -- 移動完成時呼叫 startGame() transition.to(titleScreen, {time=1200, delay=1000, y=-480, onComplete=startGame})end

showTitleScreen()

這就是所謂的場景轉換,使用 storyboard 來管理會更簡單

Current Stage

Current Stage 是最上層的 Display Group可利用 display.getCurrentStage() 取得

往上移動1移回原位2

移動畫面-- 載入背景圖display.newImage( "world.jpg" )

-- 顯示 "Hello World"local myText = display.newText("Hello, World!", 0, 0, nil, 40)myText.x = display.contentWidth / 2myText.y = display.contentWidth / 4myText:setTextColor( 255,110,110 )

-- current stage 是最上層的 Display Groupstage = display.getCurrentStage()

-- 花 1.2 秒把 stage 往上移, 1 秒後開始動作transition.to(stage, {time=1200, delay=1000, y=-480})-- 花 1.2 秒把 stage 移回原位, 2.5 秒後開始動作transition.to(stage, {time=1200, delay=2500, y=0})

HelloTransition2

Events and Listeners

Events

• System• Timers• Buttons• Collision• Audio

Event Types• Runtime Events

– enterFrame - occurs at fps interval (30 or 60)– system - such as app suspend or exit– orientation - changes from portrait to landscape or vice-versa

• Local events, such as:– touch (hit) - user touches the device screen / display objects– collision - two physics object collide– timer - a running timer completes its duration– audio - an audio file finishes playing– networkRequest - network requests phase/status/response– location (GPS) - generated by the GPS hardware

enterFrame Event

-- 載入齒輪 gear 於畫面中央local gear = display.newImage("gear.png")gear.x = display.contentWidth / 2gear.y = display.contentHeight / 2

-- 讓齒輪每一個 Frame 旋轉 1 度local function animate(event) gear.rotation = gear.rotation + 1end

Runtime:addEventListener("enterFrame", animate)

-- 可以利用 xScale, yScale 調整齒輪的縮放比例gear.xScale, gear.yScale = 0.8, 0.8

利用 enterFrame 事件讓齒輪產生旋轉的效果

GearRotaion

Touch Event

使用 addEventListener() 註冊 Listener 使用 removeEventListener() 移除 Listener

_RADIUS = 20local tapSound = audio.loadSound("beep.mp3")

-- 在 touch 的位置畫出一顆黃色的球local function onTouch(e) -- 有 began, moved, ended 和 cancelled -- 四種 touch events -- 這裏只處理 began event if e.phase == "began" then local circle = display.newCircle(e.x, e.y, _RADIUS) circle:setFillColor(255, 255, 0) audio.play(tapSound) return true endend

Runtime:addEventListener("touch", onTouch)

HelloTouch

HelloTimer - function listener

畫面上的數字會從 0 數到 20 ,然後再從 1 數到 20…

local timeDelay = 500 -- Timer delay 時間local iterations = 20 -- 重複次數

-- 畫出白色的 Texttext = display.newText("0", 115, 105, "Arial", 160)text:setTextColor(255, 255, 255)

-- 定義 function listenerfunction listener(event) local count = event.count text.text = count if count >= iterations then timer.performWithDelay(timeDelay, listener, iterations) endend

-- 在 timer up 時呼叫 listener ,重複指定次數timerID = timer.performWithDelay(timeDelay, listener, iterations)

HelloTimer

HelloTimer2 - table listener

畫面上的數字會從 0 數到 20 ,然後再從 1 數到 20…

local timeDelay = 500 -- Timer delay 時間local iterations = 20 -- 重複次數

-- 畫出白色的 Texttext = display.newText("0", 115, 105, "Arial", 160)text:setTextColor(255, 255, 255)

-- 定義 table listenerfunction text:timer(event) local count = event.count self.text = count

if count >= iterations then timer.performWithDelay(timeDelay, text, iterations) endend

-- 在 timer up 時呼叫 listener ,重複指定次數timer.performWithDelay(timeDelay, text, iterations)

HelloTimer2

實作: Hello Animation

體驗活動

HelloAnimation

跑來跑去的球

定義球半徑、球速與方向1

在畫面中央畫出黃色的球2

加上動畫讓球移動碰到邊邊時切換方向

3

定義 Content Area

-- config.luaapplication = {

content = {

width = 320,height = 480, scale = "letterbox"

}}

輸入上列內容以設定 Content Area 與 Scaling

定義球半徑、球速與方向

_W = display.contentWidth_H = display.contentHeight

-- 定義球半徑、球速與預設方向local radius = 20local xspeed = 7.5local yspeed = 6.4local xdirection = 1local ydirection = 1

xdirection = 1 往正向移動 ( 右 ) , -1 則反向移動 ( 左 )ydirection = 1 往正向移動 ( 下 ) , -1 則反向移動 ( 上 )

1

在畫面中央畫出黃色的球

-- 在畫面中央畫出一顆黃色的球local ball = display.newCircle( _W/2, _H/2, radius)ball:setFillColor(255, 255, 0)

2

設定畫面四邊的位置

-- 設定畫面四邊的位置-- 這邊是 letterbox 的算法, zoomEven 算法不一樣local screenTop = 0local screenBottom = _Hlocal screenLeft = 0local screenRight = _W

待會球會移動,碰到邊邊時要讓球切換方向

加上動畫讓球移動3

-- 加上動畫讓球移動,碰到邊邊時切換方向function animate(eveent) local dx = xspeed * xdirection local dy = yspeed * ydirection local xNew, yNew = ball.x + dx, ball.y + dy

if xNew > screenRight - radius or xNew < screenLeft + radius then xdirection = -xdirection end if yNew > screenBottom - radius or yNew < screenTop + radius then ydirection = -ydirection end

ball:translate(dx, dy)end

Runtime:addEventListener("enterFrame", animate)

動畫的播放預設是 30 fps ,每秒 30 格

zoomEven 模式下螢幕四邊的算法(0, 0)

(display.screenOriginX, display.screenOriginY)

display.viewableContentHeight

display.viewableContentWidth

所以,四邊位置為…

local d = display -- 變數別名,簡化程式碼local screenTop = d.screenOriginYlocal screenBottom = d.viewableContentHeight + d.screenOriginYlocal screenLeft = d.screenOriginXlocal screenRight = d.viewableContentWidth + d.screenOriginX

display.screenOriginX 與 display.screenOriginY 在 zoomEven 模式下,原點通常不是 (0, 0)

如果很多顆球怎麼辦?

定義一個畫球的 function1

把畫出來的球放進集合2

針對集合裏的每一顆球加上動畫讓球移動

一樣碰到邊邊時切換方向

3

HelloAnimation2

定義球的各項參數

-- 定義三顆球的參數 ( 半徑、球速、顏色等 )local params = { { radius=20, xdir=1, ydir=1, xspeed=2.8, yspeed=6.1, r=255, g=0, b=0 }, { radius=12, xdir=1, ydir=1, xspeed=3.8, yspeed=4.2, r=255, g=255, b=0 }, { radius=15, xdir=1, ydir=-1, xspeed=5.8, yspeed=5.5, r=255, g=0, b=255 },}

定義一個畫球的 function1

-- 定義畫球的 function ,新球都會在畫面中央出現local function newBall(params) local xpos = display.contentWidth*0.5 local ypos = display.contentHeight*0.5 local circle = display.newCircle(xpos, ypos, params.radius) circle:setFillColor(params.r, params.g, params.b) circle.xdir = params.xdir circle.ydir = params.ydir circle.xspeed = params.xspeed circle.yspeed = params.yspeed circle.radius = params.radius

return circleend

把畫出來的球放進集合2

local collection = {}

-- 畫出三顆球,並把球放進 collection 集合for i=1,#params do

local ball = newBall(params[i])collection[#collection + 1] = ball

end

設定畫面四邊的位置-- 設定畫面四邊的位置 , 這邊是 zoomEven 的算法local d = display -- 變數別名,簡化程式碼local screenTop = d.screenOriginYlocal screenBottom = d.viewableContentHeight + d.screenOriginYlocal screenLeft = d.screenOriginXlocal screenRight = d.viewableContentWidth + d.screenOriginX

-- config.luaapplication = {

content = {

width = 320,height = 480, scale = "zoomEven"

}}

加上動畫讓球移動3

-- 加上動畫讓球移動,碰到邊邊時切換方向function animate(event) for _,ball in pairs(collection) do local dx = ball.xspeed * ball.xdir local dy = ball.yspeed * ball.ydir local xNew, yNew = ball.x + dx, ball.y + dy

local radius = ball.radius if xNew > screenRight - radius or xNew < screenLeft + radius then ball.xdir = -ball.xdir end if yNew > screenBottom - radius or yNew < screenTop + radius then ball.ydir = -ball.ydir end

ball:translate(dx, dy) endend

Runtime:addEventListener("enterFrame", animate)

Physics

物理效果入門

啟動物理引挈後,木箱就會變成自由落體掉到地面上

HelloPhysics

載入背景、地面與木箱

local sky = display.newImage("bkg_clouds.png")sky.x = 160; sky.y = 195

local ground = display.newImage("ground.png")ground.x = 160; ground.y = 445

local crate = display.newImage("crate.png")crate.x = 180; crate.y = 50crate.rotation = 5

(x, y) 指的是物體自己的中心點rotation 指的是旋轉角度

啟動物理引挈並放入物體local physics = require("physics")physics.start()

local sky = display.newImage("bkg_clouds.png")sky.x = 160; sky.y = 195

local ground = display.newImage("ground.png")ground.x = 160; ground.y = 445

physics.addBody(ground, "static")

local crate = display.newImage("crate.png")crate.x = 180; crate.y = 50; crate.rotation = 5

physics.addBody(crate)

ground 是靜止的物體 (static body) ,不受重力影響

影片欣賞

Youtube 影片教學 : http://bit.ly/17MQkgn

實作: HelloPhysics2

體驗活動

HelloPhysics2

從天而降大量的箱子

程式流程

 定義一個產生箱子物體的 function1

 利用 timer.performWithDelay() 每 0.5 秒跑一次 newCrate() 產生箱子

2

定義產生箱子的 function1

-- 定義產生箱子的 functionfunction newCrate()

local crate = display.newImage("crate.png")crate.x = math.random(320)crate.y = -50; crate.rotation = 5

physics.addBody(crate)end

x 座標由亂數產生y 座標設成負的,感覺就像從螢幕外面放入箱子

利用 timer 每 0.5 秒產生一個箱子2

-- 每 0.5 秒跑一次 newCrate() 產生箱子-- 設定 timer 執行 50 次,設成 0 表示無窮timer.performWithDelay(500, newCrate, 50)

按 [Ctrl + R] 重新載入,即可看到完成的結果

比較 density, bounce 的差別

點按 [Sample Apps > Physics > ManyCrates]會發現:大箱子比較重,最小的箱子比較會彈跳

實作:拍氣球

體驗活動

ImpulseBallon

拍氣球

當使用者拍氣球時,就對氣球施力讓它往上飛

進行流程

載入背景、地面與氣球1

啟動物理引挈並放入物體2

加入觸控事件處理並讓氣球往上飛

3

載入背景、地面與氣球

因為要從天而降,所以氣球 (ballon) 的 y 座標是負的氣球圖檔可在 [Sample Apps > Physics > CollisonFilter] 找到

1

local sky = display.newImage("bkg_clouds.png")sky.x = 160; sky.y = 195

local ground = display.newImage("ground.png")ground.x = 160; ground.y = 445

local balloon = display.newImage("red_balloon.png")balloon.x = 180; balloon.y = -50

啟動物理引挈並放入物體2

local physics = require("physics")physics.start()

local sky = display.newImage("bkg_clouds.png")sky.x = 160; sky.y = 195

local ground = display.newImage("ground.png")ground.x = 160; ground.y = 445

physics.addBody(ground, "static")

local balloon = display.newImage("balloon.png")balloon.x = 180; balloon.y = -50

physics.addBody(balloon)

加入觸控事件處理

applyLinearImpulse() 會產生一個推動力第一和第二個參數分別是 x 和 y 方向的推動力

y 是負的,所以氣球會往上飛

3

-- 使用者拍氣球時,就推動一下氣球讓它往上飛function balloon:tap(e) balloon:applyLinearImpulse(0, -0.8, balloon.x, balloon.y)end

balloon:addEventListener("tap", balloon)

物理引挈 - 進階用法一覽

橋 (Bridge)

中間是木板連結起來的橋,左右各連結一根竹竿範例路徑: [Sample Apps > Physics > Bridge]

鍊條 (Chains)

畫面右半部是連結在一起的鍊條範例路徑: [Sample Apps >

Physics > Chains]

玩偶 (RagDoll)

玩偶是多個 Shapes 鏈結起來的物體,可以用繩子操控玩偶範例路徑: [Sample Apps >

Physics > RagDoll]

物理連結 (Physics Joints)

Joint Types 說明Pivot Joint 樞紐連結。最常用的連結,舉凡輪胎、馬達、齒輪、轉

盤、關節等都可以用 Pivot Joint 完成。在 Box2D 稱為 revolute joint 。

Distance Joint 距離連結,以固定距離連結物體Piston Joint 活塞連結。在 Box2D 稱為 prismatic jointFriction Joint 摩擦連結Weld Joint 焊接連結。這種連結方式不會移動或旋轉。Wheel Joint 結合了 piston 與 pivot 兩種 joints 。在 Box2D 稱為

line joint 。Pulley Joint 滑輪連結。把繩索連結兩個物體,繩索長度是常數,如

果一物體被往下拉,另一個物體就會往上拉Touch Joint 觸控連結。把物體連結到目前觸控的位置

Storyboard

Concepts of Storyboard

Storyboard 的用途是場景管理 (Scene Management)1

使用 storyboard.newScene() 建立新場景2

使用 storyboard.gotoScene() 切換場景3

每個 Scene 物件都有個 view property ,也就是其內部的 display group

4

在 Scene 生命中的每個階段都有對應的事件5

storyboard 範例

點按 [Sample Apps > Interface > Storyboard] 打開範例觸控後會呼叫 storyboard.gotoScene() 切換到下一個場景

切換場景切換到指定的場景功能說明

storyboard.gotoScene( sceneName [, options] )語法

option 說明effect 設定場景轉換的效果,例如 fade, zoomOutIn,

zoomOutInFade, flip, flipFadeOutIn, ZoomOutInRotate, zoomInOutRotate, fromRight, fromLeft, fromTop, fromButtom, slideLeft, slideRight, slideDown, slideUp, crossFade 等

time 轉換效果的持續時間,預設是 500 millisecondsparams (optional) 傳遞給下一個場景的自訂資料。資料會透過 event

listeners 傳遞,可從 createScene, willEnterScene 與 enterScene 這幾個事件的 event.params 取得

storyboard.gotoScene( "scene1", {effect = "fade"})範例

建立新場景-- scene1.lua

local storyboard = require "storyboard"local scene = storyboard.newScene()

function scene:createScene( event ) -- object creation code hereend

function scene:enterScene( event ) -- scene logic goes hereendscene:addEventListener( "createScene" )scene:addEventListener( "enterScene" )

return scene

使用 storyboard.newScene() 建立新場景記得要用 addEventListener() 註冊每個階段的 event listener

場景的事件event 說明createScene 當場景的 view 不存在時會呼叫。通常會在這階段建立

display objects 並加到 self.view 裏willEnterScene 發生於場景轉換開始前enterScene 發生於場景移到螢幕上時 ( 即場景轉換完畢時 ) 。通常會

在這個階段 start timers, load audio, start listeners 等exitScene 發生於場景即將移開螢幕時。通常會在這個階段 stop

timers, unload audio, stop listeners 等didExitScene 發生於場景移開螢幕時 ( 即場景轉換完畢時 )destroyScene 發生於場景被清除 (purge) 或被移除時 (remove) 。通常

會在這個階段 remove listeners, widgets 等

一般來說, willEneterScene 和 didExitScene 比較少用

清除與移除場景的差別-- Called immediately after scene has moved onscreen:function scene:enterScene( event ) print( "1: enterScene event" ) -- remove previous scene's view storyboard.purgeScene( storyboard.getPrevious() ) --[[ INSERT code here (e.g. start timers, load audio, start listeners, etc.) ]] end

Mobile Devices 記憶體很珍貴,不用時要「節能減碳」purgeScene() 是清除 display objects ,場景將來還可以再 re-

load removeScene() 是把整個模組 unload

Scene Template

點按 [Sample Apps > Interface > Storyboard] 打開範例點按 [File > Show Project Files] 即可找到 scenetemplate.lua

---------------------------------------------------------- scenetemplate.lua ( 節錄 )-------------------------------------------------------

local storyboard = require( "storyboard" )local scene = storyboard.newScene()

-- Called when the scene's view does not exist:function scene:createScene( event )

local group = self.viewend

-- Called immediately after scene has moved onscreen:function scene:enterScene( event )

local group = self.viewend

Hello Storyboard( 重寫 HelloDisplayGroup)

體驗活動

HelloStoryboard

遊戲流程

顯示 titleScreen 場景1

切換到 gameScreen2

讓小魚進行翻滾到指定地點

3

main.lua1

local storyboard = require( "storyboard" )

-- 切換到 titleScreen 場景storyboard.gotoScene("titleScreen", {effect = "fade", time=300})

titleScreen.lua2

-- titleScreen.lualocal storyboard = require( "storyboard" )local scene = storyboard.newScene()

function scene:createScene( event ) local group = self.view

display.newText(group, " 開心水族箱 ", 20, 110, "Arial", 50) display.newText(group, "Start", 120, 280, "Arial", 40)end

function scene:enterScene(event) local function showGameScreen() -- 切換場景,花 1.2 秒把 titleScreen 往上移 storyboard.gotoScene("gameScreen", "slideUp", 1200) end

timer.performWithDelay(1000, showGameScreen, 1)end

scene:addEventListener("createScene", scene)scene:addEventListener("enterScene", scene)

return scene

gameScreen.lua3

-- gameScreen.lualocal storyboard = require( "storyboard" )local scene = storyboard.newScene()

local fish = nillocal bubble = audio.loadSound("bubble.wav")

function scene:createScene( event ) local group = self.view

display.newImage(group, "bkg.jpg") fish = display.newImage(group, "fish.png", 30, 220)end

function scene:enterScene(event) -- 讓魚花 3.5 秒鐘的時間移動到右上角 -- 移動時要翻滾 360 度 , 快要到達時減速 transition.to(fish, {time=3500, x=250, y=80,

rotation=360, transition=easing.outExpo}) audio.play(bubble)end

scene:addEventListener("createScene", scene)scene:addEventListener("enterScene", scene)

return scene

Widget

Widgets• button• switch• segmented

control• slider• stepper• spinner• table view

(list view)• scroll view• tab bar• picker wheel• progress view

點按 [Sample Apps > Interface > WidgetDemo] 看示範

ButtonEvents

1. 示範 Button widget2. 使用影像檔製作 button 3. 處理 onPress, onRelease 與

onEvent 事件

點按 [Sample Apps > Interface > ButtonEvents] 看示範

Widget 建立步驟

載入 widget library:

local widget = require("widget")

1

使用 widget.newXXXX() 產生 widget2

建立按鈕

local widget = require( "widget" )

local function btnClicked(event) print(event.target.id .. ": Hello World")end

-- Create a simple buttonwidget.newButton{

id = "simple button",left = 60,top = 120,label = "Say Hello",onRelease=btnClicked

}

HelloWidgets

建立切換鈕

local function onOffSwitchListener(event)

print("On/Off Switch\nIs on?: " .. tostring(event.target.isOn))end

-- Create a default on/off switchlocal onOffSwitch = widget.newSwitch{ left = 100, top = 230, initialSwitchState = true, onPress = onOffSwitchListener}

Corona Simulator Output

點按 Button 或 Switch 時,在 Output 視窗裏看見的訊息

工具箱 (3rd Party Tools)

Koneki LDT

Lua Devepment Tools (LDT) 是 Eclipse-based 的 Lua IDE

Outlaw IDE

有免費版 : Outlaw Lite version ,可建立專案的數量有限

有 syntax highlighting 與 auto complete 功能

用來產生 Sprite sheet 圖檔

TexturePacker

用來設定 Physics Parameters 以建立 Collision shapes

Gumbo - Corona Level Designer

Gumbo 可以自動產生 UI 的 Lua Code ,有 Web 與 PC 版

LevelHelper

用拖曳 (Drag and drop) 的方式建立關卡 (level)

Cutting EngineJoints

Custom ShapesPath Movement

tiled map editor

Lime 2D Tile Engine

Lime 可以使用 Tiled 產生的 Map

Feature Demo: http://bit.ly/17jGVMr

補充資料

App Icons for iOSFile Size (w x h) Purpose

Icon.png 57 x 57 Icon - iPhone

Icon@2x.png 114 x 114 Icon - Retina iPhone

Icon-72 72 x 72 Icon - iPad

Icon-72@2x.png 144 x 144 Icon - Retina iPad

Icon-Small-50.png 50 x 50 Search - iPad

Icon-Small-50@2x.png 100 x 100 Search - Retina iPad

Icon-Small.png 29 x 29 Search - iPhone

Icon-Small@2x.png 58 x 58 Search - Retina iPhone

App Icons for Android

File Size (w x h)

Icon-xhdpi.png 96 x 96

Icon-hdpi.png 72 x 72

Icon-mdpi.png 48 x 48

Icon-ldpi.png 36 x 36

Android Manifest Permissions-- build.settingssettings{ android = { versionCode = "11", -- App 版本號碼 version 1.1 usesPermissions = {

"android.permission.INTERNET","android.permission.VIBRATE",

"android.permission.ACCESS_FINE_LOCATION","android.permission.CAMERA","android.permission.REBOOT",

}, },}

在專案資料夾下建立 build.settings上列這些設定代表需要 :

「存取網路、設備震動、 GPS、 Camera 以及重開機」等權限

Android 支援的 Permissions

http://bit.ly/S2Met

HelloVibrate

安裝時會要求「控制震動」的權限點按 App 的 [Vibrate] 按鈕就會產生震動

HelloVibrate

build.settings

-- build.settingssettings ={

android ={

usesPermissions ={

"android.permission.VIBRATE",}

}}

main.lualocal widget = require( "widget" )

local function btnClicked(event)-- 讓設備震動system.vibrate()

end

-- Create a simple buttonwidget.newButton{

left = 60,top = 120,label = "Vibrate",onRelease=btnClicked

}

只要 system.vibrate() 一行程式碼就可以讓設備震動一下

如何發 Email 與簡訊

native.showPopup()顯示系統預設的 popup window可用來發 Email, SMS 簡訊 , twitter 訊息等

功能說明

native.showPopup( name, options )語法

點按 [Sample Apps > Netwokring > ComposeEmailSMS] 打開範例

發 HTML Email-- 發一封 HTML email 給兩位收件人local options ={ to = { "john.doe@somewhere.com",

"jane.doe@somewhere.com" }, cc = { "john.smith@somewhere.com",

"jane.smith@somewhere.com" }, subject = "My High Score", isBodyHtml = true, body = "<html><body>I scored over <b>9000</b>!!!"

"Can you do better?</body></html>", attachment = {

{ baseDir=system.ResourceDirectory, filename="email.png", type="image" },

{ baseDir=system.ResourceDirectory, filename="coronalogo.png", type="image" },

},}native.showPopup("mail", options)

執行結果

發 SMS 簡訊

-- 發一則 SMS 簡訊 ( 不支援夾檔 )local options ={ to = { "1234567890", "9876543210" }, body = "I scored over 9000!!! " ..

"Can you do better?"}native.showPopup("sms", options)

保存 Game Settings

到這裏 http://bit.ly/1f1lh3O 下載 loadsave.lua loadsave.lua 可以把 Lua table 存成 json 檔,也可以反 過來把 json 檔轉成 Lua table

1

以 saveTable(tableName, filename) 保存設定2

以 tableName = loadTable(filename) 載入設定3

保存設定

local loadsave = require("loadsave")

appSetings = {

musicOn = true,score = 80,lives = 1

}

loadsave.saveTable(appSettings, "appSettings.json")

appSettings.json 會被儲存到 system.DocumentsDirectory如 /data/data/com.coopermaa.helloworld/appSettings.json

載入設定

local loadsave = require("loadsave")

appSettings = loadsave.loadTable("appSetings.json")

if appSettings == nil thenappSettings = { musicOn = true, score = 0, lives = 3}loadsave.saveTable(appSettings, "appSetings.json")

end

若找不到檔案, loadTable() 會回傳 nil可判斷回傳值以決定是否使用預設值

使用自訂字型(Load Custom Fonts)

CustomFont

不喜歡系統預設字型嗎?

-- 使用系統預設字型顯示 Textdisplay.newText("12345", 30, 60, native.systemFont, 90)display.newText("24680", 30, 180, native.systemFont, 90)

安裝自訂字型 - iOS-- build.settingssettings ={

iphone ={

plist ={

UIAppFonts ={

"fonts/DS-DIGI.ttf"},UIApplicationExitsOnSuspend =

true}

}}

以 DS-Digital 字型為例 : http://bit.ly/7dqQ7G把字型檔 DS-DIGI.ttf 放到一個資料夾下 (e.g. fonts)

安裝自訂字型 - Mac, Windows, Android

注意事項: 1. Windows 裝好字型後,必須重開 Corona Simulator 才能載入字型 3. 在 Android 上,字型檔名大小寫有別,而且副檔名一定要用小寫

Mac: 在字型檔上點按兩下以安裝

Windows: 在字型檔按右鍵,然後選 [ 安裝 ]

Android: 把字型檔放到專案資料夾裏

在 Windows 7 上安裝字型

使用自訂字型

-- 使用自訂字型 DS-Digital 顯示 Textdisplay.newText("12345", 30, 60, "DS-Digital", 100)display.newText("24680", 30, 180, "DS-Digital", 100)

在 Mac 與 Windows 上,字型名稱可能會不一樣在 Android 上,檔案名稱 ( 不加副檔名 ) 就是字型名稱

讓程式跨平台-- 同一套字型,在不同平台下名稱可能會不一樣-- 底下會根據平台調整字型的名稱local platform = system.getInfo("platformName")local font = "DS-Digital"

if platform == "Win" thenfont = "DS-Digital"

elseif platform == "Android" then-- filename with no extension, case sensitivefont = "fonts/DS-DIGI"

else-- Mac and iOSfont = "DS-DIGI"

end

-- 使用自訂字型 DS-Digital 顯示 Textdisplay.newText("12345", 30, 60, font, 100)display.newText("24680", 30, 180, font, 100)

在 App 中置入廣告

廣告目的

Corona SDK 支援的廣告網路

置入 Google AdMob 廣告的步驟

申請 AdMob 帳號1

到 AdMob 網站新增應用程式2

整合 AdMob 廣告到你的 App 裏3

申請 AdMob 帳號1

連到 http://www.google.com.tw/ads/admob/點按 [申請 AdMob]

直接用 Google 帳號登入

點按右上角的 [登入 ] 直接用 Google 帳號登入或是填寫表單申請新的 Google 帳號也可以

輸入 Google 帳密

填寫個人資料後按 [ 提交 ]

添加第一個應用程式

這是第一次新增 App 的畫面以後要從 AdMob 首頁進入以新增 App (見下頁 )

新增網站 /應用程式

以後新增 App 要從這個位置進入

輸入稅務資料

在使用 AdMob 前,要先輸入收款的稅務資料付款詳細資料建議用 PayPal ,屆時可轉帳到指定銀行帳

到 AdMob 網站新增應用程式2

點按 [網站與應用程式 > 新增網站 /應用程式 ] 並點按 [Android 應用程式 ]

填寫應用程式資料

有關 Android 套裝 URL 請見下頁說明

Android 套裝 URL

把 App 在 Google Play 上的網址 ( 上圖紅框處 ) 填入 Android 套裝 URL 欄位。這只是方便讓使用者移至 App 詳細資料頁面,

輸入個人網站也可以,不寫也沒關係

下載 AdMob Android SDK (Java User only)

用 Corona SDK 寫 App 的不需下載

收益報告

點按 [網站與應用程式 >網站與應用程式 ] 即可看到收益報告

管理設定

在收益報告頁面上點 App 的 [管理設定 ]

取得發佈商 ID

之後 App 要用發佈商 ID 跟 AdMob 整合

整合 AdMob 廣告到你的 App 裏3

-- build.settingssettings ={ plugins = { -- key is the name passed to Lua's 'require()' ["CoronaProvider.ads.admob"] = { -- required publisherId = "com.coronalabs", }, }, }

在 build.settings 檔中加入上列設定其它廣告網站請參考 http://bit.ly/1eofiHE

在程式裏加入顯示廣告的程式碼-- main.lua-- 載入 'ads' library ( 在 Simualtor 下無法使用廣告 )local ads = require "ads"-- 發佈商 IDlocal appID = "a152396ea402f78"

myText = display.newText( "Hello AdMob", 50, 50, "Arial", 32 )

local function adListener(event)-- 收不到廣告時,印出錯誤訊息if event.isError then

print(event.response)end

end -- 設定廣告 appIDads.init( "admob", appID, adListener )-- 在指定位置顯示廣告,每 60 秒更新一次ads.show( "banner", { x=0, y=250, interval=60 } )

手機上執行的結果

HelloAdMob

申請 PayPal 帳號

申請 PayPal

• eBay 子公司• 線上金流• 可用來線上付款• 也可以線上收款,包括收取 AdMob 的款項

• 網站 : https://www.paypal.com/tw

註冊帳號

到 PayPal 網站點右上角的 [ 立即註冊 ]

選擇 [ 個人 ] PayPal 帳號

[ 個人 ] 不能接受別人信用卡付款, [特選 ] 可以,但是要手續費,適合網拍賣家, [商業 ] 適合公司行號

填寫個人資料

可以用中文填寫。日後用 email 登入 PayPay

設定密碼提示

輸入信用卡卡號

輸入信用卡卡號才可以用 PayPal 線上購物刷卡若不需要線上購物付款,例如只是用來收 AdMob 款項

者可跳過與信用卡相關的步驟

確認電子郵件啟用帳號

完成電子郵件確認

輸入 PayPay 登入密碼後即完成電子郵件確認

確認信用卡郵件

等收到信用卡月結單時,上面會有 NTD 70 的費用要找一下 4 位數代碼

信用卡認證

點按 [獲得認證 ] 。 PayPal 會從信用卡帳戶扣除 NTD 70 ,目的是確認此信用卡是否為您所有

輸入 4 位數代碼

完成認證

會看到「感謝您!我們會在 24小時內退還所有費用。」

帳戶變成 [已認證 ]

之後便可以用 PayPal 線上付款

使用 PayPal 領取 AdMob 廣告收入

收到 AdMob 付款通知

登入 PayPal

登入後,前往我的帳戶

會看到 AdMob 的付款資訊

點按 [接受 ]

接受付款

提領

在 [我的帳戶 ] 底下點按 [ 提領 ]

選擇提領交易款項的方式

點按 [ 提領交易款項到你的銀行帳戶 ]

輸入銀行帳戶資料

核對資料

輸入交易款項金額

最後按下 [ 提交 ]

完成交易

會收到轉帳通知郵件

等轉帳完成,就可以在你的銀行帳號看到入帳囉

top related