2015년 10월 31일 토요일

corona sdk 에서 level director 이용 Animation 동적 생성 충돌


지난번에 작업하던것을 이어서, Animation 관련해서 궁금한 점들을 실험해보도록 하겠습니다.

Animation 동적 생성하기

앞의 예제에서는 asset 에서 canvas에 bird를 끌어다 놓았습니다.
게임을 만들다 보면 총알이라던가 적 캐릭터, 폭발 장면등의 경우 그때 그때마다 생성했다가 금방 사라져야 하는 경우 map editor의 고정 위치에 두고 작업을 할 수가 없습니다.
그래서 동적으로 생성해야 하는데요.

Level Director (이하:LD )에서 Assets에있는 object는 언어에서의 intance라고 이해하면 됩니다. 그걸 끌어다가 canvas에 올려놓으면 object가 되는거고요.

그럼 동적으로 만든다는 말은 assets상태로만 존재하는걸 runtime시 생성되게 하는겁니다.

그럼 일정 시간마다 생성되게 하려면 특정 이벤트에 등록해야 할 겁니다.
아래와 같이 할 수 있습니다.

-------------------------------------------------
--function to position new ball and update scores
-------------------------------------------------
local function spawnObject()

 local objProps = 
 {
  name  = "bird_dy", 
  x  = math.random(20,300),
  y  = 0,
  xScale  =  1,
  yScale  =  1,
  assetName = "bird_png_1",
 }
 
 -- set the graphics 
 local bird_d = myLevel:createObject("New Layer", objProps).view
 
 bird_d:setSequence("Sequence0")
 bird_d:play()

 transition.moveTo( bird_d, { x=200, y=200, time=8000 } )

end

-------------------------------------
local function update(event)
-------------------------------------
 local tDelta = event.time - tPrevious
 tPrevious = event.time
 deltaSum = deltaSum + tDelta;
 if (deltaSum > 5000 ) then
  deltaSum = 0
  spawnObject()
 end

end

-- add frame handler
Runtime:addEventListener( "enterFrame", update )


주기적으로 생성된 bird가 200,200으로 날아오는 모습을 볼 수 있습니다.
여기서 assetName은 LD에 있는 asset 이름을 적어주면 되고 name부분은 충돌시 사용하면 도움이 됩니다.





충돌 검사하기


corona sdk에서 충돌 방식 그대로 사용가능하고 canvas에 올려놓으면 올려놓는 object에 직접 속성을 수정하는것에 대해서만 동작을 합니다.

아래 전체 코드를 공개합니다.



physics = require ("physics")
physics.start()

local LD = require("lib.LD_LoaderG2") -- G2 is for Corona Graphic2.0, remove for Graphics1.0
local myLevel = {}
myLevel=LD:loadLevel("level01")  -- Level01 will be the name of your exported level file

local yobj = myLevel:getLayerObject("New Layer","y").view
local bird = myLevel:getLayerObject("New Layer","bird").view
local tPrevious = system.getTimer()
local deltaSum = 0

-------------------------------------------------
--function to position new ball and update scores
-------------------------------------------------
local function spawnObject()

 local objProps = 
 {
  name  = "bird_dy", 
  x  = math.random(20,300),
  y  = 0,
  xScale  =  1,
  yScale  =  1,
  assetName = "bird_png_1",
 }
 
 -- set the graphics 
 local bird_d = myLevel:createObject("New Layer", objProps).view
 
 bird_d:setSequence("Sequence0")
 bird_d:play()

 transition.moveTo( bird_d, { x=yobj.x, y=yobj.y, time=8000 } )

end

-------------------------------------
local function update(event)
-------------------------------------
 local tDelta = event.time - tPrevious
 tPrevious = event.time
 deltaSum = deltaSum + tDelta;
 if (deltaSum > 5000 ) then
  deltaSum = 0
  spawnObject()
 end

end

-- poop collision handler
local function onGlobalCollision( event )
  if event.phase == "began" then
    local obj1 = event.object1; 
    local obj2 = event.object2; 
 print (obj1.name)
 print (obj2.name)
 if ( obj1.name == "bird_dy" and obj2.name == "y" ) or 
    ( obj1.name == "y" and obj2.name == "bird_dy" )  then
    if( obj1.name == "y" ) then 
      display.remove(obj2)
   obj2 = nil
    else 
   display.remove(obj1)
   obj1 = nil
    end
 end
  end
end



bird:setSequence("Sequence0")
bird:play()


yobj:setSequence("Sequence0")
yobj:play()

-- add frame handler
Runtime:addEventListener( "enterFrame", update )
Runtime:addEventListener( "collision", onGlobalCollision )


위 소스에서 동적 object삭제시 아래와 같이 LD api를 이용하여 삭제 하여야 합니다.
display.remove(obj2)  -> myLevel:removeLayerObject("New Layer", obj2.name)
display.remove(obj1)  -> myLevel:removeLayerObject("New Layer", obj1.name)

y라는 이미지를 만들었습니다. 회전시 각기 다른 충돌 영역을 설정할 수 있는지 테스트 하기 위해서 만들었습니다.
결과는 canvas에 끌어다 놓는 시점의 asset의 초기값을 기반으로 우측 상단에 있는 layer에 표시되는 object의 속성값을 가지고 사용하게 됩니다. 또한 애니메이션시 각각의 frame에 있는 충돌정보를 이용하지 않고 끌어다 놓은 시점의 frame만의 충돌 정보를 이용하게 됩니다.


충돌 검사를 하려면 physics enable이 true가 되어야 하고 body type이 dynamic과 static이 되도록 해줍니다. 자세한 사항은 corona sdk 문서를 참고하면 됩니다.
body type이 static끼리는 충돌 검사가 되지 않습니다.
여기에서 y는 static으로 설정하였고 bird는 dynamic으로 설정하였습니다.
충돌시 dynamic이 튕겨나가지 않으려면 IsSensor 항목을 true로 설정해줍니다. 이것도 corona sdk에 있는 내용입니다.





우측 img_20 의 이름을 y로 변경해주고, y가 animation이 되게하려면 asset에서 y_png_1의 속성중에 animation정보를 변경해주도록 합니다.

그러면 회전 하는 y에 bird이 날아들면서 충돌된 bird는 사라지는 예제입니다.
아래는 실행 화면입니다.







댓글 없음:

댓글 쓰기