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
관리 메뉴

만재송

[Cocos Creator] Tiled Map 정복하기 (5) - 충돌체 구현 본문

프로그래밍/COCOS Creator

[Cocos Creator] Tiled Map 정복하기 (5) - 충돌체 구현

만재송 2018. 2. 12. 02:56

없는게없는 Tiled Map Editor


하다하다 충돌체 까지 구현할 수 있다. Tiled 에디터만 있으면 봄버맨 같은 게임은 식은죽 먹기로 만들수 있을것같다.



(심지어 누가 Tiled 에디터로 만들었다...)


우리도 빨리 Tiled Map 을 정복하고 봄버맨 같은 게임을 만들어보자! 기존에 만든 타일맵을 Tiled 에디터로 불러오자. 먼저 돌이나 벽같은 장애물에 충돌체를 구현하자.



장애물 지정


이전 챕터까지 완료했으면 키보드로 이동하는 외계인을 볼 수 있을것이다. 하지만 외계인도 UFO 가 있어야 나는법! 벽을 뚫고 지나갈수는 없을것이다. 그러니 벽이나 돌같은 장애물에 충돌했을때 못가게 하는 기능을 구현해보자. 충돌체를 지정하기 위해서는 메타 데이터로 사용할 레이어를 만들어야한다. 간단하게 충돌부분을 색깔있는 타일로 지정하기 위해서 메타 타일을 만들어줘야한다. 굳이 타일을 만들필요는 없다. 아래 파일을 다운만 받으면된다.


meta_tile.png.zip


그리고 처음에 했던 타일셋을 추가하자. 그럼 meta_tile 을 사용할수 있게된다.



이제 두 타일의 속성을 변경하자. 빨간색 타일은 장애물로, 초록색 타일은 아이템 충돌체로 지정할것이다. 그러기 위해 사용자 정의 속성을 이용할 것이다. 왼쪽 하단에 보면 + 버튼이 있는데 클릭해보자.



클릭하면 속성 추가 창이 뜰것이다. 그럼 빨간색과 초록색 타일에 아래와 같이 지정하자.


빨간색 타일 => 속성이름: collisionType, 타입: string, 값: obstacle

초록색 타일 => 속성이름: collisionType, 타입: string, 값: item


저장을하면 충돌 타일을 설치하기 위해 새로운 레이어를 생성해야한다. 레이어 -> 타일 레이어를 생성하고 이름을 Meta 로 변경하자.



새로운 레이어를 생성하는 이유는 각 레이어의 위치에 있는 타일은 1자리에 1개만 만들수 있기 때문이다. 그리고 각 기능에 맞는 레이어 끼리 나누면 사용하기에도 편하다.


이제 빨간색 타일로 장애물이라고 생각하는 타일에 덕지덕지 바르자. 필자는 아래와같이 추가했다.



장애물이라고 생각하는 타일을 빨간색 타일에 추가하면 완성이다.



아이템 만들기


장애물은 다만들었으니 이제 아이템을 만들어보자. 왠만하면 아이템과 장애물은 레이어로 구분을하자. 레이어 -> 타일 레이어를 클릭 후 이름을 Item 으로 변경하자.


그다음 타일셋에 있는 선인장 모양의 타일을 아이템으로 지정하고 몇군대 생성해보자.



이제 생성한 아이템에 충돌체 타일을 입혀야한다. Meta 레이어를 클릭하고 초록색 타일로 선인장 타일위에 붙이자.




스크립트 작성


Cocos Creator 를 실행시켜서 TiledMap 스크립트를 수정하자.


먼저 onLoad 에 Meta 레이어를 불러오고 tilePos 변수를 프로퍼티로 변경하자.


