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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Posted on . Written by


오늘의 튜토리얼은 코로나의 physics contact에 대해 소개해 드리려고 합니다. 이 기능은 physics engine 에 최근에 implement 됐습니다. 개략적으로 말하자면 physics contact 는 막 일어나려는 특정 collision (충돌) 을 말하는 겁니다.

개발자들에겐 아마도 physics pre-collision이 친숙할텐데요. 아마도 이 physics contact 하고 뭐가 다른지 의문이 드실 겁니다. physics contact 는 대부분의 경우 pre-collision event 중에 사용됩니다. 그럼에도 이 두가지는 중요한 차이점이 있습니다.



Pre-collision Event


두 object 사이의 pre-collision (or any collision) 이 일어날 경우 Corona는 Lua ID에 의해 각각의 object 에 접근할 수 있도록 합니다. 이 방법을 통해 어떤 object (객체) 에 어떤 action 을 구현할 수 있을 겁니다. 예를 들어 dl pre-collision에서 한 object 를 센서로 바꿔서 다른 object 가 이 object를 통과할 수 있도록 만들 수도 있구요 아니면 둘 중 하나는 터지도록 만들 수도 있을 겁니다.  또는 여기에 force를 더 줄 수도 있고 혹은 다른 많은 action 들을 부여할 수 있습니다. 이 기능은 Corona 에서 오래 전부터 제공해 왔죠. 그런데 여기에는 몇가지 제한이 있었습니다. 그리고 physics contact로 그 제한을 해결할 수 있게 됐습니다.



One-Sided Platforms


2D side-view games 에서 자주 요구되어지는 것 중 하나가 “one-sided platform” 입니다. (수퍼 마리오를 비롯해 다른 수 많은 2D platform games 에서 이 기능이 사용되고 있습니다.) character 가 platform 아래에서 점프를 할 수 있고 이 platform 을 통과 할 수도 있죠. 그리고 그 platform 위에 사뿐히 착지하게 됩니다. 코로나에서는 이전에 점프할 때 character를 sensor 로 바꿔서 해결했습니다. 그리고 그 platform 위에서 character 는 다시 일반적인 object로 전환 됐죠.

대부분의 경우 이 방법으로 해결이 가능했습니다. 그런데 한가지 중요한 문제점이 있었죠. 만약에 enemy “goomba” 가 platform 위에서 걸어가고 있는 경우에는 어떻게 될까요? 이 character 가 그 enemy “goomba” 하고 부딪힐 때도 여전히 sensor 인 상태가 되죠. 그러다가 platform 위로 올라가게 되는 순간 두 object 의 충돌이 인식되서 “bounce” 가 일어나지 않는 등의 문제가 생길 수 있습니다.






Introducing the Physics Contact


위 문제는 새로 도입된 physics contact로 해결 할 수 있습니다. 위에서 언급한대로 특정 reference 에 대해 막 일어나려고 하는 충돌의 경우 알 수가 있습니다. pre-collision event listener 가 사용되고 있는 사이에 physics contact 와 4개의 properties에 접근할 수 있습니다. 이전에는 ㅇ접근할 수 없었던 것이죠.

one-sided platform 예제를 한번 더 생각해 볼까요. character 가 점프하고 아래쪽에서 platform 에 충돌 했을 때 코로나는 character 의 머리와 platform의 밑부분이 충돌하려고 한다는 것을 알 수가 있습니다. physics contact를 사용해서 곧 일어날 temporary access를 알아채서 코로나에게 여러분이 하고 싶은 일을 하라고 얘기할 수 있습니다. 혹은 이것을 완전히 무시하라고 얘기할 수도 있죠.


아래에 pre-collision event listener를 사용해서 어떻게 physics contact에 어떻게 접근하는지에 대한 예제가 있습니다.


function character:preCollision( event )
   print( event.contact ) --"event.contact" is the physics contact "userdata"
   --the following properties of the collision can be accessed; the last three are settable!
   print( event.contact.isTouching ) --read-only: are the two objects touching?
   print( event.contact.isEnabled ) --'true' or 'false'; will the collision resolve?
   print( event.contact.bounce ) --get/set the bounce factor of the collision
   print( event.contact.friction ) --get/set the friction factor of the collision

