개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
오늘의 튜토리얼은 코로나의 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에 어떻게 접근하는지에 대한 예제가 있습니다.
functioncharacter: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 이면 해당 충돌을 무시하라고 얘기하실 수 있습니다. 아래 예제에서 처럼요.
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