2015년 1월 12일 월요일

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵 블루베리 먹기

이번엔 저번 충돌방식과 같은 방법으로 블루베리를 먹어볼것이다.

방법은 저번과 동일하다.

 case cocos2d::EventKeyboard::KeyCode::KEY_E:{

  CCPoint playerPos = sprPlayer->getPosition();

  CCPoint tileCoord = this->tileCoordForPosition(playerPos);

  int tileGid = _meta->tileGIDAt(tileCoord);

  auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Eat"].asString();
  if (propertyValue.compare("True") == 0) { 
   _meta->removeTileAt(tileCoord);
   _tree->removeTileAt(tileCoord);

  }
break;
}

키보드 E를 눌렀을경우 적용시킨다.

타일의 id를 알고 타일의 Eat 이 True 일경우 그 타일을 삭제 시킨다.

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵 충돌 판정

캐릭터까지 움직이는 것을 다 했다면 타일맵으로 물체와 충돌하여 보자.

우선 tiled에서 아래 보이는 것처럼 레이어를 2개 추가 하고 tileset 을 하나 추가하자.

 tileset은 분홍색과 파란색 타일 두개가 있다.
 



레이어는 Tree와 Meta 라는 이름으로 2가지를 만들었고

Tree레이어로 나무와 물등 각각의 지형을 추가하자.

그후 Meta레이어로 분홍색 타일을 고른다음 충돌판정을 일으키고 싶은 곳에 타일을 두면 위

화면처럼 보일 것이다.

그후 분홍 타일의 Properties 에 property를 하나 추가한 다음 이름을 Collidable 이라하고  값을

True로 설정해놓는다.

헤더에 아래함수를 추가하고
CCPoint tileCoordForPosition(CCPoint position);

그후 cpp 코드에서 함수를 정의해준다.

CCPoint HelloWorld::tileCoordForPosition(CCPoint position)
{
 int x = position.x / _tileMap->getTileSize().width;
 int y = ((_tileMap->getMapSize().height * _tileMap->getTileSize().height) - position.y) / _tileMap->getTileSize().height;
 return ccp(x, y);
}

그다음 update에서 지속적으로 체크해준다 .

