Cocos2d-x パズルゲーム編 其の一 cocos2d::Mapとstd::mapを使ってみる

raharu(仮名)(プログラマー)
これがダイバージェンス1%の先の世界か。。。

さてこの間まではUnityでアクションゲーム作っていたのですが、
最近はもっぱらCocos2d-xでC++とにらめっこしてます。

C系の言語はUnityでC#をやっていた位で、今まであまり触った事がないので全然なれていませんが
こういう時はとにかく書く!ソースをひたすら書いてなれる!これに限ります。
とうことでひたすらトライ&エラーを繰り返していきたいと思います。
(だれか俺にc++教えてください!)

さて今回はパズルゲーム作るよということで現在まではこんな感じ。

f:id:raharu0425:20140228134219p:plain

なんかMavericksにするとFPSが安定しないんですよね。どなたか情報あったら教えてください。

※はまりどころ

何かしらの言語をやていればランダムに番号を作成して
マスを作成するのはお手の物だと思います。

自分もここまでは適当に脳内構築をソースに落とす事ができました。

cpp側

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//乱数の初期化
srand((unsigned int)time(NULL));

//正方形のものを作成
for (int x = 0; x < PANEL_X; x++) {
    for (int y = 0; y < PANEL_Y; y++) {
        //最大オブジェクト数の個数より算出
        int block_type = rand() % 5;

        //ブロック作成
        SpriteBlock* pSpriteblock = SpriteBlock::create(x, y, block_type);
        this->addChild(pSpriteblock->sprite_block);
    }
}

pSpriteblockはCCSpriteを継承してい変数(sprite_block)にSkeletonAnimationを丸め込んでいます。

座標点をキーにしてpSpriteBlockを連想配列で持っておく

とりあえず7x7のマスを全部持っていたいので、cocos2d::Map使ってみます。

header

1
cocos2d::Map<std::string, SpriteBlock*> mapTotal;

mapTotalには key: x:yの座標 value: 一つのマスオブジェクト

こんな感じだとこうなりました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//乱数の初期化
srand((unsigned int)time(NULL));

//正方形のものを作成
for (int x = 0; x < PANEL_X; x++) {
    for (int y = 0; y < PANEL_Y; y++) {
        //最大オブジェクト数の個数より算出
        int block_type = rand() % 5;

        //ブロック作成
        SpriteBlock* pSpriteblock = SpriteBlock::create(x, y, block_type);

        //座標点
        auto strPosX = Value(x);
        auto strPosY = Value(y);
        auto coordinate = strPosX.asString() + ":" + strPosY.asString();

        //cocos2d::Map
        mapTotal.insert(coordinate, pSpriteblock);

        this->addChild(pSpriteblock->sprite_block);
    }
}

大体おk。これをまわしてみます

1
2
3
4
5
6
7
8
9
10
//まわしてみた
cocos2d::Map<std::string, SpriteBlock*>::iterator itr = mapTotal.begin();

while (itr != mapTotal.end()) {
    auto key = itr->first;
    auto block = itr->second;

    std::cout << "key" << key << "block" << block->block_type;
    ++itr;
}

f:id:raharu0425:20140228135533p:plain

うんうん、いい感じじゃないですか。

そんじゃ各色毎の座標配列も持っておきたいのでこんなんも作ります。

header

1
cocos2d::Map<std::string, std::list<std::string> > mapColor;

そしたら
Invalid Type for cocos2d::Map<K, V>!
宣言しただけで怒られましたorz

どうやらcocos2d::Mapにこの書き方はできないんすかね?

そんじゃ致し方ないのでstd::mapを使ってみます

header

1
std::map<int, std::list<std::string> > mapColor;

こっちはおk。stdクラスなのでオペレーターが使えるはずですのでこんな感じで書いておきます

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
//乱数の初期化
srand((unsigned int)time(NULL));

//正方形のものを作成
for (int x = 0; x < PANEL_X; x++) {
    for (int y = 0; y < PANEL_Y; y++) {
        //最大オブジェクト数の個数より算出
        int block_type = rand() % 5;

        //ブロック作成
        SpriteBlock* pSpriteblock = SpriteBlock::create(x, y, block_type);

        auto strPosX = Value(x);
        auto strPosY = Value(y);
        auto coordinate = strPosX.asString() + ":" + strPosY.asString();

        //cocosMap
        mapTotal.insert(coordinate, pSpriteblock);

        //std::mapならオペレーター使える!
        mapColor[block_type].push_back(coordinate);

        this->addChild(pSpriteblock->sprite_block);
    }
}

この2つのmapに問い合わせてみます

1
2
3
4
5
6
7
8
//mapTotalに問い合わせてみる
auto atTest = mapTotal.at("1:1");
std::cout << "block_type" << atTest->block_type;


//色の数を数えてみる
auto atTest2 = mapColor.at(0);
std::cout << "red_color_count" << atTest2.size();
1
block_type2red_color_count8

いいですね。次回はマスをタップしたら座標点を返してくれる処理を作りたいと思います。