지난번에 이어 animation chain 소스를 분석해 보겠습니다.
지난번 글을 올린지 1주일이 지났나보네요.
지난번 main.lua 에서는 화면에 나오는 빨간 공 4개와 흰공 한개를 배치하는 로직이었습니다.
animationchain.lua 에서는 이 흰공을 4개의 빨간공을 따라서 움직이게 하는 코드가 있을 겁니다.
main.lua 의 마지막 줄에 이 작업을 하기 위해 animationchain.lua 에 있는 함수를 이렇게 call 했습니다.
animationchain.anim(c,stops[1]).whenDone(c,stops[2]).whenDone(c,stops[3]).whenStart(c,stops[4]).onComplete(c,stops[5]).onStart(function() print("done") end).start()
c 가 바로 흰공이었고 stops 에는 빨간공들의 위치값들이 있습니다.
animationchain.lua 의 소스는 아래와 같습니다.
local M={}
animationchain=M
local transition=transition
local setmetatable=setmetatable
local type=type
local error=error
setfenv(1,M)
local function start(anim,options,onStart,onComplete)
return function()
if options.delete then
options.onComplete=function(obj)
obj:removeSelf()
if onComplete then
onComplete()
end
end
else
options.onComplete=onComplete
end
anim()
if onStart then
onStart()
end
end
end
-- args
-- exec - is the current function to execute. It is assumed to be a function that runs a Corona SDK transition
-- options - options for the animation (see Corona SDK). These are assumed to be the same closed over by the exec call - chainFunctions relies on being able to manipulate them for "onComplete" and "whenDone" to work
-- # Additional feature: if options.delete==true the subject of the animation will be deleted (obj:removeSelf() called) when the animation completes
-- runParent (optional) - run the previous function in the chain. It takes a single function as an argument. chainFunction creates this function itself
-- noanim (optional) - true if exec does not represent a function executing a Corona SDK transition. If true, the only valid call to the chain is "start"
function chainFunctions(exec,options,runParent,noanim)
local t={}
local mt={
__index=function(t,k)
local run=function(execChildAnim)
local doIt
-- wrap child animation in relation to previous call
local onStart,onComplete
if k=="onStart" or k=="whenStart" then
onStart=execChildAnim
elseif k=="onComplete" or k=="whenDone" then
onComplete=execChildAnim
end
doIt=start(exec,options,onStart,onComplete)
if runParent then
runParent(doIt)
else
doIt()
end
end
return function(...)
if k=="start" then
return run()
end
if noanim then
error("animationchain: passing in pure functions must terminate the chain. Only call start after passing a single function into the chain")
end
if #arg==1 and type(arg[1])=="function" then
-- just a function has been passed in.
return chainFunctions(arg[1],{},run,true)
end
return anim(arg[1],arg[2],run)
end
end
}
setmetatable(t,mt)
return t
end
function anim(obj,options,runParent)
return chainFunctions(function () return transition.to(obj,options) end, options,runParent)
end
return M
여기서 어느 부분이 제일 먼저 실행 될까요?
이 파일에는 크게 세개의 함수가 있습니다. 맨 처음에 start() 함수가 있구요. 두번째에 chainFunctions() 그리고 세번째로 anim() 함수가 있습니다.
start 함수가 맨 처음에 있고 이름도 start 이니까 이게 제일 먼저 실행 될까요?
아닙니다. 사실은 start() 함수는 이 세개중에 제일 나중에 실행 됩니다.
함수는 running time 중에 누군가가 call 해 주지 않으면 실행되지 않습니다.
마치 옛날 왕의 여자들처럼 나라를 run 하시는 왕이 call 하지 않으면 평생 독수공방해야 되듯이요.
제일 처음 실행되는 함수는 anim() 입니다. 왜냐하면 main.lua 의 맨 마지막 단계에서 이 함수를 call 했기 때문이죠.
이 anim() 함수는 무슨 행동을 할까요?
chainFunctions() 함수를 return 합니다. 즉 chainFunctions() 함수가 실행 되는 거죠.
여기서 파라미터로 function () return transition.to(obj,options) end 와 options, 그리고 runParent가 pass 됩니다.
이 파라미터들이 어디서 온건지 알아볼까요?
그냥 설명하면 길어질 것 같아서 위와 같이 정리해 봤습니다.
c 는 흰공이고 stops[1] 은 빨간공의 좌표 입니다.
빨간공은 따로 파라미터로 넘겨 주지 않습니다. 왜냐하면 흰공만 움직일 거니까요. chainFunctions() 에서 필요한건 빨간공의 좌표값뿐입니다.
우선 main.lua 에서 이 c(흰공) 과 stop[1] 첫번째 빨간공의 좌표를 넘겨 줍니다.
이걸 animationchain.lua 의 anim(obj,options,runParent) 함수가 받죠.
여기서 obj 는 첫번째 파라미터로서 흰공 c를 말하고 options는 빨간공의 좌표 입니다. 그리고 세번째 좌표 runParent는 main.lua 에서 전달하지는 않았습니다.
이건 나중에 살펴 보겠습니다.
anim() 함수 안에서는 chainFunctions()를 콜하면서 3개의 파라미터를 전달하죠?
그런데 첫번째 파라미터는 함수를 전달해 줍니다.
transition.to(obj,options) 라는 함수 입니다.
이 transition.to()함수는 corona sdk 에서 제공되는 함수인데 애니메이션 표현할 때 아주 많이 사용합니다.
transition() 함수 API 를 보시려면 여기로 가셔서 참고하세요.
이 transition.to(obj.options)를 해석하자면 obj를 options 까지 움직인다는 의미 입니다. 즉 흰공을 stops[1] 까지 움직이는 거죠.
한번 소스 코드를 바꿔볼까요?
main.lua 에서
animationchain.anim(c,stops[1]).whenDone(c,stops[2]).whenDone(c,stops[3]).whenStart(c,stops[4]).onComplete(c,stops[5]).onStart(function() print("done") end).start()를 없애시고 animationchain.anim(c.stops[1])을 넣어 보세요.
그리고 animationchain.lau 의 anim() 함수 안에
return chainFunctions(function () return transition.to(obj,options) end, options,runParent) 를 없애시고
transition.to(obj.options)를 넣어 보세요.
그러면 흰공이 가운데에서 왼쪽 빨간 점으로 움직일 겁니다.
main.lua 에서 animationchain.anim(c.stops[2]) 를 넣어 보세요.
그러면 흰공이 곧바로 왼쪽 위에 있는 빨간공으로 움직이죠?
이렇게 해 보시면 transition.to() 함수의 기능을 확실히 아실 수 있을 겁니다.
일단 오늘은 animationchain.lua 파일에 있는 3가지 함수 중에 main.lua 에서 call 되서 가장 먼저 실행되는 anim(obj.options,runParent) 함수에 대해서 분석해 봤습니다.
이제 이 anim() 함수 안에서 chainFunctions()를 호출 하는 것을 확인 했습니다.
이때 3개의 파라미터가 전달 되는데 첫번째 파라미터는 흰공이 2번 빨간 공까지 transition 한다는 함수이고 두번째 파라미터는 options로서 이건 main.lua에서 부터 전달 된 빨간 공의 좌표 입니다.
runParent는 아직 정체를 알 수는 없습니다.
아마 이 소스의 핵심 부분인 chainFunctions()를 분석하면 알 수 있을 겁니다.
오늘은 여기까지만 하고요.
다음에 chainFunctions()를 분석해 보겠습니다.
'Corona SDK > 샘플 코드 분석' 카테고리의 다른 글
animation chain 소스 분석 해 보기 03 (0) | 2013.08.11 |
---|---|
animation chain 소스 분석 해 보기 01 (0) | 2013.07.15 |
코로나로 뱀 기어디니는 효과 내기 (0) | 2012.02.28 |
간단하게 눈발 흩날리는 느낌 주기 (2) | 2012.02.16 |
돈 넣고 돈 먹기(야바위) 모바일 게임 만들기 2 (11) | 2012.01.04 |
돈 넣고 돈 먹기(야바위) 모바일 게임 만들기 1 (2) | 2012.01.03 |
내가 그린 선으로 떨어지는 공 받아내기 (2) | 2011.12.31 |
Corona SDK 화면전환 API (Story Board) (4) | 2011.12.23 |
Level 별 Lock 기능 걸고 푸는 법 (0) | 2011.12.15 |
벽돌 깨기 게임 만들기 -3 (1) | 2011.12.01 |