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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

이번주에도 Corona SDK 에서 금주의 SDK FAQ 5개를 올렸습니다.

이 내용 번역해서 같이 공유 합니다.


FAQ Wednesday

Posted by Tom Newman 

수요일 입니다. 오늘도 자주 들어오는 5개의 질문을 골라서 답변해 드리겠습니다.

Question 1

코로나에서는 PNG 나 JPG 어떤 이미지를 써야 하나요?

Answer

이미지의 화질이나 앱 패키지의 사이즈 등에 따라 다를 수 있습니다. 코로나는 32비트 PNG 와 32비트 JPGs를 지원합니다. PNG는 손실없이 압축하면서도 투명 효과를 지원하고 JPG는 압축되지만 약간 손실이 있고 장점은 광범위한 Color range를 지원합니다. 같은 해상도에서 PNG는 일반적으로 JPGs 보다 사이즈가 큽니다. 이건 여러분의 앱 용량 제한 조건에 영향을 줄 수 있습니다.

texture 메모리 사용량에 대해  PNG와 JPG는 모두 같은 용량의 openGL 메모리를 차지합니다. 왜냐하면 이미지는 메모리에 로드됐을 때는 압축되지 않기 때문이죠. 또 한가지 알아두셔야 할 것은 이미지는 openGL 메모리에 로드됐을 때는 2의 제곱으로 (2, 4, 8, 16, 32, 64, 128, 256, 512, etc.) 로드 됩니다. 만약 여러분이 320*480, 280*400 두개의 이미지가 있을 때 이 이미지는 모두 512*512 만큼의 texture memory를 소비한다는 겁니다. 769*1024 이미지는 1024*1024 byte를 소비할 겁니다.





Question 2

가끔 began touch 이벤트는 있는데 ended 이벤트는 없는 경우가 있는데 왜 그런가요?

Answer

그런 현상은 버그가 아닙니다. 이런 일이 어떻게해서 일어나는지 그리고 어떻게 처리해야 하는지 개발자로서 잘 알아 두실 필요가 있습니다. touch 에는 began과 ended 이벤트가 있습니다. display object에 touch 리스너를 생성하셨다면 그 object를 touch 하면 일반적으로 began, moved, ended 이벤트를 받게 됩니다. 그리고 그 리스너를 어떻게 구현했는지 그리고 유저가 그 object에 대해 touch를 어떻게 발생했는지에 따라 touch 시에 특정 이벤트가 missing 될 수 있습니다.

아래 코드는 circle object에 대해 간단한 방법으로 touch 리스너를 단 예제입니다.

local circle = display.newCircle( 100, 100, 50 )

-- Touch listener
local function myTouch( event )
    print( "Touch event = " .. event.phase )
end

circle:addEventListener( "touch", myTouch )


만약 유저가 원을 터치하고 손을 떼면 리스너는 began과 ended 이벤트를 call 할 겁니다. 또 만약 손가락을 떼지 않고 화면에서 움직이면 moved 이벤트가 나올 겁니다.

유저가 그 원을 터치하고 움직이다가 원을 벗어났다고 생각해 봅시다. 그럴 경우에는 began 과 moved 이벤트만 생성되고 ended 이벤트는 생성되지 않을 겁니다. 왜냐하면 손가락을 뗀 행위는 그 원안에서 일어나지 않았기 때문입니다.

그러면 ended 이벤트는 어디로 갔을 까요? 답은 다른 object 리스너로 갔다 입니다. Runtime touch 리스너나 원이 아닌 다른 object 의 리스너로 간거죠.

그러면 그 다른 object의 이벤트는 어떨까요? 그 object에는 moved와 ended는 있지만 began이 없겠죠? 왜냐하면 touch 이벤트가 한 object에서 시작해서 그 object 를 떠나서 다른 object에서 마감을 했기 때문입니다.

만약 한 object에서 이벤트가 시작됐을 경우 그 이벤트의 끝이 그 object에서 작동하게 하려면 setFocus 를 쓰시면 됩니다.

local circle = display.newCircle( 100, 100, 50 )

-- Touch listener
local function myTouch( event )
    print( "Touch event = " .. event.phase )
  
    if "began" == event.phase then
        display.getCurrentStage():setFocus( circle )  -- set touch focus on circle
        event.target.focus = true
    end
  
    if "ended" == event.phase or "cancelled" == event.phase then
        if event.target.focus ~= true then
            return false
        end
        print( "Ended found" )
        display.getCurrentStage():setFocus( nil ) -- clear touch focus
        event.target.focus = false
    end

    return true
end

circle:addEventListener( "touch", myTouch )


이 예제에서 setFocus는 began 일 경우에 설정을 했습니다. 그리고 ended에서 이 setFocus를 해제를 했죠. 이러한 방법으로 해당 객체에서 이벤트가 시작됐으면 그 이벤트가 그 객체 밖에서 종료하더라도 해당 객체에 ended 가 적용되도록 만들 수 있습니다.

아래 문구에 대해서 주의 깊게 살펴 보실 필요가 있습니다.

