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

최근에 받은 트랙백

글 보관함

Corona SDK Physics API

2011. 9. 22. 07:30 | Posted by 솔웅


코로나의 Physics 엔진은 아주 강력합니다.
제가 경험했던 그 어떤 언어보다 강력한거 같아요.

개발자들은 아주 간단한 코딩으로 Physics 구현을 할 수 있거든요.
그리고 나중에 다루게 되겠지만 이것이 MultiTouch 기능이랑 합해지면 아주 다양하면서도 새로운 모바일 앱을 가능하게 해 줍니다.

이번에 제가 개발한 Multi Player Ping Pong 도 최대 4인용까지 사용할 수 있는데 4명이 동시에 이벤트를 발생해도 그것들을 다 처리해 줍니다.

이제 본격적으로 Physics 엔진 사용법을 살펴 봅니다.

local physics = require("physics")

이 physics 엔진을 사용하기 위해서는 처음에 위와 같이 선언합니다.
로컬변수 physics 를 사용해서 코로나의 physics 엔진을 사용하겠다는 의미입니다.

이 physics 엔진을 시작하고 멈추고 일시 정시 시키는 함수가있는데요.
아래와 같이 사용합니다.
physics.start()
physics.pause()
physics.stop()

그리고 아래와 body 에도 이를 적용할지 안할지를 아래 함수를 통해 제어할 수 있습니다.
(body 에 대해서는 조금 있다가 다룰 겁니다.)

physics.start(true)-- prevent all bodies from sleeping
physics.start(false) -- default behavior; bodies may sleep

중력(gravity)에 대해서도 선언할 수 있습니다.
기본적으로 중력값은 9.8 입니다. 그래서 코로나의 디폴트 중력값은 9.8입니다.)
physics.setGravity( 0, 9.8 )
지난 시간에 다뤘던 ManyCrates 의 main.lua 파일 안에 이 부분을 한번 적용해 보세요.
physics.start() 다음에 추가해 보세요.
physics.setGravity( 0, 3 ) 하면 달이나 뭐 그런데 처럼 박스들이 천천히 떨어지구요.
physics.setGravity( 0, 30) 정도로 하면 아주 무겁게 떨어집니다.

괄호 안의 숫자는 x,y 좌표를 나타냅니다.
앞의 0의 숫자를 고치면 왼쪽에서 오른쪽으로 중력이 작용합니다. (테스트 해 보세요.)

이 중력값 (gravity) 을 get 할 수도 있는데요.
gx,gy = physics.getGravity() 하면 gx에는 첫번째 인수값이 gy 에는 두번째 인수값이 들어갑니다.

다음은 Accelerometer (가속도) 에 대해 볼 건데요.

지난번 코드에 아래와 같이 추가해 보세요.
_W = display.contentWidth;
_H = display.contentHeight;

위 두개는 display.setStatusBar( display.HiddenStatusBar ) 밑에다 놓으세요.
그리고 맨 마지막에 아래와 같이 코딩 해 주세요.
(local dropCrates = timer.performWithDelay( 500, newCrate, 100 ) -> 이 코드 밑에요.)

local function onTilt( event )
        physics.setGravity( 10 * event.xGravity, -10 * event.yGravity )
        gx, gy = physics.getGravity()
        print("x Gravity = " .. gx .. " y Gravity = " .. gy)
        gravityx.text = gx;
        gravityy.text = gy;
end
 
Runtime:addEventListener( "accelerometer", onTilt )

이 accelerometer 기능은 핸드폰을 기울이면 그 기울이는 쪽으로 중력이 적용 되는 거예요.
그래서 시뮬레이터에서는 테스트 할 수 없구요. 디비이스에 인스톨 한 다음에 사용 가능해요.

빌드 하신 후 디바이스에 인스톨 하세요.
그리고 앱을 실행하시면 원래처럼 아래에서 위로 떨어질 거예요.
그리고 핸폰을 좌,우,상,하 바꾸면서 기울이시면 그에 따라서 박스들 떨어지는 방향이 바뀔거예요.

가운데 중력 값이 텍스트로 표시 되게 했으니 참고 하시구요.

이런 강력한 기능을 이렇게 간단하게 구현할 수 있다니 코로나 정말 매력적이예요.

코로나는 기본적으로 30픽셀을 1미터로 계산 합니다.
이 기능을 이용해서도 게임에 아주 재밌는 기능 구현을 할 수 있을 것 같은데요.
이 세팅값을 바꾸려면 아래 함수를 사용합니다.
physics.setScale(60)
이러면 60픽셀당 1미터로 계산 하겠죠?
이것은 코로나의 기준이고 아이폰이나 안드로이드 폰 그리고 해상도가 다름에 따라 주의를 기울여야 한다고 합니다.
자세한 내용을 보려면 Corona API Reference 의 autoscaling content for multiple screens 를 보라고 하네요.

자세한 내용은 저도 나중에 봐야겠습니다.

physics 엔진을 사용하면서 테스트 하거나 디버깅 할 때 setDrawMode 함수를 이용하면 편합니다.
이 함수에는 다음과 같이 세가지 옵션이 있습니다.

physics.setDrawMode( "debug" ) -- shows collision engine outlines only
physics.setDrawMode( "hybrid" ) -- overlays collision outlines on normal Corona objects
physics.setDrawMode( "normal" ) -- the default Corona renderer, with no collision outlines

