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

최근에 받은 트랙백

글 보관함


Working with Time: Delays and Counting 

Posted by Jonathan Beebe

time 을 사용하는 앱이나 게임은 무수히 많습니다. 몇 초 후에 어떤 일이 일어나게 하던지 유저가 얼마 안에 특정 일을 끝내게 해야 한다던지 같은 시간을 컨트롤 해야 할 일들은 많습니다.

Corona SDK에서는 이러한 time을 빠르고 쉽게 콘트롤 함으로서 게임이나 앱의 개발에 도움을 줄 수 있는 가이드를 제공하고 있습니다.

이 튜토리얼에서는 코로나의 아주 유용한 timer.performWithDelay() 함수에 대해 소개하려고 합니다. 그리고 이 함수를 가지고 여러분의 앱에서 간단하게 활용할 수 있는 방법도 알려 드리겠습니다.

Time Delays


timer.performWithDelay() 는 특정 시간 이후에 특정 동작을 행할 수 있도록 해 줍니다. 이 함수 이름만 봐도 이 함수가 뭘 하는지 쉽게 짐작하실 수 있을 겁니다.

아래 신택스가 있습니다.

timer.performWithDelay( delay, listener [, iterations] )


여러분이 이 함수를 call 했을 때 여러분은 얼마동안 delay 하는지에 대해 정해 주시면 됩니다. (단위는 밀리세컨드입니다.) 그리고 그 지정된 시간이 다 됐을 때 불리워질 함수를 넣으시면 됩니다. 옵션으로 이 작업을 몇번이나 반복해서 수행하는지도 iterarions 에 숫자를 넣어서 정해 주시면 됩니다. 디폴트는 1 입니다.

What are iterations?

timer iteration은 이 timer.performWithDelay 를 몇번 수행할지 정해 주시는 부분입니다. 이 숫자를 0으로 지정하시면 이 timer를 remove 하거나 앱을 종료할 때까지 무한으로 반복합니다.


다음에는 timer.performWithDelay() 함수와 함께 anonymous 함수를 어떻게 사용할 수 있는지에 대해 알려드리겠습니다.





Using a function

아래 예제에서는 1초 후에 hello_world() 함수를 call 하는 것을 단 1회 시작하도록 코딩 했습니다.

local function hello_world()
  print( "Hello world!" )
end

timer.performWithDelay( 1000, hello_world, 1 )


hello_world vs. hello_world()

계속 진행하기 이전에 많은 개발자 분들이 혼동하시는 부분에 대해 명확히 밝히고 넘어가겠습니다. 위 예제에서 timer.performWidhDelay() 함수의 두번째 인수로 hello_world() 를 사용하지 않고 hello_world 를 사용한 점입니다.

그 이유는 이것은 존재하는 함수를 단지 참조하라고 알려주는 것이라서 입니다. 그래서 우리는 그 함수의 변수명(variable name)을 사용하면 되는 겁니다. 만약에 여기에 hello_world()를 사용한다면 이 함수를 실제로 call 하게 되는 겁니다. 그러면 hello_world() 함수에서 return 되는 값에 따라 그 다음 동작이 일어날 수도 있고 안 일어 날 수도 있습니다. 기본적으로 함수의 디폴트 return 은 nol 이기 때문에 그렇게 하면 문제가 발생할 수가 있습니다. 그래서 함수명이 아니라 변수명을 사용하시는 겁니다.


Using anonymous functions

timer.performWithDelay() 함수의 두번째 인수가 함수가 들어가는데요. 여기에 anonymous 함수를 사용할 수도 있습니다. 그냥 이 부분에 함수를 구현하실 수 있다는 애기입니다. 아래 예제에서 보시는 대로 두번째 인수에 이 함수를 구현하시면 됩니다.

timer.performWithDelay( 1000, function()
  print( "Hello world!" )
end, 1 )


