반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Director to Storyboard “Transition” Guide -2-


Switching Scenes

디렉터 클래스나 스토리보드 모두 화면 전환의 목적은 같습니다. 하지만 그 화면의 이면에서는 어떤 일들이 벌어지는지는 완전히 다릅니다. 그 다른 부분 중 어떤 것들은 여러분들이 컨트롤 해야 될 필요가 있고 어떤 부분들은 별로 신경을 쓰지 않아도 되는 부분이 있습니다.

Director Scene Transitions


아래 예제는 디렉터 클래스를 사용해서 scene1에서 scene2 로 전환하는 방법을 보여 드립니다.

-- somewhere in scene1.lua...
director:changeScene( "scene2", "moveFromRight" )


위 코드대로 하면 scene1은 움직여서 보여지지 않고 scene2 가 화면에 나타날 겁니다. moveFrimRIght로 해서 화면은 오른쪽에서 왼쪽으로 옮겨질 겁니다. (이런 화면 전환 효과를 사용하지 않으려면 changeScene의 두번째 파라미터를 없애면 됩니다.) 아래 내용들은 director:changeScene()이 call 됐을 때 화면 뒤에서는 어떤 일들이 일어나는지를 정리한 내용입니다.
   
    - 디렉터가 scene2.lua를 로드하고 제 위치에 위치 시킵니다.
    - 두 scene 모두 최종 목적지로 transition 됩니다.
    - 디렉터는 scene1의 display group이 clean()메소드를 가지고 있는지 체크하고 만약 있으면 메소드를 call 합니다.
    - scene1의 display group이 remove되고 scene1이 unload 됩니다.


아주 간단하고 직관적입니다. 만약 여러분이 디렉터 클래스 사용자라면 위에 정리한 내용이 아주 익숙할 겁니다. 이제 스토리보드에서는 같은 화면전환이면서 그 이면에 어떤 다른 일들이 일어나는지 살펴 보겠습니다.





Storyboard Transitions

아래 스토리보드 API 를 사용해서 scene1에서 scene2로 화면 전환하는 예제입니다.

-- somewhere in scene1.lua...
storyboard.gotoScene( "scene2", "slideLeft" )


아래는 위에서 처럼 gotoScene이 call 됐을 때 화면 뒤에서 어떤 일이 일어나는지를 정리한 내용입니다.

    - scene1 : "exitScene" 이벤트가 dispatch 됩니다.
    - scene2 : 만약 view display group 이 없으면 새로 생성해서 시작 위치에 위치 시킵니다. (시작 위치는 화면전환 효과에 따라 달라집니다.) 그리고 나서 createScene 이벤트가 createScene 이벤트가 dispatch 됩니다.
    - scene2 : 만약 view 가 이미 존재한다면 그것을 시작 위치에 위치 시킵니다.
    - scene2 : willEnterScene 이벤트가 dispatch 됩니다. scene1과 scene2가 제 위치로 이동합니다.
    - scene1 : didExitScene 이벤트가 dispatch 됩니다.
    - scene2 : enterScene 이벤트가 dispatch 됩니다.


아주 많은 것들이 진행 되는 것 같네요. 그것들이 모두 유용한 것들입니다.

위에서 ~event가 dispatch 된다는 것은 그 이벤트를 이용해서 listener 함수를 사용하고 그 안에서 여러분이 어떤 작업을 할 수 있다는 얘기입니다. (뭐든지 필요한 기능을 구현하시면 됩니다.) 너무 복잡하게 느끼실 필요가 없습니다. 스토리보드의 다양한 이벤트를 이용해서 무엇을 구현한다는 것은 필수가 아닙니다. 여러분이 필요한 부분만 사용하시면 됩니다. 만약 여러분이 willEnterScene 이벤트를 작성하지 않았다면 이 이벤트는 dispatch 된 다음게 그대로 cancel 될 겁니다.

Which one should you use?

이 글을 쓴 목적은 디렉터 클래스 대신 스토리보드 API를 사용하라거나 반대로 스토리보드 대신 디렉터 클래스를 사용하라고 설득하기 위해 쓴 것이 아닙니다. 이 글의 목적은 디렉터 클래스의 주요 기능들을 스토리보드 API를 사용할 때 어떻게 사용해야 하는지를 보여드리기 위해 쓴 글입니다.

