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

최근에 받은 트랙백

글 보관함


Posted on . Written by


오늘의 guest tutorial 은 Omid Ahoural 의 두번째 글 입니다. ArdentKid 라는 별명으로 불리는 inDie Game Developer 입니다. 지난 2년간 Omid는 코로나를 접해 왔습니다. 그리고 그가 참여한 첫번째 앱인 "Balloon Bazooka" 의 출시를 앞두고 있습니다. 그는 또한 Corona 강좌를 제공하고 있기도 하구요. 그의 블로그 www.ardentkid.com에 가시면 보실 수 있습니다.



Optimizing Transitions


이제 곧 나올 저의 게임 퍼포먼스를 올리기 위해서 game sprite들에 좀 더 효율적인 transition을 사용하기로 했습니다. TimeSpaceMagic 같은 library들을 찾을 수 있었는데요. pause 와 time-warping 관련한 겁니다. 이 라이브러리들은 모두 transition property들인 at Runtime을 calculate 하는데요 작업하는데 꽤 힘든 일 입니다. transition이 항상 같다면 이런 작업은 필요 없겠죠.


그래서 저는 AK-Tween 을 만들었습니다. predetermining transitions 과 그것들을 at Runtime 에 manually 적용하는 겁니다. 다른 것들을 벤치마크해서 다른 Runtime transition 접근법보다 (제가 찾은 가장 efficient 한 방법보다도) 20% 정도 빠르게 동작하도록 만들었습니다. 이 라리브러리의 alpha 버전은 AS3의 GTween을 바탕으로 해서 쉽게 만들 수 있었습니다.  그러니까 이 라이브러리는 그 결과가 코로나의 transition easing 과 비교해도 비슷할 만큼 쉽게 만들었습니다. (아래 iPhone4 테스트 결과를 보세요.)


The Core Idea


“AK-Tween”  의 계산(calculates) 는 table이나 배열에 저장된 값들에 의해 load time (Runtime이 아닌)에 일어납니다. 그리고 그 값들이 필요하면 custom Runtime function을 사용해서 iterate 합니다. 아래에 배열값을 return 하는 tween calculation code 의 일 부분이 있습니다. 한 눈에 보시고 이해하실 수 있도록 간략하게 만들었습니다.


--AKtween.lua
local function tweenCalc( config, anim )

  local time = config.time or 1000
  local ease = config.ease
  local totFrames = 0.06 * time --frames at 60FPS

  local step = 1/totFrames

  if ( ease == "outQuad" ) then

    for i=1,totFrames do
      pos = pos + step
      local index = i +startArr
      local ratio = -pos * (pos-2) arr[index] = from + (ratio * delta)
    end

  elseif ( tween == "inQuad" ) then
    ...

  end

  return arr
end



아래는 이 tween 을 실제로 set up 하는 부분입니다. (예제로 공이 튕기는 것을 구현하겠습니다.)


--CREATE TWEEN FOR BALL BOUNCE
local AKtween = require( "AKtween" )

local ball = display.newImage( "ball.png" )

local bounceTween = AKtween:newTween( {time=400, y=-120, ease="outQuad"} )
--bounceTween.yArr = [-4.79, -4.58, -4.37, -4.16, -3.95 ...
-0.83, -0.625, -0.416, -0.20, 0]
--#bounceTween.yArr = 24

bounceTween:append( {time=400, y=0, "inQuad"} )
--bounceTween.yArr = [-4.79, -4.58, -4.37, ...
-0.416, -0.20, 0, 0.20, 0.416 ... 4.37, 4.58, 4.79]
--#bounceTween.yArr = 48

ball.yBounceArr = bounceTween.yArr --JUST GET THE Y-VALUES,
--bounceTween:apply( ball, "bounce" )
--OR ALLOW AKTWEEN TO HANDLE THE WHOLE ANIMATION
 

이렇게 하면 y=0 to y=-120 까지 볼이 튀어 올라가고 다시 내려올 겁니다. 그 움직임은 quadratic ease를 사용해서 자연스러울 거구요.  시간은 400ms 가 걸릴겁니다. (24 frames at 60 fps). 우리가 한 일은 마지막 줄에 :apply() function을 call 한 것입니다. 그리고 이 tween을 AKtween 에 의해 제대로 컨트롤 되게 하기 위해 ball:playTween(“bounce”)를 사용했습니다. 이것과 똑 같은 일을 할건데요. 라이브러리에서 생성된 y-value array만 사용해 보겠습니다.

그러니까 ball.yBounceArrpredetermined y-values가 저장돼 있는 거죠. Runtime ball:bounce() script를 set up 하기만 하면 됩니다.


function ball:bounce()
local yVals = self.yBounceArr
  local totFrames = #yVals
  local curFrame = 1

  --RUNTIME SCRIPT, OCCURS ON EVERY FRAME
  local function frameCount()
    if ( curFrame <= totFrames ) then
      self:translate( 0, yVals[curFrame] )
      curFrame = curFrame+1
    else
      curFrame = 1
    end
  end

  --SAVE REFERENCE TO RUNTIME FUNCTION, AND BEGIN
  self.bounceFC = frameCount
  Runtime:addEventListener( "enterFrame", frameCount )

end


 


불이 튕기기를 원하면 언제든지 ball:bounce()를 call 합니다. 그러면 frameCount라고
하는 local Runtime script 를 setup 합니다. 이는 frameCount는 각 프레임마다 공에
새로운 y의 위치값을 세팅할 겁니다.

이 reference는 또한 ball.bounceFC에도 저장돼 있습니다. 이 ball.bounceFC
튕기는 것을 pause, resume, or stop할 수 있게 합니다.


function ball:pause()

  if ( self.bounceFC ) then
    Runtime:removeEventListener( "enterFrame", self.bounceFC )
  end
end

function ball:resume()
  if ( self.bounceFC ) then
    Runtime:addEventListener( "enterFrame", self.bounceFC )
  end
end

function ball:stop()
  if ( self.bounceFC ) then
    Runtime:removeEventListener( "enterFrame", self.bounceFC )
    self.bounceFC = nil
  end
end

manual way 는 regular transition 보다 implement 하는데 더 어렵습니다. 하지만
자신만의 animation property들을 사용해서 원하는 결과를 정확히 만들어 낼 수
있는 장점이 있죠.

performance 측면에서도 아주 효율적입니다. 또한 pause-enabled 하구요.
저의 dynamic sprites implementation과 같이 사용하면 게임이 아주 자연스럽게 움직일
겁니다.


Benchmark Results



아래가 이 메소드를 사용한 후의 benchmark result 입니다.
두 매뉴얼과 AKtween play function 들은 아래와 같이 주목할 만한 결과를 보여 줍니다.


요약하자면 우리는 우리의 object들을 transitioning 하기 위해
underlying alternate method를 정의했습니다.
이러한 benchmark는 이 메소드가 아주 효율적이라는 것을 증명했구요.
우리는 그냥 단순히 배열에서 값을 읽어서 이것을 해당 object property 에 적용하는
일만 합니다.

이러한 작업은 AKtween juggler에 object를 pass 함으로서 그 기능을 사용하게 됩니다.
혹은 local runtime script를 추가하거나 제거함으로서 애니메이션을 전체적으로 control
할 수 있습니다.

두 방법 모두 AKtween을 사용하시면 됩니다. 이것이 여러분 앱 개발에 도움이 될 수
있는지 잘 확인해 보세요.




반응형

Comment