美思 [Solar2D] 程式設計教學:利用 Composer 在應用程式中切換頁面

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

[注意事項] Corona 已改名為 Solar2D

在先前的範例中,我們的程式皆位在單一頁面上;透過 Solar2D 提供的 composer 函式庫,我們的程式可在不同頁面間切換。我們將完整的程式碼放在這裡,本文僅節錄部分內容。

程式的示意圖如下:

{{< figure src="img/corona-sdk/composer.png" alt="Solar2D 的 Composer 範例" class="phone" >}}

本範例的 main.lua 相當簡單:

local composer = require("composer")

composer.gotoScene("index")

因為我們的主程式只是用來過水到第一個場景 (scene) 而已。

由於場景的程式碼比較長,在觀看真正的程式碼前,我們先將架構的部分抽出來看:

local composer = require("composer")

local scene = composer.newScene()

-- create()
function scene:create( event )
end

-- show()
function scene:show( event )
end

-- hide()
function scene:hide( event )
end

-- destroy()
function scene:destroy( event )
end

scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

return scene

在 Solar2D 程式中,場景要寫成 Lua 模組 (module),供其他程式呼叫。如果不熟模組如何撰寫,可以參考這裡的說明。

場景有 "create""show""hide""destroy" 四個生命階段,分別對應頁面生成、顯示、隱藏、銷毀等不同階段。我們在撰寫 Solar2D 的場景時,就是依照這樣的架構,各自填入不同階段所要進行的行為即可。

接下來,我們會用本範例程式展示場景的四個階段。

在一開始,我們先準備一段無意義的文字 (lorem ipsum),用來填充版面:

local text = "Lorem ipsum dolor sit amet, vix ut persius laoreet consulatu, "
  .. "et populo equidem fastidii vel. Usu no scripta similique. "
  .. "Numquam fabellas his ex. Et ius dictas dolores forensibus, "
  .. "ea propriae salutatus sea. Per ei veri dicta conclusionemque, "
  .. "exerci eripuit per ex, tale appareat efficiendi nec et."

這種無意義文字稱為 lorem ipsum,主要的用途是用一些沒有實際意義的文字填塞版面,用來看排版的效果,在國外的網頁教學有時候會看到這個東西。

如果讀者需要一些填塞版面的文字,不用自己生,網路上可以找到一些生成器,像是這個

create 階段,我們產生三個物件,程式碼如下:

-- create()
function scene:create( event )
  local sceneGroup = self.view

  local title = display.newText(
    {
      text = "My App",
      x = display.contentWidth * 0.5,
      y = display.contentHeight * 0.12,
      fontSize = 28,
    }
  )

  title:setFillColor(0 / 255, 0 / 255, 0 / 255)

  sceneGroup:insert(title)

  local content = display.newText(
    {
      text = text,
      x = display.contentWidth * 0.5,
      y = display.contentHeight * 0.45,
      width = display.contentWidth * 0.9,
      fontSize = 18,
    }
  )

  content:setFillColor(0 / 255, 0 / 255, 0 / 255)

  sceneGroup:insert(content)

  local btnNext = widget.newButton(
    {
      x = display.contentWidth * 0.5,
      y = display.contentHeight * 0.85,
      label = "Next",
      fontSize = 20,
      emboss = false,
      shape = "roundedRect",
      width = 100,
      labelColor = {
        default = { 0 / 255, 0 / 255, 0 / 255},
        over = { 0 / 255, 0 / 255, 0 / 255},
      },
      fillColor = {
        default = { 180 / 255, 255 / 255, 255 / 255},
        over = { 110 / 255, 255 / 255, 255 / 255},
      },
      onEvent = function (ev)
        composer.gotoScene("next")
      end
    }
  )

  sceneGroup:insert(btnNext)
end

這些物件的生成方式我們先前都看過了,此處的重點在於用 sceneGroup 將這些物件串連起來,之後就可以一起調整其可視度。另外注意我們將切換場景的動作藏在按鈕的事件處理器中。

show 階段中,又會在細分兩個時期,分別是 "will""did",前者在場照即將開始時發動,後者則是在場景顯示在螢幕後發動。程式碼參考如下:

-- show()
function scene:show( event )

  local sceneGroup = self.view
  local phase = event.phase

  if ( phase == "will" ) then
    sceneGroup.isVisible = true
  elseif ( phase == "did" ) then

  end
end

有關該場景的詳細說明在此,讀者可自行參考。

同樣地,在 hide 階段也分為兩階段:

function scene:hide( event )
  local sceneGroup = self.view
  local phase = event.phase

  if ( phase == "will" ) then

  elseif ( phase == "did" ) then
    sceneGroup.isVisible = false
  end
end

有關該場景的詳細說明在此

destroy 階段,我們會將物件銷毀,以釋放記憶體等系統資源:

function scene:destroy( event )
  local sceneGroup = self.view
  -- Code here runs prior to the removal of scene's view

  sceneGroup:removeSelf()
end

在本範例程式中共有三個場景,另兩個場景的概念雷同,故不重覆展示。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。