void HelloWorld::update(float delta){

 auto sprPlayer = (Sprite*)this->getChildByTag(TAG_SPRITE_PLAYER);
 this->setViewPointCenter(_player->getPosition());

 if (wKeyCheck){
  CCPoint playerPos = sprPlayer->getPosition();

  CCPoint tileCoord = this->tileCoordForPosition(playerPos + Point(0, 10));
  int tileGid = _meta->tileGIDAt(tileCoord);

  auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Collidable"].asString();
  if (propertyValue.compare("True") == 0) {
   auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_W);

   sprPlayer->getActionManager()->removeAction(action);
   wMoveCheck = false;
  }
 else{

  if (!wMoveCheck){
    auto action_0 = MoveBy::create(0.1, Point(0, TAG_SPRITE_PLAYER_SPEED));
    auto action_1 = RepeatForever::create(action_0);

    action_1->setTag(TAG_SPRITE_PLAYER_ACTION_W);

   sprPlayer->runAction(action_1);
    wMoveCheck = true;
   }
  }
 
 }

 if (sKeyCheck){
  CCPoint playerPos = sprPlayer->getPosition();

  CCPoint tileCoord = this->tileCoordForPosition(playerPos + Point(0, -10));
  int tileGid = _meta->tileGIDAt(tileCoord);

  CCLOG("tileGID:%d", tileGid);

  auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Collidable"].asString();
  if (propertyValue.compare("True") == 0) {
   auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_S);

   sprPlayer->getActionManager()->removeAction(action);
   sMoveCheck = false;
   CCLOG("sussece");

  }
  else{

   if (!sMoveCheck){
    auto action_0 = MoveBy::create(0.1, Point(0, -TAG_SPRITE_PLAYER_SPEED));
    auto action_1 = RepeatForever::create(action_0);
    action_1->setTag(TAG_SPRITE_PLAYER_ACTION_S);
    sprPlayer->runAction(action_1);
    sMoveCheck = true;
   }
  }

 

 }


 if (dKeyCheck){
  CCPoint playerPos = sprPlayer->getPosition();

  CCPoint tileCoord = this->tileCoordForPosition(playerPos + Point(10, 0));
  int tileGid = _meta->tileGIDAt(tileCoord);

  CCLOG("tileGID:%d", tileGid);

  auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Collidable"].asString();
  if (propertyValue.compare("True") == 0) {
   auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_D);

   sprPlayer->getActionManager()->removeAction(action);

   dMoveCheck = false;
   CCLOG("sussece");

  }
  else{

   if (!dMoveCheck){
    auto action_0 = MoveBy::create(0.1, Point(TAG_SPRITE_PLAYER_SPEED, 0));
    auto action_1 = RepeatForever::create(action_0);
    action_1->setTag(TAG_SPRITE_PLAYER_ACTION_D);
    sprPlayer->runAction(action_1);
    dMoveCheck = true;
   }
  }
 

 }
 if (aKeyCheck){
  CCPoint playerPos = sprPlayer->getPosition();

  CCPoint tileCoord = this->tileCoordForPosition(playerPos + Point(-10, 0));
  int tileGid = _meta->tileGIDAt(tileCoord);

  CCLOG("tileGID:%d", tileGid);


  auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Collidable"].asString();
  if (propertyValue.compare("True") == 0) {
   auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_A);

   sprPlayer->getActionManager()->removeAction(action);
   aMoveCheck = false;
   CCLOG("sussece");

  }
  else{

   if (!aMoveCheck){

    auto action_0 = MoveBy::create(0.1, Point(-TAG_SPRITE_PLAYER_SPEED, 0));
    auto action_1 = RepeatForever::create(action_0);
    action_1->setTag(TAG_SPRITE_PLAYER_ACTION_A);
    sprPlayer->runAction(action_1);
    aMoveCheck = true;
   }
  }
 }

 }

 위 소스에서 중요한 부분은 플레이어의 위치로부터 그 위치에있는 포인트를 tileCoord 로 변환

한 다음 그곳의 타일 ID를 가져온다. 그후 

auto properties = _tileMap->propertiesForGID(tileGid);

  ValueMap map = properties.asValueMap();

  String propertyValue = map["Collidable"].asString();

과정을 통해서  propertyValue 에 값을 넣은 다음 그 값이

if (propertyValue.compare("True") == 0) 이면

다음에 취할 명령을 넣으면 된다.

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵에 플레이어 와 카메라 같이 움직이기

캐릭터를 움직이면 화면을 움직이는 방법은

헤더(.h)에

void setViewPointCenter(CCPoint position);

cpp에

void HelloWorld::setViewPointCenter(CCPoint position) {
 CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 int x = MAX(position.x, winSize.width / 2);
 int y = MAX(position.y, winSize.height / 2);
 x = MIN(x, (_tileMap->getMapSize().width * this->_tileMap->getTileSize().width) - winSize.width / 2);
 y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height) - winSize.height / 2);
 CCPoint actualPosition = ccp(x, y);
 CCPoint centerOfView = ccp(winSize.width / 2, winSize.height / 2);
 CCPoint viewPoint = ccpSub(centerOfView, actualPosition);
 this->setPosition(viewPoint);
}

그후 init 함수에

this->scheduleUpdate();

해주고

void HelloWorld::update(float delta){

 this->setViewPointCenter(_player->getPosition());

}

이렇게하면 계속 화면의 위치를 플레이어의 위치로 바꿔 줄 수 있다.

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵에 플레이어 키보드로 움직이기

우선 헤더(.h)에

void onKeyPressed(EventKeyboard::KeyCode keyCode, Event *event);
void onKeyReleased(EventKeyboard::KeyCode keyCode, Event *event);

