이제 새로운 코인만 생성하면 대충 완성된 형태의 게임이 완성될 것 같습니다. 남은 과정은 점수, Scene 전환, 시간제한 정도가 있겠네요. 점점 마지막을 향해 가고 있습니다!!
- 11 - 새로운 코인 생성
1. 사라진 코인의 수?
새로운 코인을 생성할 차례입니다. 이미 남아있는 코인들은 바닥 쪽으로 이동한 상태이기 때문에, 각 라인 별로 비어있는 위치에 코인을 생성해주면 될 것 같습니다. 다음과 같이 해보려고 합니다.
- 랜덤하게 코인 종류를 선택
- 코인 이미지를 종류에 맞게 변경
- 코인을 setVisible(True)로 화면에 보이도록 설정
- 새로운 코인의 액션 추가
이렇게 하면, 마치 새로운 코인이 위에서 아래로 떨어지는 것처럼 보이게 할 수 있을 것 같습니다. 여기서 새로운 코인이 떨어지는 위치를 잘 계산해야 하는데요. 다음과 같이 하려고 합니다.
빨간색 원은 새로 생성될 코인인데요. 간단하게 현재 라인에 비어있는 코인이 두 개라면, 두 개 만큼 위에서 떨어지도록 하는 것이 동작의 전부입니다. 코인의 간격은 이미 초기화면을 구성할 때 정했기 때문에 이 값을 잘 이용하면 될 것 같습니다. 그런데, 새로 코인을 생성하는 시점에서는 각 라인 별로 얼마나 많은 코인이 사라졌는지를 알 수가 없습니다. 관련한 내용을 확인한 적이 없어서 인데요. 새로 코인을 생성하는 함수에서 각 라인 별로 사라진 코인의 수를 확인하고, 이후 갯수에 맞게 코인 액션을 추가하겠습니다.
/Classes/HelloWorldScene.h
class HelloWorld : public cocos2d::CCLayer { private: ... int _lineDeadCoin[BOARDX]; public: ... void addNewCoin(); void setNewCoin(GameCoin* coin); void addNewCoinAction(); };
_lineDeadCoin 배열에 각 라인의 사라진 코인 수를 저장하겠습니다. addNewCoin() 함수가 전체 동작의 중심이 될 것이고요. setNewCoin()에서는 새로 생성될 코인의 정보를 설정하고, addNewCoinAction()을 통해 위에서 아래로 떨어지는 액션을 추가하겠습니다.
2. 코인 생성
addNewCoin() 함수부터 확인해보겠습니다.
/Classes/HelloWorldScene.cpp
void HelloWorld::addNewCoin() { GameCoin* coin; int line = 0; for (int i = 0; i < BOARDX; i++) _lineDeadCoin[i] = 0; for (int i = 0; i < _gameCoins->count(); i++) { coin = (GameCoin*)_gameCoins->objectAtIndex(i); if (coin->getState() == GameCoin::DEAD) { line = (int)(i / BOARDY); _lineDeadCoin[line] += 1; setNewCoin(coin); } } addNewCoinAction(); }
우선, _lineDeadCoin 배열을 초기화하고 시작합니다. 전체 코인 중에서 DEAD 상태인 코인을 찾아서 각 라인 별로 갯수를 더해줍니다.
line = (int)(i / BOARDY) 를 통해 간단하게 현재 index의 코인이 어떤 라인에 위치하고 있는지를 알 수 있습니다. 해당 라인의 코인 수를 '1'개 증가하고요. setNewCoin()으로 코인의 각 정보를 설정합니다.
/Classes/HelloWorldScene.cpp
void HelloWorld::setNewCoin(GameCoin* coin) { CCString* name; CCTexture2D* tex; int coinType = rand() % TOTALCOINTYPE + 1; name = CCString::createWithFormat("coin_0%i.png", coinType); tex = CCTextureCache::sharedTextureCache()->addImage(name->getCString()); coin->setTexture(tex); coin->setVisible(true); coin->setType(coinType); coin->setState(GameCoin::LIVE); }
코인 설정하는 부분도 어렵지 않습니다. 앞서 말씀드린대로 코인 종류를 선택하고, 종류에 맞는 이미지 선택, 그리고 화면 상에 보이게 해주면 됩니다. 랜덤하게 결정한 값을 coinType에 저장하고 이 값을 이용해서 종류의 맞는 이미지를 선택해서 setTexture(tex)로 설정합니다. 그리고 다른 정보도 업데이트하고 마지막으로 코인의 상태를 LIVE로 변경해서 사용자가 코인을 선택할 수 있도록 해줍니다.
마지막으로 코인에 액션을 추가합니다.
/Classes/HelloWorldScene.cpp
void HelloWorld::addNewCoinAction() { GameCoin* coin; CCPoint pos; int startIndex; int diffY = 120; for (int i = 0; i < BOARDX; i++) { if(_lineDeadCoin[i] > 0) { startIndex = i * BOARDY; for (int j = startIndex; j < startIndex + _lineDeadCoin[i]; j++) { coin = (GameCoin*)_gameCoins->objectAtIndex(j); pos = coin->getPosition(); coin->setPosition(ccp(pos.x, pos.y + (_lineDeadCoin[i] * diffY))); moveCoin(coin, pos); } } } }
이미 각 라인 별로 사라진 코인의 수는 계산했기 때문에, 라인 별로 위부터 사라진 갯수만큼만 액션을 추가하면 되겠습니다. 처음 설명한 아이디어와 같이 (사라진 코인 개수 * diffY) 만큼 위에서 떨어지게하면 되는데요. 각 위치를 설정하고, 이전에 만들어 놓은 moveCoin()으로 액션을 추가합니다.
여기서 한 가지 실수아닌 실수를 했는데요. diffY를 클래스 변수로 따로 설정하지 않아서 이전에 설정한 값이 있음에도 불구하고, 이 함수에는 사용할 수가 없습니다. 따라서 다시 이 함수에서 'int diffY = 120;' 으로 그냥 추가해서 사용하도록 하겠습니다.
이제 필요한 함수는 모두 만들었으니, 터치 마지막 부분에 추가를 해보겠습니다.
/Classes/HelloWorldScene.cpp
void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event) { CCTouch* touch = (CCTouch*)( touches->anyObject() ); CCPoint location = touch->getLocation(); clearSelectCoin(); moveUpDeadCoin(); addNewCoin(); }
필요한 작업은 모두 마쳤습니다. 빌드하고 동작이 잘 되는지 확인해보시기 바랍니다. 저는 잘 되네요~!!
이제 중요한 게임 동작은 모두 완성했습니다. 다음에는 실제 게임 동작 외에 게임을 좀 더 긴장감있고 중독성있게 만들어 주는 여러가지 장치들을 추가해보겠습니다. 물론 제가 만든 게임은 중독성이나 긴장감 따위는 전혀없는 아주 건전한 게임입니다. ^^;
읽어주셔서 감사합니다. 끝!
'cocos2d-x > pyocopang' 카테고리의 다른 글
cocos2d-x 포코팡 류 게임만들기!! - 12 - 점수 계산 (0) | 2014.07.12 |
---|---|
[버그] 첫 번째 코인이 선택되지 않는 문제 - 해결!! (0) | 2014.07.11 |
cocos2d-x 포코팡 류 게임만들기!! - 10 - 코인 애니메이션 (0) | 2014.07.07 |
cocos2d-x 포코팡 류 게임만들기!! - 9 - 사라질 코인들은 모두 위로~! (1) | 2014.07.05 |
cocos2d-x 포코팡 류 게임만들기!! - 8 - 없어진 coin 채우기 : idea (0) | 2014.07.04 |