스토리보드 API는 코로나 SDK에서 화면 관리하는 것을 지원하려고 만든 코로나 SDK의 공식 API 입니다. 그렇다고 해서 여러분이 필요한데도 디렉터 클래스를 사용하지 말고 스토리보드 API를 사용하라는 의미가 아닙니다. 어떤 분들은 간단하게 화면 전환을 컨트롤 할 수 있는 디렉터 클래스를 선호할 것입니다. 그리고 디렉터 클래스는 오픈 소스 스크립트 입니다. 그리고 다른 관점에서 보면 스토리보드를 이용해서 코로나 이벤트 모델을 사용함으로서 좀 더 유연하고 다양한 기능을 사용하기 원하는 분들은 스토리보드 API를 선호할 겁니다.

어느것을 선택하시든 여러분들의 프로젝트에 더 적합한 수단을 사용하시면 되고 이 글을 통해 그 사용 법을 익힐 수 있었기를 바랍니다. 만약 여러분이 디렉터 클래스를 사용하시다가 스토리보드를 사용하시는데 어려운 부분이 있었다면 이 글을 통해서 그 혼란 스러움이 다 가셨기를 바라는 마음입니다.

특별히 스토리보드에 대해 좀 더 알고 싶으시면 이 링크를 클릭하셔서 공식 Storyboard API 문서를 보세요.

반응형


반응형

Director to Storyboard “Transition” Guide -1-

Lights… camera… CUT!

조명... 카메라... 컷!

코로나의 Storyboard API 가 나온지 꽤 됐습니다. 그런에 이 사용법에 대해서는 아직까지 약간의 혼동이 있는 것 같습니다. 최근에 제가 소개해 드린 스토리 보드의 이벤트 에 대한 글이 그 혼동을 해소하는데 약간 도움이 될 수 있을 겁니다. 하지만 스토리보드에 대한 설명은 단 한번으로는 부족할 겁니다.

스토리보드 API 이전에 Corona SDK에서는 scene 관리를 위한 공식적인 솔루션은 없었습니다. 그래서 대부분의 사람들은 Ricardo Rauber의 Director 클래스를 사용 했었죠. scene 관리를 도와주는 정말 대단한 3rd-party 오픈 소스 라이브러리 였습니다. 또한 scene 전환은 여러개의 쿨한 화면전환 효과를 사용해서 구현 할 수도 있었죠. 스토리보드가 나왔을 때 그 디렉터 클래스와는 사용법이 많이 달랐습니다. 그래서 디렉터 클래스 사용자들이 스토리보드를 곧바로 사용하는것은 좀 어려웠었던 것 같습니다.

그래서 오늘 여러분이 Director class를 사용하고 있다면 어떻게 스토리보드를 사용할 수 있는지 간단하면서도 쉽게 설명 드리겠습니다. 그리고 만약 여러분이 director class 유저가 아니라면 곧바로 스토리보드를 배울 수 있는 좋은 기회일 겁니다. 그런 분들은 이 문서를 꼭 보실 것을 권장합니다. (그 곳에는 more information section 있습니다.)





Scene Templates

디렉터 클래스는 오래 전부터 있어 왔습니다. 그 클래스는 꽤 큰 feature set 입니다. 저는 이 튜토리얼에서 module structure와 scene 변환에 대한 기본적인것을 다룰께요.

우선 Director 1.4의 scene template 으로 시작하죠. (이 글을 쓰는 현재 가장 최신 버전입니다.)

template.lua (Director)

module(..., package.seeall)

--====================================================================--
-- SCENE: [NAME]
--====================================================================--

new = function () 
    ------------------
    -- Groups
    ------------------
  
    local localGroup = display.newGroup()
  
    ------------------
    -- Your code here
    ------------------
  
    --- CODE ---
  
    ------------------
    -- MUST return a display.newGroup()
    ------------------
  
    return localGroup
end


디렉터 클래스는 아주 간단하고 사용하기 쉽습니다. (그래서 개발자들이 아직까지 이 방법을 사용하고 있는 이유겠죠). 바로 위에 소개한 scene tamplate 에 대한 설명을 하겠습니다.

new() 함수안에 여러분의 scene과 관련된 코드가 들어갑니다. 그리고 중요한것은 모든 display 객체들은 같은 group에 insert 하셔야 합니다. 그리서 그 그룹이 마지막에 return 되야 합니다. (위 예제에서는 localGroup이 됩니다.)

