본문 바로가기

cocos2d-x/pyocopang

cocos2d-x 포코팡 류 게임만들기!! - 11 - 새로운 코인 생성

이제 새로운 코인만 생성하면 대충 완성된 형태의 게임이 완성될 것 같습니다. 남은 과정은 점수, 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();
}

필요한 작업은 모두 마쳤습니다. 빌드하고 동작이 잘 되는지 확인해보시기 바랍니다. 저는 잘 되네요~!!


이제 중요한 게임 동작은 모두 완성했습니다. 다음에는 실제 게임 동작 외에 게임을 좀 더 긴장감있고 중독성있게 만들어 주는 여러가지 장치들을 추가해보겠습니다. 물론 제가 만든 게임은 중독성이나 긴장감 따위는 전혀없는 아주 건전한 게임입니다. ^^;

읽어주셔서 감사합니다. 끝!