만재송
[COCOS2D-JS] chipmunk 물리엔진 정복(5) - 충돌체크 본문
충돌체크
2개의 물체, 아니면 2개이상의 물체들이 충돌했을 때 일어나는 일을 수행하고 싶을때가 있다. 예로들면 똥피하기 같은 게임에서 똥이 바닥에 부딪쳤을 때 똥을 제거하고 싶다거나 플레이어가 똥에맞았을때 게임을 종료하는 함수를 실행하고 싶을때도 필요하다. 그래서 우리는 chipmunk 라이브러리에 있는 충돌체크 기능을 통해서 일을 수행 할 것이다.
준비단계
일단 이전 GameScene코드에서 addPhysicsBox 메서드를 추가하자. 이 메서드 안에는 사각형 모양의 물리기능을 갖는 Sprite를 생성 할 것이다.
addPhysicsBox: function() {
var sprite = new cc.PhysicsSprite(res.crate);
var body = new cp.Body(10, cp.momentForBox(10, 128, 128));
body.setPos(cp.v(360, 1000));
var shape = new cp.BoxShape(body, 128, 128);
this.space.addBody(body);
this.space.addShape(shape);
sprite.setBody(body);
this.addChild(sprite);
},
딱히 설명은 이전에 다했기때문에 할께없다. 다만 shape가 circle에서 box로 변경됬다. 사용법은 똑같고 인자값이 반지름에서 가로 세로 길이로 변경되고 나머지는 같다.
코드를 실행해보자 오렌지와 박스는 땅에 떨어지면서 서로 충돌하게 된다. 이제 충돌할 때 간단하게 콘솔창에 로그를 한번 남겨보자. 코드에 addCollisionHandler 메서드를 생성하고 아래와 같이 구현해보자.
addCollisionHandler: function() {
var beginHandler = function(arbiter, space) {
console.log("서로 부딪침");
return true;
};
var preSolveHandler = function(arbiter, space) {
return true;
};
var postSolveHandler = function(arbiter, space) {
};
var separateHandler = function(arbiter, space) {
};
this.space.addCollisionHandler(1000, 2000, beginHandler, preSolveHandler,
postSolveHandler, separateHandler);
},
Space 객체에는 두 물체가 충돌했을 때 호출되는 함수가 있다. addCollisionHandler 함수는 두 물체가 충돌했을 때의 과정을 4개로 나눠서 그에 대한 콜백함수를 실행한다.
첫번째 beginHandler 는 두 물체가 서로 부딪치는 즉시 호출하는 함수이다. 모든 콜백 함수는 2개의 파라미터 arbiter와 space를 가지는데 이부분은 다음장에서 설명하겠다.
두, 세번째 preSolveHandler, postSoveHandler 는 두 물체가 충돌을 계속하고 있으면 지속적으로 호출하는 함수이다. preSolve 와 postSolve의 차이점은 호출 되는 순서다. 서로 부딪치면 preSolve 가 먼저 호출 되고 postSolve가 그다음 호출된다. 뭔가 기능을 순차적으로 처리하고 싶을때 기능을 나눠서 사용하면 될 것 같다.
네번째 separateHandler 는 두 물체가 충돌을 하고 떨어졌을 때 호출하는 함수이다. 두 물체가 충돌 후 서로 떨어졌을 때 Sprite를 지우려고 하는 기능을 구현하고 싶으면 4번째 메서드에 추가하면된다.
그리고 beginHandler 와 preSolveHandler 에는 return Boolean 값이 있는데 true 면 서로 부딪치고 false 면 두 물체가 서로 통과 된다.
이제 충돌 체크 콜백 함수가 완성이 됬다. 그런데 어떻게 내가 원하는 물체만 콜백 함수를 실행하게 할 수 있을까?? 방법은 바로 addCollisionHandler 에 있는 첫번째 두번째 파라미터 인지 값이다.
shape를 생성하면 내장 메서드인 setCollisionType을 설정할 수 있다. 타입은 정수의 값이고 설정하지 않으면 0이다. 이를 통해 shape에 원하는 타입을 설정 후 addCollisionHandler에 원하는 물체의 타입을 넣어주면 해당 두타입의 물체가 충돌했을 때 콜백 함수가 실행된다.
첫번째 circleShape에는 타입을 2000으로 , 두번째 boxShape에는 1000을 추가하자. addCollisionHandler 에는 보통 첫번째 인자가 부딪치려는 대상, 두번째 인자가 부딪치는 대상으로 표현한다.
shape.setCollisionType(2000);
shape.setCollisionType(1000);
그리고 코드를 실행해보자. 서로 부딪쳤을 때 콘솔창에 "서로 부딪침" 이라는 문자열이 찍히게 될 것이다.
다음장에는 충돌을 했을 때 shape와 body를 제거하는 방법을 알아보겠다.
var GameScene = cc.Scene.extend({
ctor: function () {
this._super();
this.initPhysics();
this.initDebugMode();
this.scheduleUpdate();
},
initPhysics: function () {
this.space = new cp.Space();
this.space.iterations = 10;
this.space.gravity = cp.v(0, -800);
this.space.damping = 1;
this.space.collisionSlop = 0.1;
this.addPhysicsCircle();
this.addPhysicsBox();
this.addWallsAndGround();
this.addCollisionHandler();
},
addWallsAndGround: function() {
var bottomWall = new cp.SegmentShape(this.space.staticBody,
cp.v(0, 0), cp.v(720, 0), 100);
this.space.addStaticShape(bottomWall);
},
addPhysicsCircle: function() {
var sprite = new cc.PhysicsSprite(res.orange); // PhysicsSprite 객체 생성
var body = new cp.Body(10, cp.momentForCircle(10, 0, 64, cp.v(0, 0)));
body.setPos(cp.v(360, 720));
var shape = new cp.CircleShape(body, 64, cp.v(0, 0));
shape.setCollisionType(2000);
this.space.addBody(body);
this.space.addShape(shape);
sprite.setBody(body); // Sprite에 body 설정
this.addChild(sprite);
},
addPhysicsBox: function() {
var sprite = new cc.PhysicsSprite(res.crate);
var body = new cp.Body(10, cp.momentForBox(10, 128, 128));
body.setPos(cp.v(360, 1000));
var shape = new cp.BoxShape(body, 128, 128);
shape.setCollisionType(1000);
this.space.addBody(body);
this.space.addShape(shape);
sprite.setBody(body);
this.addChild(sprite);
},
addCollisionHandler: function() {
var beginHandler = function(arbiter, space) {
console.log("서로 부딪침");
return true;
};
var preSolveHandler = function(arbiter, space) {
return true;
};
var postSolveHandler = function(arbiter, space) {
};
var separateHandler = function(arbiter, space) {
};
this.space.addCollisionHandler(1000, 2000, beginHandler, preSolveHandler,
postSolveHandler, separateHandler);
},
initDebugMode: function() {
var phDebugNode = new cc.PhysicsDebugNode(this.space);
this.addChild(phDebugNode, 10);
},
update: function(dt) {
this.space.step(dt);
}
});
chipmunk 물리엔진 정복 시리즈
- chipmunk 물리엔진 정복(1) - 물리공간 생성 및 기본설정
- chipmunk 물리엔진 정복(2) - body 와 shape
- chipmunk 물리엔진 정복(3) - staticBody
- chipmunk 물리엔진 정복(4) - Sprite에 물리 적용하기
- chipmunk 물리엔진 정복(5) - 충돌체크
- chipmunk 물리엔진 정복(6) - body, shape 제거
- chipmunk 물리엔진 정복(7) - shape의 기능
'프로그래밍 > COCOS2D-JS' 카테고리의 다른 글
[COCOS2D-JS] chipmunk 물리엔진 정복(7) - shape의 기능 (0) | 2018.01.21 |
---|---|
[COCOS2D-JS] chipmunk 물리엔진 정복(6) - body, shape 제거 (0) | 2018.01.21 |
[COCOS2D-JS] chipmunk 물리엔진 정복(4) - Sprite에 물리 적용하기 (0) | 2018.01.21 |
[COCOS2D-JS] chipmunk 물리엔진 정복(3) - staticBody (0) | 2018.01.21 |
[COCOS2D-JS] chipmunk 물리엔진 정복(2) - body 와 shape (3) | 2018.01.21 |