event.target.focus = true

이 코드가 began 에서 사용됐죠 그리고 ended 에서도 false로 할당 하느라고 사용했습니다. 바로 이 코드가 해당 object에서 리스너가 일어나고 끝날 수 있게 컨트롤 해 주는 겁니다.

좀 touch에 대해 좀 더 자세히 알고 싶으시면 Detecting Touches in Corona 튜토리얼을 보시기 바랍니다.

Question 3

코로나에서 하수를 정의하는 두가지 방법에 대해서 봤습니다. 어떤게 올바른 건가요? 그리고 그 둘의 차이점은 뭔가요?

Answer

함수는 두가지 방법으로 생성하실 수 있습니다.

local function myfunc1()
    print( "function = ", myfunc1 )
end

and
local myfunc2 = function()
    print( "function = ", myfunc2 )
end


두개 모두 대부분의 경우 잘 동작합니다. 그런데 두번째의 경우에는 이 함수 내부에서  function name을 참조하는것이 필요한 경우에는 작동하지 않습니다. 왜냐하면 이 함수 변수인 myfunc2는 이 함수가 정의 되기 전까지는 아직 생성된게 아니니까요. 첫번째의 경우에는 함수 변수 myfunc1은 이 함수가 정의되기 이전에 생성된 겁니다. 그러니까 이 함수 내부에서 참조될 수가 있습니다. 위 두개의 코드를 시뮬레이터에서 실행하시면 첫번째는 myfunc1 값을 보실수 있지만 두번째는 nil을 보시게 될 겁니다.

myfunc1 함수는 아래와 똑 같습니다.

local myfunc1
function myfunc1()
...
end


저는 myfunc1 방식으로 함수를 사용하는 편입니다. 왜냐하면 저한테는 이게 더 전통적이라고 느껴지거든요. 그리고 함수 안에서 그 함수를 참조할 때 nil 값을 받을 염려도 없구요. 하지만 글로벌 함수로 이용한다면 두 함수 모두 똑 같습니다.

Question 4

config.lua 에서 스크린 사이즈를 640*960 (iPhone 4) 로 설정했습니다. 그랬더니 iPhone 3 에서는 이미지가 작게 나와요. 왜 그럴까요?

Answer

만약 여러분이 디바이스의 표준 해상도보다 큰 이미지를 로드하기 위해 display.newImage를 사용하신다면 이 이미지들은 config.lua 파일에 세팅된 width/height 에 근거해서 dynamic 하게 scale이 조절되기 전에 screen에 맞게 먼저 조절 됩니다. 예를 들어 600*100 픽셀짜리 이미지를 iPhone3 (320*480) 에 표시한다고 합시다. 이 이미지는 dynamic하게 scale 되기 전에 화면에 맞게 먼저 이미지가 작아질 겁니다. 이래서 iPhone4에 맞추면 iPhone3에서 이미지가 작게 보이는 이유입니다. 이것을 해결하려면 display.newImageRect (위의 경우에는 이미지 사이즈를 600*100으로 하시면 되겠죠)나 display.newImage와 isFullResolution flag를 true로 세팅하시면 됩니다. 이렇게 하면 native screen size에 근거해서 이미지가 scaling 되는 것을 건너 뛰게 해 줍니다.

Note : iPhone4에서 scale down 하기 위해 320*480 보다 큰 이미지를 사용하면 display.newImage에서 에러가 발생하는 버그가 있었습니다. 이런 현상은 dynamic scaling이 적용 되던 안되던 발생했습니다. 이 버그는 Daily Build 2012.788 에서 해결 됐습니다.

좀 더 자세한 정보는 Dyamic Image Resolution 을 참조하세요.

Question 5

iOS5 환경에서 코로나는 audio 관련 버그가 좀 있었습니다. 왜 애플과 관련해서계속 버그가 나오죠?

Answer


가끔 코로나의 버그들은 operating system 에서 발견된 버그에 기인하는 경우가 있습니다. 그 문제와 관련해서 해결책을 찾기위해 노력중입니다. 일단 최선의 방법은 그 OS에서 버그를 해결하는게 되겠죠. iOS5에서는 해결하기 어려운 openAL audio 버그들이 좀 있습니다. 저희들은 포럼들에 버그 메세지가 올라오는 것을 보고 그 버그를 지속적으로 수정하고 있습니다. 그리고 그 버그 해결과 관련한 글을 그 포럼들에 댓글로 답해주고 있습니다. 그리고 그 버그들을 정리하고 있습니다. 또 애플에 report를 하고 있구요.  더 많은 유저들이 이 버그에 대해 레포트를 한다면 애플에서 이 버그를 근본적으로 해결할 가능성이 커 지겠죠. Ansca 말고는 아무도 이 버그 레포트를 하지 않는다면 이 문제는 근본적인 해결이 어렵겠죠.

좀 더 자세한 정보와 애플 버그와 관련된 정보는 Apple Bug Reporter 에서 보실 수 있습니다.


 
 

반응형