onLoad: function () {
this.tiledMap = this.node.getComponent(cc.TiledMap);
this.objects = this.tiledMap.getObjectGroup("Objects");
this.mainLayer = this.tiledMap.getLayer("Background");
this.spawnPoint = this.objects.getObject("SpawnPoint");
this.metaLayer = this.tiledMap.getLayer("Meta");
this.tilePos = this.getTilePos(this.spawnPoint.offset);
var pos = this.mainLayer.getPositionAt(this.tilePos);
this.target.setPosition(pos.x - 480, pos.y - 320);

this.addKeyboardListener();
},


다음은 새로운 메서드인 setTargetPosition 메서드를 추가하자.


setTargetPosition: function (addingTilePos, addingTargetPos) {
var tilePos = cc.v2(this.tilePos.x + addingTilePos.x, this.tilePos.y + addingTilePos.y);
var tileGID = this.metaLayer.getTileGIDAt(tilePos);
if (tileGID) {
var properties = this.tiledMap.getPropertiesForGID(tileGID);
if (properties != null) {
if (properties["collisionType"] === "obstacle") {
return;
} else if (properties["collisionType"] === "item") {

}
}
}
this.tilePos = tilePos;
this.target.x += addingTargetPos.x;
this.target.y += addingTargetPos.y;
},


setTargetPosition 는 키보드 이벤트가 발생할 때 마다 호출되는 메서드다. 어느방향으로 움직이느냐에 따라 파라미터 값인 addingTilePos, addingTargetPos 값이 다르게 들어온다. 


먼저 tileGID 변수는 메타레이어의 해당 타일 좌표의 GID 를 가져온다. GID 는 Global Id 의 약자이다. 각각의 타일은 GID 를 가지고 있는데 타일의 좌표를 넘겨주면 해당 타일의 GID를 얻을 수 있다. 타일이 없을경우에는 0을 호출한다.


tileGID 가 0 이아니라는 말은 해당위치에 타일이 있다는 뜻이다. 첫 if 문을 통과하면 tiledMap 컴포넌트에 있는 getPropertiesForGID 메서드를 호출한다. getPropertiesForGID는 해당 타일의 GID를 통해 아까 TIled 에디터에서 만든 사용자 정의 속성 값을 리턴한다.


값이 있으면 TIled 에디터에서 만든 사용자 정의 속성 값이 있다는 말이므로 다음 if 문을 넘어간다. 마지막으로 해당 객체의 프로퍼티 값이 obstacle 인지 item 인지 검사를 하고 obstacle 이면 포지션을 변경하지 않고 메서드를 빠져나간다. 


마지막으로 모든 예외처리가 완료되면 Sprite 의 포지션과 Sprite가 위치하고있는 타일 포지션을 변경해준다.


addKeyboardListener: function () {
var self = this;
var tileSize = this.tiledMap.getTileSize();
this.listener = cc.EventListener.create({
event: cc.EventListener.KEYBOARD,
onKeyPressed: function (key, event) {
    switch(key) {
case 65:
self.setTargetPosition(cc.v2(-1, 0), cc.v2(-tileSize.width, 0));
        break;
case 83:
self.setTargetPosition(cc.v2(0, 1), cc.v2(0, -tileSize.height));
        break;
case 68:
self.setTargetPosition(cc.v2(1, 0), cc.v2(tileSize.width, 0));
        break;
case 87:
self.setTargetPosition(cc.v2(0, -1), cc.v2(0, tileSize.height));
        break;
    }
}
});
cc.eventManager.addListener(this.listener, this.target);
},


이제 키보드 이벤트를 통하여 setTargetPosition 메서드를 호출해주면된다. 이동하는 방향에 따라 변경할 타일의 포지션과 Sprite의 포지션을 보내준다.


이제 저장하고 실행을 해보자. 빨간 부분에는 못지나가는 기능이 탄생했다. 빨간색, 초록색 타일을 보기싫다면 metaLayer의 노드의 active를 false로 하면된다


this.metaLayer.node.active = false;







참고




Tiled Map 정복 시리즈



Comments