Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Total
관리 메뉴

만재송

[COCOS2D-JS] chipmunk 물리엔진 정복(5) - 충돌체크 본문

프로그래밍/COCOS2D-JS

[COCOS2D-JS] chipmunk 물리엔진 정복(5) - 충돌체크

만재송 2018. 1. 21. 20:30

충돌체크


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 물리엔진 정복 시리즈



Comments