화면전환 (scene transition)이 발생하면 디렉트 클래스는 현재 화면을 밖으로 보내고 그 다음 화면을 화면으로 불러옵니다. (이 때 화면 전환 효과를 사용하실 수 있습니다.)

화면 전환이 완료 되면 이전 화면은 remove 됩니다. 옵션으로 clean() 메소드를 화면의 group에 추가해도 됩니다. 이것은 화면을 remove 하기 바로 전에 call 됩니다. clean() 메소드는 timer들을 정지시키고 Runtime listener를 remove 하기에 좋은 메소드 입니다. 아래 예제는 이 clean() 에소드가 포함된 경우 입니다.

template.lua (Director)

module(..., package.seeall)

--====================================================================--
-- SCENE: [NAME]
--====================================================================--

local cleanUp = function()

    -- stop timers, transitions, listeners, etc.

end

new = function () 
    ------------------
    -- Groups
    ------------------
  
    local localGroup = display.newGroup()
  
    ------------------
    -- Your code here
    ------------------
  
    --- CODE ---
  
    ------------------
    -- MUST return a display.newGroup()
    ------------------

    -- add clean method
    localGroup.clean = cleanUp
  
    return localGroup
end


Storyboard Scene Template

위의 코드를 스토리보드 API를 사용해서 구현하려면 어떻게 해야 되는지에 대한 예제가 아래에 있습니다.

scenetemplate.lua (Storyboard)

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

--------------------

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

    --
    -- Create objects here (e.g. scene creation)
    --
end

--------------------

function scene:enterScene( event )

    --
    -- Manipulate objects here (e.g. scene logic)
    --
end

--------------------

function scene:exitScene( event )

    --
    -- Optional cleanup code here
    --
end

--------------------

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

return scene


디렉터 클래스의 new() 함수에 해당하는 스토리보드의 이벤트는 두가지가 있습니다. createScene과 enterScene 입니다. 사실 좀 더 있지만 일단 이 두가지를 보기로 하겠습니다.

스토리보드에서는  self.view 를 사용해서 그 화면의 view display group에 접근 할 수 있습니다. 디렉터 클래스에서 localGroup에 해당 화면의 모둔 객체들을 insert 했듯이요. 스토리보드에서도 그 화면의 모든 객체들을 self.view에 insert 하셔야 합니다. 이것을 하기에 가장 좋은 장소는 바로 createScene event listener 입니다.

위 예제에서 마지막에 있는 이벤트 리스너는 exitScene 이벤트 입니다. 이 부분은 디렉터 클래스의 clean() 메소드와 비슷합니다. 이 함수에서 타이머나 transition들을 정지시키고 Runtime listener들을 remove 시키는 등의 일을 하시면 됩니다.

스토리보드에서는 왜 이렇게 세분화 해서 나눴는지 궁금하실 겁니다. 나중에 설명 드리겠습니니다. 일단 왜 스토리보드에서는 createScene과 enterScene이 나눠졌는지를 알려드릴께요.

It has to do with scene “purging”.

디렉터 클래스와는 다르게 스토리보드에서 화면이 사라질때 그 화면은 자동적으로 remove 되지 않습니다. 그냥 화면 밖으로 사라져 버릴 뿐입니다. 여러분이 purge를 사용해서 그 scene을 따로 remove 시켜야 합니다. remove 되지 않는 다는 것은 그 화면의 객체들이 여전이 메모리에 있다는 얘기고 그러면 그 다음에 다시 그 화면을 불러 올 때 더 빨리 불러 올 수 있다는 얘기입니다. 그래서 자동적으로 remove 시키지 않고 개발자가 따로 함수를 사용해서 remove 시키도록 돼 있습니다.

Caveat : 만약 OS가 메모리가 부족하다는 경고를 보내면 최근에 접근된 화면이 purge 될 겁니다. 이 경우가 유일하게 스토리보드에서 화면이 자동적으로 remove 되는 상황입니다. 다른 경우에는 purge 나 remove 함수를 사용해서 특정 화면이나 이전의 전체 화면을 remove 시킬 수 있습니다. purge나 remove 같은 용어들의 정확한 의미를 아시려면 Storyboard Scene Events를 살펴 보세요.

조금 전으로 다시 돌아가서, 다른 화면으로 전환했는데 이전 화면은 화면에서만 사라지고 실제로는 메모리에 있는 상황을 가정합시다. 그 경우에 그 이전 화면이 다시 call 됐을 때 그 화면의 createScene event는 불려지지 않을 겁니다. (왜냐하면 이전에 이미 불려졌기 때문이죠). 이것이 createScene과 enterScene 이벤트가 둘로 분리된 가장 큰 이유입니다.