해주고

cpp 에서 init 함수에

 auto keylistener = EventListenerKeyboard::create();
 keylistener->onKeyPressed = CC_CALLBACK_2(HelloWorld::onKeyPressed, this);
 keylistener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);
 _eventDispatcher->addEventListenerWithSceneGraphPriority(keylistener, this);

해준다. onKeyPressed,onKeyReleased 함수가 필요함으로

void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode, Event *event){
 auto sprPlayer = (Sprite*)this->getChildByTag(TAG_SPRITE_PLAYER);

 switch (keyCode)
 {
 case cocos2d::EventKeyboard::KeyCode::KEY_A:{
  aKeyCheck = false;
  aMoveCheck = false;
  auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_A);
  sprPlayer->getActionManager()->removeAction(action);
  break;
 }

 case cocos2d::EventKeyboard::KeyCode::KEY_D:{

  dKeyCheck = false;
  dMoveCheck = false;
  auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_D);
  sprPlayer->getActionManager()->removeAction(action);
  break;
 }

 case cocos2d::EventKeyboard::KeyCode::KEY_S:
 {

  sKeyCheck = false;
  sMoveCheck = false;
  auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_S);
  sprPlayer->getActionManager()->removeAction(action);
  break;
 }

 case cocos2d::EventKeyboard::KeyCode::KEY_W:
 {
  wKeyCheck = false;
  wMoveCheck = false;
  auto action = (Action*)sprPlayer->getActionByTag(TAG_SPRITE_PLAYER_ACTION_W);
  sprPlayer->getActionManager()->removeAction(action);
  break;
 }

 default:
  break;
 }
}
void HelloWorld::onKeyPressed(EventKeyboard::KeyCode keyCode, Event *event){
 auto sprPlayer = (Sprite*)this->getChildByTag(TAG_SPRITE_PLAYER);

 switch (keyCode)
 {
 case cocos2d::EventKeyboard::KeyCode::KEY_A:{

  aKeyCheck = true;
  aMoveCheck = true;

   auto action_0 = MoveBy::create(0.1, Point(-TAG_SPRITE_PLAYER_SPEED, 0));
   auto action_1 = RepeatForever::create(action_0);
   action_1->setTag(TAG_SPRITE_PLAYER_ACTION_A);
   sprPlayer->runAction(action_1);


  break;
 }

 case cocos2d::EventKeyboard::KeyCode::KEY_D:{

  dKeyCheck = true;
  dMoveCheck = true;

   
     auto action_0 = MoveBy::create(0.1, Point(TAG_SPRITE_PLAYER_SPEED, 0));
     auto action_1 = RepeatForever::create(action_0);
     action_1->setTag(TAG_SPRITE_PLAYER_ACTION_D);
     sprPlayer->runAction(action_1);
  
 

  break;
 }
 case cocos2d::EventKeyboard::KeyCode::KEY_E:{
  CCPoint playerPos = sprPlayer->getPosition();
  CCPoint tileCoord = this->tileCoordForPosition(playerPos);
  int tileGid = _meta->tileGIDAt(tileCoord);
  auto properties = _tileMap->propertiesForGID(tileGid);
  ValueMap map = properties.asValueMap();
  String propertyValue = map["Eat"].asString();
  if (propertyValue.compare("True") == 0) {
 
   _meta->removeTileAt(tileCoord);
   _tree->removeTileAt(tileCoord);
  }

  break;
 }
 case cocos2d::EventKeyboard::KeyCode::KEY_S:
 {
  sKeyCheck = true;
  sMoveCheck = true;


   auto action_0 = MoveBy::create(0.1, Point(0, -TAG_SPRITE_PLAYER_SPEED));
   auto action_1 = RepeatForever::create(action_0);
   action_1->setTag(TAG_SPRITE_PLAYER_ACTION_S);
   sprPlayer->runAction(action_1);

  break;
 }

 case cocos2d::EventKeyboard::KeyCode::KEY_W:
 {
  wKeyCheck = true;
  wMoveCheck = true;


   auto action_0 = MoveBy::create(0.1, Point(0, TAG_SPRITE_PLAYER_SPEED));
   auto action_1 = RepeatForever::create(action_0);
   action_1->setTag(TAG_SPRITE_PLAYER_ACTION_W);
   sprPlayer->runAction(action_1);

  break;
 }

 default:
  break;
 }

}

