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

최근에 받은 트랙백

글 보관함


Posted on . Written by




Wind Tunnel / Vents


Runtime 이벤트에서 Physics sensor와 :applyForce() function 을 사용하게 되면 wind tunnel 지역이나 객체들을 날려버리는 통풍구들을 만들기가 쉽습니다. 이 작업을 하기 위해 통풍구(vent)들과 각 객체들에 모두 두가지 프로퍼티들을 할당할 겁니다. 이 프로퍼티들을 xFyF로 명명하겠습니다. 객체들과 관련된 xy 의 force를 나타낼 겁니다.

실제 vent들은 사각형의 센서들이 될 겁니다. 이 센서들은 원하는 각도로 rotate 될거구요. 이 각도에 맞게 바람이 뿜어져 나와서 객체들을 위로 보내서 땅에 떨어지지 않도록 할 겁니다. 이 예제에서 떠 다니는 물체들은 나뭇잎들로 할겁니다.


각각의 잎들도 Runtime 이벤트 동안 적용될 force 를 나타내는 xFyF force 프로퍼티를 갖고 있습니다. 이 값들은 이 나뭇잎이 vent 지역을 들어오고 나갈때마다 새로 계산될 겁니다. 그리고 vector force 값들이 두개 이상의 통풍구 바람이 다른 방향으로 영향을 미칠 때 적용될 요소가 될 겁니다. 여러분이 원하신다면 휘어진 통풍구도 만들 수 있습니다.



Configuring Vents


vent 는 여느 physics body와 마찬가지로 셋업 하시면 됩니다. 센서로 세팅할 것이고 isVent 프로퍼티도 넣어서 collision handler 에서 다른 객체들이 vent로 처리되지 않도록 할 겁니다. 네번째 줄에서는 xFyF 값을 얻게 됩니다. 여기서 getVentVals() 함수는 바로 다음에서 다루게 될 겁니다.


local vent1 = display.newRect( 0, 0, 80, 300 )
physics.addBody(vent1, "kinematic", { isSensor=true } )
vent1.isVent = true ; vent1.rotation = 14 ; vent1.x = 432 ; vent1.y = 660
vent1.xF, vent1.yF = getVentVals( vent1.rotation, 160 )



Retrieve Vent Force Values


아래 함수는 두개의 파라미터를 전달 받습니다. vent의 각도와 power 입니다. 이 값들로 계산해서 xFyF force 값을 리턴하게 되죠. 이 값들이 떠다니는 객체들이 영역으로 들어왔을 때 불어 올리는 동작을 할 수 있도록 해 줍니다.


function getVentVals( angle, power )
   local xF = math.cos( (angle-90)*(math.pi/180) ) * power
   local yF = math.sin( (angle-90)*(math.pi/180) ) * power
   return xF,yF
end



Vent Collision Handler


collision handler 는 collision의 beganended phases 에 어떤 처리를 하게 됩니다. began phase에서는 vent의 xFyF 요소들을 떠다니는 객체들의 해당 프로퍼티 값에 더해 주게 됩니다. 그리고 ended phase에서는 그 값을 빼주게 되죠.

예를 들어 한 vent에는 xFyF 값이 02 이고 위로 불어 올리고 있고  다른 vent는 이보다 약간 더 센 power를 가지고 아래로 내리고 있다고 칩시다. (0하고 3.5 정도). 이 두 vent의 영향을 한꺼번에 받는다면 떠다니는 객체는 1.5(-2+3.5)만큼 아래로 가게 되겠죠. 


function ventCollide( self,event )

   local vent = event.other
   if ( event.phase == "began" and vent.isVent == true ) then
      self.xF = self.xF+vent.xF ; self.yF = self.yF+vent.yF
   elseif ( event.phase == "ended" and vent.isVent == true ) then
      self.xF = self.xF-vent.xF ; self.yF = self.yF-vent.yF
   end
end
leaf1.collision = ventCollide ; leaf1:addEventListener( "collision", leaf1 )



Runtime Force Application


마지막으로 각 나뭇잎들에 실제 force를 적용할 필요가 있습니다. 이 작업은 Runtime event 동안에 하게 됩니다. (이 force value들은 계속 누적 될 겁니다.) 그러면 나뭇잎이 오래 떠 다닐수록 더 큰 force 가 적용된다는 얘기가 되겠죠.

실제 함수는 아주 간단합니다. 특정 잎의 xFyF 값이 0이 아니면 특정 force가 게임 중에 적용이 되게 됩니다.


function constantForce()
   if not ( leaf1.xF == 0 and leaf1.yF == 0 ) then
      leaf1:applyForce( leaf1.xF, leaf1.yF, leaf1.x, leaf1.y )
   end
end

Runtime:addEventListener( "enterFrame", constantForce )



눈치 빠르신 분들은 알아차리셨겠죠? 객체가 통풍구에서 멀어질 수록 적은 영향을 받게 됩니다. 이 값이 true 일 경우에 객체들은 vent 의 범위 안에 있는 것이고 그러면 그 force 의 영향을 받게 됩니다.

windtunnel.zip


여기까지가 기본 사항입니다. 예제에 있는 여러 값들을 바꿔가면서 테스트 해 보세요.


In Summary…


세 가지 예제를 모두 보시려면 여기 sample projects 에서 다운 받아서 보세요. 그리고 궁금하신 점이나 의견이 있으시면 댓글에 남겨 주세요.

반응형

Comment