위 예제에 있는 것 말고도 여러분들이 사용할 수 있는  몇개의 Storyboard scene event들이 더 있습니다. 이것들을 모든 경우에 다 사용하셔야 된다는 것은 아닙니다. 필요한 경우에 사용하시면 됩니다.

   -  createScene
    - willEnterScene
    - enterScene
    - exitScene
    - didExitScene
    - destroyScene

위 이벤트들에 대한 좀 더 깊은 설명을 보려면 Storyboard Scene Events Explained 글을 봐 주세요. 그 글에는 각 이벤트들이 실행되는 순서를 보여주는 다이어그램도 있습니다. 그러니까 스토리모드의 위 이벤트들에 대해서 이해하시기 어려우시거나 좀 더 확실하게 사용하시려면 위 글을 봐 주세요. 


---- o ---- o ---- o ---- o ---- o ----


다음 글에서는 디렉터 클래스와 스토리보드 API 의 화면전환에 대해 비교해 보겠습니다.


반응형


반응형

얼마전 KOW님 질문에 대한 corona sdk 의 답변이었죠?


코로나로 개발하면서 안드로이드의 메뉴 버튼 클릭했을 때 이것을 콘트롤 할 수 있느냐는 거요.

대답은 event.keyName API를 보라는 거였는데요.


그 document를 아래 번역합니다.

예제 소스도 하나 만들었습니다.


event.keyName

Description:

"key" 리스너를 사용해서 눌려진 navigation key 의 이름을 스트링으로 얻습니다. key의 state (up,down)에 대한 사항은 event.phase를 보세요.

Note : home 하고 text 키들 (A-Z,0-9,punctuation)을 capture 될 수 없습니다.

** 안드로이드 디바이스에만 해당 됩니다.***


Syntax: keyName = event.keyName


Example:

-- Key listener
local function onKeyEvent( event )
        local phase = event.phase
        local keyName = event.keyName
        eventTxt.text = "("..phase.." , " .. keyName ..")"
 
        -- we handled the event, so return true.
        -- for default behavior, return false.
        return true
end
 
-- Add the key callback
Runtime:addEventListener( "key", onKeyEvent );


Note : keyEvent 리스너에서 false를 사용하면 해당 키의 디폴트 액션이 실행 됩니다.


Parameters: 없음


Returns: string


눌려진 navigation key의 이름이 return 됩니다 : "back", "search", "menu", "volumeUp", "volumeDown".

The D-Pad/Trackball key strings 는 "up", "down", "left", "right", "center" 가 return 됩니다

Note: home 키는 캡쳐 될 수 없습니다.


안드로이드 디바이스에서만 가능하고 코로나 SDK Build 2011.559 이상에서만 작동 합니다.

   

이상입니다.





위 소스를 조금 변경해서 아래 샘플 코드를 만들어 봤습니다.


-- Key listener
    _W = display.contentWidth;
    _H = display.contentHeight;
local txtPhase, txtKeyName, haveFun

txtPhase = display.newText( "Phase ", _W/2, _H/5, native.systemFont, 32 )
txtKeyName = display.newText( "KeyName : ", _W/2, _H/3, native.systemFont, 32 )
haveFun = display.newText( "Move", _W/8, _H/2, native.systemFont, 32 )

local function onKeyEvent( event )
        local phase = event.phase
        local keyName = event.keyName

        txtPhase.text = phase;
        txtKeyName.text = keyName;

        haveFun.x = haveFun.x + 50;
        if(haveFun.x > _W) then haveFun.x = 0 end
         -- we handled the event, so return true.
        -- for default behavior, return false.
        return true
end
 
-- Add the key callback
Runtime:addEventListener( "key", onKeyEvent );


main.lua에 이 소스를 붙여 넣고 실행하시면 화면에 phase와 keyName이 뜰겁니다.

제 디바이스에서 menu , back, search, volumeUp, volumeDown 등이 뜨는 거 확인 했어요.

마지막에 haveFun은 그냥 키가 눌려질 때 글자가 움직이도록 해 봤어요. 심심해서....


KOW님 덕분에 저도 몰랐던 사실을 알게 됬네요.


감사합니다.


반응형