이처럼 키보드의 각 키의 경우 마다 실행할 조건들을 넣어주면 된다.


2015년 1월 10일 토요일

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵에 플레이어 올리기

cocos에 타일맵을 띄우는 것을 성공했다면 이제 플레이어를 올려보자.

우선 플레이어 이미지를 Resources 폴더에 추가 한 후

잠깐 코드를 보자. 우선 플레이어를 띄우는 것은 간단하다.


 _player = Sprite::create("TileGameResources/Player.png");
 _player->setPosition(Point(x, y));
 this->addChild(_player);

헤더에 _player를 선언해준후  위와 같이 cpp에 쓰면 된다. 하지만 setPosition(Point(x, y)) 에

들어갈 x,y좌표가 필요하다. 이것은 시작점이다. 그냥 정하면 되기도 하지만 이번에는 타일맵

에서 좌표값을 가져와서 해보자.

우선 tiled를 켜서 tmx파일을 열어보자. 그후 object layer를 하나 추가하자,

레이어 이름은 object로 하였다.


그후 상단의 네모 도구를 이용하여 영역을 정한뒤 오브젝트 이름을 SpawnPoint라고 정한다.



그후 _player를 만들기전에

 CCTMXObjectGroup *objectGroup = _tileMap->objectGroupNamed("Object");

 if (objectGroup == NULL){
  CCLog("tile map has no objects object layer");
  return false;
 }

  
 ValueMap spawnPoint = objectGroup->getObject("SpawnPoint");

 int x = spawnPoint["x"].asInt();
 int y = spawnPoint["y"].asInt();

이렇게 함으로써 x,y좌표를 알 수 있고 플레이어의 포지션을 선택 할 수 있게 되었다.

플레이어가 생성된 모습은 다음과 같다.

2015년 1월 8일 목요일

cocos2d-x tiled를 이용한 타일게임 제작 -cocos2d-x 에 타일맵 적용하기

tiled로 tmx파일을 만들었다면 다음과 같이 하면 된다.

tmx 파일과 이미지 파일을 Resources 폴더에 넣은 뒤

우선 헤더 파일(.h)에 선언

CCTMXTiledMap *_tileMap;
CCTMXLayer *_background;


cpp에서는

 _tileMap = CCTMXTiledMap::create("TileGameResources/TileMap.tmx");

 _background = _tileMap->layerNamed("Background");

 this->addChild(_tileMap);

컴파일하면

2015년 1월 7일 수요일

cocos2d-x tiled를 이용한 타일게임 제작 -Tiled 설치 및 사용하기

http://www.raywenderlich.com/39113/cocos2d-x-tile-map-tutorial-part-1/ 

이곳을 상당히 인용하여 올리는 글임.

tiled로 tmx 파일을 만든후 이것을 이용하여 cocos2d-x에 맵과 여러 기능을 활용할 것임.


Tiled 주소
http://www.mapeditor.org/

간단히 Download 하면 끝.


tiled 실행후 new 클릭



맵크기와 타일 크기를 조절 할 수 있고 맵 형태를 선택 할 수도 있고

다양한 기능이 있음.


이제 tileset 으로 이미지를 불러옴
각각 타일 설정을 하고 누르면 완료


신나게 맵 만들면 기본 맵은 완성!
레이어 이름은 cocos2d-x에서 사용할것이니 잘 바꿔준다.



tiled도 툴이라 익숙해져야 함
나머지 자세한 기능은 게임 만들면서 올림