hybrid를 적용하면 화면이 아래와 같이 나옵니다.



physics.body 가 적용되는 범위가 투명하게 다른 색으로 표시되고 테두리도 따로 그어져서 physics가 얼만큼 어디에 적용 되는지 알 수 있습니다.

debug를 적용하면 아래와 같이 나옵니다.


원래 이미지는 안보이고 physics.body가 적용 되는 범위만 보입니다.

위에 표시된 색들도 다른데요. 각 색깔별로 아래오 같은 의미가 있습니다.
    * Orange: dynamic physics bodies (the default body type)
    * Dark blue: kinematic physics bodies
    * Green: static physics bodies, such as the ground or walls
    * Gray: a body that is "sleeping" due to lack of activity
    * Light blue: joints

포지션을 체크하고 속도를 체크하는 경우도 많이 있는데요.
이것을 체크하는 주기도 아래와 같이 설정할 수 있습니다.
physics.setPositionIterations

Sets the accuracy of the engine's position calculations.

physics.setPositionIterations( 16 )

The default value is 8, which means that the engine will iterate through eight position approximations per frame for each object. Increasing this number will cause fewer momentary innacuracies (overlapping objects. etc.) but will increase computational overhead. The default value should be good for most general cases.
physics.setVelocityIterations

Sets the accuracy of the engine's velocity calculations.

physics.setVelocityIterations( 6 )

The default value is 3, which means that the engine will iterate through three velocity approximations per frame for each object. Increasing this number will cause fewer momentary innacuracies (overlapping objects. etc.) but will increase computational overhead. The default value should be good for most general cases.

포지션이나 속도롤 보다 세밀하게 체크해서 콘트롤 하시려면 위의 숫자값들을 큰 숫자로 하셔서 코딩하시면 되겠죠?

이러한 코로나의 physics engine은 Box2D 엔진을 기본으로 만들어 졌답니다.
Box2D is a free open source 2-dimensional physics simulator engine written in C++ by Erin Catto and published under the zlib license. It has been used in Crayon Physics Deluxe, Rolando, Fantastic Contraption, Incredibots, Angry Birds, Transformice, Stripe physics2, and many online Flash games,[3] as well as iPhone, iPad and Android games using the Corona framework.

코로나는 이 Box2D 엔진의 대부분 기능을 포함하고 있고 또 일부 포함하지 않는 기능도 있답니다.

코로나 웹싸이트에 정리된 내용을 옮겨 봅니다.
Porting Box2D applications from other platforms should be fairly easy. The Corona API includes most of the core features of Box2D, including:

    * Automatic world setup, scaling, and synchronization with visible Corona objects
    * Basic collision geometry (boxes, circles and arbitrary polygons)
    * Complex collision geometry (multi-element bodies)
    * Attributes for primary body and fixture properties
    * Collision events via Corona event listeners, including collision forces
    * Primary collision event phases: began and ended
    * Additional collision event types: preCollision and postCollision, which correspond to Box2D "preSolve" and "postSolve" collision features
    * Draggable object handling within the simulation
    * Eight types of joints: distance, pivot, piston, friction, weld, wheel, pulley and touch (some of these are renamed from their Box2D counterparts; see “Joints” section below)
    * Touch joints (based on Box2D "mouse joints") can be used with multitouch, for simultaneous dragging of 5-10 physics objects; see "DebugDraw" sample project
    * Joint motors and limits
    * Applied forces and impulses, both linear and angular
    * Dynamic gravity, including accelerometer-driven gravity
    * Sensors and bullets
    * Collision categories, masking and groups
    * “DebugDraw” mode, including an exclusive "hybrid" mode showing the debug view as an overlay
    * Joint and body destructors

Features not yet supported include:

    * Gear joints
    * Ray casting, region queries, etc.
    * Automatic resizing of physics objects when Corona display objects are resized with xScale/yScale attributes (avoid using xScale/yScale on an already-existing physical object in the meantime).

오늘은 코로나 SDK의 Physics engine 기본을 살펴 봤습니다.
다음 시간에는 physics를 입힌 물체끼리 충돌할 때 튕겨나간다든지, 약한 쪽을 부숴지게 한다든지 하는 효과를 줄 수 있는 Collision events 에 대해 살펴 볼 것 같습니다.

그럼 다음 시간에 뵐께요.



반응형

'Corona SDK > Corona Doc' 카테고리의 다른 글

Physics Joints 예제 코드  (0) 2011.09.29
Physics Joint  (0) 2011.09.28
Physics Bodies 코딩 하기  (5) 2011.09.27
Physics Bodies  (0) 2011.09.26
Physics의 Collision Event  (0) 2011.09.26
정말 매력있는 코로나의 Physics Engine  (2) 2011.09.20
config.lua 파일과 build.lua 파일...  (2) 2011.09.19
코로나 프로그래밍 기본 규칙...  (0) 2011.09.15
폰트 및 config.lua 파일에 대하여.  (10) 2011.09.14
처음으로 코딩 해 보기  (2) 2011.09.12

Comment

  1. stud 2011.09.22 18:18

    와우 상당히 편리한 물리엔진이네요...충돌도 상당히 궁금합니다~!