end
character:addEventListener( "preCollision" )


physics contact 는 collision-specific properties 를 제공합니다. (이전에 traditional listener events 에서는 접근할 수 없었던 것들이죠.)  간단한 condition 로직을 사용하셔서 (if문 같은) 해당 충돌을 완전 무시하거나 선택할 수 있습니다. 혹은 특정 충돌에 대해 bounce/friction factor(s)등에 변화를 줄 수 있죠. 해당 객체에 적용한 bounce/friction  을 override 하시면 됩니다.


one-sided platform 을 위해서는 physics contact 메소드를 사용하는 것이 훨씬 좋습니다. 처음에 플랫폼의 프로퍼티를 “pass through” (or any other term)로 설정하고 그 다음에 conditional logic (if 문 같은)을 사용해서 코로나에게 만약 그 플랫폼이 “passthru” type 이면 해당 충돌을 무시하라고 얘기하실 수 있습니다. 아래 예제에서 처럼요.


local platform = display.newImage( "platform.png" )
platform.collType = "passthru"
physics.addBody( platform, "static", { bounce=0.0, friction=0.3 } )

function character:preCollision( event )

   local collideObject = event.other
   if ( collideObject.collType == "passthru" ) then
      event.contact.isEnabled = false --disable this specific collision!
   end
end

 

physics contact 충돌하는 두 객체의 reference 는 아닙니다. 다만 충돌 그 자체의 reference 입니다.그 충돌을 다시 적용시키기 위해 override 하실 수 있습니다. physics contact properties 를 세팅하면 두 객체 모두에 이 프로퍼티가 계속 적용되는 것이 아닙니다. 코로나는 그 특정 충돌에 대해서만 해당 프로퍼티를 사용할 겁니다.  그리고 나서는 그 프로퍼티를 무시합니다. 예를 들어 physics contact 의 “bounce” factor 를 바꾼다면 두 객체의 core bounce 에 대해서는 set/reset을 하지 않습니다.


코로나에서 physics contact (and its properties)는 어떤 타입의 충돌 리스너에서든지 가리지 않고 사용할 수 있습니다.(pre-, post-, or standard). 대부분의 경우 pre-collision를 많이 사용하죠. 왜냐하면 프로퍼티에 접근하고 세팅하고 하는 작업은 그 충돌이 일어나기 전에 필요한 거니까요.




Other Possibilities


physics contact 를 사용해야 하는  one-sided platform 이외의 경우를 한번 볼까요. 핀볼 게임 아시죠? 이 게임을 위해서 아래와 같은 conditional logic(if문 등)을 사용하실 수 있을 겁니다.


  • Silver balls collide with red bumper for extreme bounce (set physics contact bounce to 1)
  • Silver balls collide with blue bumper for no bounce (set physics contact bounce to 0)
  • Gold balls collide with red bumper for no bounce (opposite of the first case)
  • Gold balls collide with blue bumper for medium bounce



See it in Action


“one-sided platform” method를 사용하신 경우롤 보시려면 demo project를 다운 받아서 참조하세요.






In Summary…


새로만든 physics contact는 네가지 새로운 프로퍼티들을 제공합니다.


  • event.contact.isTouching — read only: are the two objects touching?
  • event.contact.isEnabled — read/write: ‘true’ or ‘false’; should the collision resolve?
  • event.contact.bounce — read/write: get or set the bounce factor of the collision
  • event.contact.friction — read/write: get or set the friction factor of the collision


특정 상황에서 이 프로퍼티들은 기본적인 충돌 이벤트와 충돌 필터들을 사용해서 이전에는 구현할 수 없었던 정교한 콘트롤을 할 수 있도록 해 줍니다. 이 프로퍼티들을 다음 physics-based project에서 사용해 보세요.


질문이나 의견이 있으시면 저 위 본문 시작하는 제목에 걸린 링크를 클릭하세요.

원문페이지기 있는데요. 거기다가 댓글로 질문 하시면 됩니다.


영어로 하셔야 되는데요.


영어가 어려우시면 이 글 밑에 댓글로 달아 주세요.

제가 여건이 되는대로 대신 질문 전달하고 답변 받으면 이 블로그에 공유해 드릴께요.



반응형