물론 이것을 1라인으로 만들 수도 있지만 이것이 함수인것을 좀 더 이해하기 쉽도록 하기 위해 저렇게 줄을 나눴습니다.

이 anonymous 함수를 사용하실 때 알아두셔야 할 점은요. 쉼표 (,) 사이에 전체 함수 (function() 에서 end 까지)가 들어가야 한다는 것입니다. 그래야지 timer.performWithDelay()는 이 인수가 valid 하다고 판단합니다.

좀 더 자세한 정보는 1년전에 Eric Wing이 작성한 using closures as function callbacks 튜토리얼을 보시면 아실 수 있을 겁니다.

Passing Arguments to the Listener

timer.performWithDelay()를 사용하면서 많이 나오는 질문이 호출하는 함수에 어떤 인자를 전달할 수 있느냐 입니다.

이것을 구현하는 방법은 아래와 같이 하시면 됩니다.

local function hello_world( arg1, arg2 )
  print( "Hello world!", arg1, arg2 )
end

timer.performWithDelay( 1000, function()
    hello_world( "first", "second" )
end, 1 )


어떻게 하는지 아시겠죠? timer.performWithDelay() 안에서 anonymous 함수를 사용해서 그 함수에서 외부 함수를 인수와 함께 호출했습니다.
좀 헛갈리시나요? 몇번 해 보시면 금방 익숙해 지실 겁니다.

Other functions

timer 함수는 timerId를 return 합니다. 그래서 다른 함수가 이 timerId를 가지고 어떤 동작을 하도록 컨트롤 할 수 있습니다. timer 함수에는 timer.pause, timer.cancel(), timer.resume() 등의 메소드가 있습니다. 이 메소드들은 이름만 봐도 어떤 일을 하는지 알 수 있겠죠? 자세한 내용은 timer API reference page 를 참조하세요.

Counting Time


앞서 얘기했듯이 앱에서 이 time을 컨트롤 해야 할 상황이 아주 많습니다. 예를 들어 게임을 시작하는 시간과 끝나는 시간을 한번 catch 해 봅시다.

이 게임을 시작하는 부분에 아래 코드를 넣습니다.

local markTime = os.time()

os.time()
이 함수는 현재의 시간을 return 합니다. (위와 같이 아무런 인자 없이 call 했을 경우) 이외에도 더 많은 기능이 있는데요. 그 기능은 여기를 참조하세요.



사용자가 game over 상태에 이르렀을 때 아래 코드로 게임 시간이 얼마나 길었는지를 얻어낼 수 있습니다.

local timePassed = os.time() - markTime


처음 시작했을 때의 시간이 markTime 이니까 끝날 때의 현재시간 (os.time()) 에서 markTime을 빼면 게임 시간이 나오겠죠? 여기서 timePassed 는 초단위로 값을 갖고 있습니다. 분단위로 표시하고 싶으면 이 값을 60으로 나누면 되겠죠. 밀리세컨드로 하려면 1000을 곱하면 되겠구요. 밀리세컨드로 곧바로 값을 받을 수도 있습니다. system.getTimer()를 이용하시면 됩니다. 이용하시는 방법은 위와 똑 같구요.

Time’s up!

이제 여러분은 timer.performWithDelay() 함수를 사용하시는데 프로가 되셨습니다. 그리고 여러분의 앱에서 어떻게 time을 관리해야 하는지에 대해서도 이해하셨을 겁니다.

time 과 관련된 다른 함수들들을 더 이해하고 싶으시면 os.clock(), os.date(), os.difftime(), system.getTimer() 함수들을 보시면 더욱 더 유용하게 여러분의 앱에서 time을 컨트롤 하실 수 있을 겁니다.

반응형

Comment

  1. dk 2012.04.27 20:19

    언제나 도움되는 글 감사합니다.
    하나 보태자면, 타이머 컨트롤을 위해 timer ID를 담아놓는 핸들러를 쓰는 습관,
    local timerHandle = timer.performWithDelay(...) 하는게 꼭 필요하겠더라고요.