위 코드를 살펴 보겠습니다.
자동차 몸체와 바퀴가 조인트로 연결 돼 있고 앱을 시작하면 위에서 밑으로 떨어집니다.
다 떨어지면 언덕에서 아래로 구르게 됩니다.
display.setStatusBar( display.HiddenStatusBar )
require "physics"
physics.start()
physics.setDrawMode("hybrid")
--Determine Device Size
local disw = display.contentWidth
local dish = display.contentHeight
local car = display.newGroup()
여기 까지는 따로 설명이 필요 없구요. (newGroup()에 대해서는 나중에 살펴 볼 겁니다.)
--Create The Car
local car_body = display.newRect(0, 0, 102, 20)
car_body:setFillColor(100,75,75)
local car_rear_wheel = display.newCircle( 10, 30, 15 )
local car_front_wheel = display.newCircle( 80,30,15 )
car_rear_wheel:setFillColor(25,128,25)
car_front_wheel:setFillColor(25,25,200)
여긴 자동차를 만드는 부분입니다.몸통을 newRect로 만들고 색을 정해 주고 앞바퀴와 뒷바퀴를 newCircle()을 이용해서 만듭니다.
자동차 몸통이 있고 그 아래에 파랗고 녹색인 바퀴 두개가 있습니다.
그 다음은 바닥과 왼쪽 오른쪽 벽 그리고 경사도를 아래와 같이 만듭니다.
--Add An Environment
local floor = display.newRect(0, dish-10, disw,dish )
local lwall = display.newRect(0, 0, 0,dish )
local rwall = display.newRect(disw,0,disw,dish)
local ramp = display.newLine(0,dish-40,disw,dish-10)
local rshape = {0,0,disw,30}
ramp.width = 3
여기 까지 하면 위와 같이 나옵니다.
rshape는 나중에 ramp에 addBody할 때 사용할 겁니다.
한번 볼까요?
--Apply The Physics
physics.addBody(floor,"static", {friction=0.5})
physics.addBody(lwall,"static", {friction=0.5})
physics.addBody(rwall,"static", {friction=0.5})
physics.addBody(ramp,"static",{friction=1,shape=rshape})
physics.addBody(car_body,{density=0,friction=0,bounce=0})
physics.addBody(car_rear_wheel,{density=2,friction=3,bounce=0,radius=15})
physics.addBody(car_front_wheel,{density=2,friction=3,bounce=0,radius=15})
지금까지 만든 객체들에 addBody를 해 줍니다.
자동차 몸체와 바퀴만 빼 놓고 나머지는 static으로 해 줍니다. 움직이지 않게 하겠다는 뜻이죠?
몸체와 바퀴는 표시를 안 했으니 디폴트 값인 dynamic이 적용 됩니다.
그러면 디폴트 중력인 9.8의 중력을 받아서 밑으로 떨어지게 될 겁니다.
이 상태로 실행하면 dynamic이 적용된 몸체와 바퀴가 떨어져서 경사면에서 아래로 미끄러지거나 구르게 됩니다.
그런데 아직 서로간의 관계를 joint를 써서 사용하지 않았기 때문에 따로따로 떨어져서 움직이게 됩니다.
이제 Joint를 사용하겠습니다.
--Add The Wheel Joints and Let The Problems Begin
local rear_wheel_joint = physics.newJoint("wheel",car_body,car_rear_wheel,10,10,0,10)
local front_wheel_joint = physics.newJoint("wheel",car_body,car_front_wheel,80,10,0,10)
앞바퀴와 뒷바퀴를 각각 자동차 몸체에 wheel joint를 사용해서 연결했습니다.
몸체랑 바퀴랑 연결되긴 했는데 뭔가가 조금 이상하죠?
일단 바퀴끼리 막 서로 가까워지기도 하고 그러니까 이 거리를 항상 유지해 보죠.
--Keep The Wheels Separated
local wheel_distance_joint = physics.newJoint("distance",car_rear_wheel, car_front_wheel, car_rear_wheel.x, car_rear_wheel.y, car_front_wheel.x, car_front_wheel.y)
distance joint를 써서 두 바퀴의 거리를 항상 유지하도록 했습니다.
돌려 보시면 아까보다는 조금 나아 졌는데 아직 완벽하지는 않습니다.
나머지는 여러분들이 weld, pivot 조인트 등을 사용하셔서 한번 적용해 보세요.
현재까지의 전체 소스는 아래와 같습니다.
display.setStatusBar( display.HiddenStatusBar )
require "physics"
physics.start()
physics.setDrawMode("hybrid")
--Determine Device Size
local disw = display.contentWidth
local dish = display.contentHeight
local car = display.newGroup()
--Create The Car
local car_body = display.newRect(0, 0, 102, 20)
car_body:setFillColor(100,75,75)
local car_rear_wheel = display.newCircle( 10, 30, 15 )
local car_front_wheel = display.newCircle( 80,30,15 )
car_rear_wheel:setFillColor(25,128,25)
car_front_wheel:setFillColor(25,25,200)
--Add An Environment
local floor = display.newRect(0, dish-10, disw,dish )
local lwall = display.newRect(0, 0, 0,dish )
local rwall = display.newRect(disw,0,disw,dish)
local ramp = display.newLine(0,dish-40,disw,dish-10)
local rshape = {0,0,disw,30}
ramp.width = 3
--Apply The Physics
physics.addBody(floor,"static", {friction=0.5})
physics.addBody(lwall,"static", {friction=0.5})
physics.addBody(rwall,"static", {friction=0.5})
physics.addBody(ramp,"static",{friction=1,shape=rshape})
physics.addBody(car_body,{density=0,friction=0,bounce=0})
physics.addBody(car_rear_wheel,{density=2,friction=3,bounce=0,radius=15})
physics.addBody(car_front_wheel,{density=2,friction=3,bounce=0,radius=15})
--Add The Wheel Joints and Let The Problems Begin
local rear_wheel_joint = physics.newJoint("wheel",car_body,car_rear_wheel,10,10,0,10)
local front_wheel_joint = physics.newJoint("wheel",car_body,car_front_wheel,80,10,0,10)
--Keep The Wheels Separated
local wheel_distance_joint = physics.newJoint("distance",car_rear_wheel, car_front_wheel, car_rear_wheel.x, car_rear_wheel.y, car_front_wheel.x, car_front_wheel.y)
--Populate The Scene
car:insert(lwall)
car:insert(rwall)
car:insert(floor)
car:insert(ramp)
car:insert(car_body)
car:insert(car_rear_wheel)
car:insert(car_front_wheel)
return car
끝에 insert는 처음에 설정했던 car라는 그룹에 각 객체들을 넣는다는 겁니다.
나중에 화면전환 같은 거 할 때 유용하게 사용 됩니다.
이 부분은 그 때 자세히 살펴 보도록 하겠습니다.
소스 하나만 더 소개시켜 드릴까요?
저 인형이 하늘에서 떨어져서 쓰러지는 건데요.
목, 팔, 다리,몸통 관절들이 제법 사실적으로 움직입니다.
이 샘플은 pivot 조인트만 이용해서 만들었습니다.
그리고 RotationLimits를 이용해서 팔관절, 다리 관절등이 반대로 꺾이지 않게 했구요
그리고 머리, 팔, 다리를 끌고 드래그 하면 그에 따라 움직이는데요.
이건 물론 touch 조인트를 이용해서 만들었구요.
샘플 코드를 압축해서 올려 놓습니다.
소스 분석은 직접 한번 해 보세요.
그리고 참고로 Box2D의 개발자 매뉴얼도 올려 놓습니다.
조인트에 대한 부분도 나와있으니까 한번 살펴 보세요.
이로서 Corona SDK의 Physics Engine에 대해 모두 훑어 봤습니다.
다음 시간부터는 어떤 주제로 할까요?
여하튼 다음에 뵈요....
'Corona SDK > Corona Doc' 카테고리의 다른 글
코로나로 애니메이션 구현하기 (0) | 2011.10.08 |
---|---|
Display Object와 Stage 사용하기 (0) | 2011.10.06 |
텍스트, 이미지, 모양 표시하기... 2 (5) | 2011.10.06 |
텍스트, 이미지, 모양 표시하기... 1 (0) | 2011.10.05 |
accelerometer 휴대폰 기울이는 대로 움직이도록 하기... (0) | 2011.10.01 |
Physics Joint (0) | 2011.09.28 |
Physics Bodies 코딩 하기 (5) | 2011.09.28 |
Physics Bodies (0) | 2011.09.27 |
Physics의 Collision Event (0) | 2011.09.27 |
Corona SDK Physics API (1) | 2011.09.22 |