본문 바로가기

cocos2d-x/pyocopang

cocos2d-x 포코팡 류 게임만들기!! - 7 - 게임을 좀 더 제대로! (2)

우연하게 네이버 블로그에서 제 글의 게임이미지로 포코팡류 게임을 만들고 계시는 분을 봤습니다.
신기하기도 하고, 뿌듯하기도 했지만, 열심히하고 계시는 그 분에 비해 저는 너무 지지부진한 것 같아서 부끄러운 마음도 들었습니다. 열심히 해야겠습니다.


지난 시간에 이어서, 좀 더 게임답게 동작하도록 만들어보겠습니다.

같은 종류의 코인이 연속되어 선택되도록 만들어 놓은 상태기 때문에, 이번에는 화면에서 손가락을 떼는 순간 선택된 코인들을 제거하도록 해보겠습니다.

처음 선택된 코인 기준으로 동일한 종류인 경우 카운트값을 증가시키고, 이 값이 3개 이상이면 제거하면 되기 때문에 그렇게 어려운 작업은 아닐 것 같습니다.


- 7 - 게임을 좀 더 제대로! (2)

1. 선택된 코인의 개수를 저장


우선 헤더파일에 선택과 삭제에 필요한 카운터 변수를 추가하고, 관련 동작에 대한 함수도 추가하겠습니다.

/Classes/HelloWorldScene.h

class HelloWorld : public cocos2d::CCLayer
{
private:
    enum {
        BOARDX = 7,
    ...
    int _selectCoinCount;

public:
    ...
    void clearSelectCoin();
    void resetSelectMask();
    void resetGameInfo();
};

int _selectCoinCount 변수를 초기화하고, 각 함수에서는 선택된 코인을 제거, 터치동작이 종료되면 다시 값들을 초기화하는 등의 동작을 수행하게 될 것입니다.

우선 게임 초기화 부분에서 _selectCoinCount 변수를 0으로 설정합니다.

/Classes/HelloWorldScene.cpp

void HelloWorld::initGameCoin()
{
    int coinXPos = 0;
    int coinYPos = 0;
    ...
    int _selectCoinCount = 0;
}


이전에 작성해놓은 코드를 보면, 

 - 터치가 시작된 위치의 코인을 선택하고(ccTouchesBegan), 
 - 손가락을 움직이는 경우, 같은 종류의 코인일 때만 추가하기 때문에(ccTouchesMoved)

/Classes/HelloWorldScene.cpp

void HelloWorld::ccTouchesBegan(CCSet* touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocation();

    _lastCoin = checkPushGameCoin(location);
    if (_lastCoin > 0) {
        addSelectCoins(_lastCoin);
    }
}

void HelloWorld::ccTouchesMoved(CCSet* touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocation();
    int newCoin = -1;

    if (inLastCoin(location) == false) {
        newCoin = checkAdjacentCoin(location);

        if (compareCoinType(_lastCoin, newCoin)) {
            _lastCoin = newCoin;
            addSelectCoins(_lastCoin);
        }
    }
}

addSelectCoins() 함수 내에서 _selectCoinCount 값을 증가하면 될 것 같습니다.

/Classes/HelloWorldScene.cpp

int HelloWorld::addSelectCoins(int index) 
{ 
    if(index < 0) { 
        return -1; 
    } 
 
    GameCoin* tmpCoin = (GameCoin*)_gameCoins->objectAtIndex(index); 
    CCSprite* selectMask = (CCSprite*)_selectMask->objectAtIndex(index); 
 
    if(tmpCoin->getState() != GameCoin::SELECT) { 
        tmpCoin->setState(GameCoin::SELECT); 
        _selectCoins->addObject(tmpCoin); 
 
        selectMask->setVisible(true); 
    } 
 
    _selectCoinCount += 1; 
 
    return 0; 
} 


2. 코인 클리어~~!!


앞서 차곡차곡 쌓아온 _selectCoins 내의 코인들을 삭제하는 일이 남았습니다. 3개 이상 연속되어 선택되면 코인들이 삭제되는 동작입니다.

화면에서 터치했던 손가락을 떼는 순간 발생하는 이벤트이기 때문에, ccTouchesEnded() 함수 내에 관련 동작을 수행합니다. 앞서 선언했던 clearSelectCoin()에 구현하도록 하겠습니다.

/Classes/HelloWorldScene.cpp

void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->getLocation();

    clearSelectCoin();
}
void HelloWorld::clearSelectCoin()
{
    int index;
    GameCoin* tmpCoin;

    if(_selectCoinCount >= 3) {
        for(index = 0; index < _selectCoins->count(); index++) {
            tmpCoin = (GameCoin*)_selectCoins->objectAtIndex(index);
            tmpCoin->setState(GameCoin::DEAD);
            tmpCoin->setVisible(false);
        }
    }
    else {
        for(index = 0; index < _selectCoins->count(); index++) {
            tmpCoin = (GameCoin*)_selectCoins->objectAtIndex(index);
            tmpCoin->setState(GameCoin::LIVE);
        }
    }

    resetSelectMask();
    resetGameInfo();
}

_selectCoinCount 값이 3 이상이면, 선택된 코인의 상태를 GameCoin::DEAD로 설정하고, setVisible(false)로 설정하여 화면에서 보이지 않게 설정합니다.

반대로, 3개가 안되는 경우에는 코인 상태를 다시 GameCoin::LIVE 로 설정합니다.

그리고나서, resetSelectMask()로 코인이 선택된 것을 시각화하기 위해서 추가했던 불투명한 이미지를 초기화하고, resetGameInfo()로 게임과 관련해서 초기화할 필요가 있는 변수들을 설정합니다.


3. 다시 처음으로


터치에서 손을 떼고, 다음 터치를 위해 초기화하는 부분을 살펴보겠습니다.

/Classes/HelloWorldScene.cpp

void HelloWorld::resetSelectMask()
{
    CCSprite* selectMask;

    for(int i = 0; i < _selectMask->count(); i++) {
        selectMask = (CCSprite*)_selectMask->objectAtIndex(i);
        selectMask->setVisible(false);
    }
}

복잡하게 생각할 것 없이 모든 마스크를 다시 보이지 않도록 설정합니다. 물론 효율이나 성능을 고려했을 때, 흠... 하고 갸우뚱할 수 있지만, 일단 구현이 목적이었으니까요. --;

void HelloWorld::resetGameInfo()
{
    _selectCoinCount = 0;
    _lastCoin = -1;

    _selectCoins->removeAllObjects();
}

resetGameInfo() 에서는 다음 터치를 위해 초기화할 변수들을 설정하는데요. 변수 이름을 보면 아시겠지만, 선택된 코인들과 관련한 값들을 모두 초기화하게 됩니다.




이전에 구현해 놓은 코드 덕분에 간단하게 코인을 제거할 수 있었습니다. 다음에는 삭제된 코인 위치에 새로운 코인들을 생성하는 방법을 생각해보겠습니다.

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