くまのがっこう神経衰弱バトルのスコアカウンターの数字の表示方法をご紹介します。
下記のクラスを作り画像で数字を表示しています。
Number.h
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#ifndef __NUMBER_H__ #define __NUMBER_H__ #include "cocos2d.h" USING_NS_CC; class Number : public Sprite { private: // 数字を表示する為のパラメーター int _number; int _span; bool _alignCenter; std::string _prefix; // 数字のオブジェクトを生成 void createNumber(int number); // 数字をクリアー void removeNumber(); public: virtual bool init(); CREATE_FUNC(Number); // 数字の画像ファイル名を設定 void setPrefix(std::string prefix); // 数字の間隔を設定 void setSpan(int span); // 数字の表示を中央寄せに設定 void setAlignCenter(); // 表示する数字を設定 void setNumber(int number); // このオブジェクトを削除 void remove(); }; #endif // __NUMBER_H__ |
Number.cpp
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
#include "Number.h" bool Number::init() { if (!Sprite::init()) { return false; } _alignCenter = false; // 子要素の数字の透明度を設定 this->setCascadeOpacityEnabled(true); // 最初に数字の0を設定 _number = 0; auto figure = Sprite::create(); figure->setTag(1); this->addChild(figure); return true; } // 数字のオブジェクトを生成 void Number::createNumber(int num) { _number = num; std::string number = StringUtils::format("%d", _number); long length = number.length(); int baseX = 0; if (_alignCenter) { if (0 < length) { baseX = (int)(length - 1) * _span / 2; } } for (int i=0; i<length; i++) { std::string charFigure = number.substr(length - 1 - i, 1); std::string imageFile = StringUtils::format("%s%s.png", _prefix.c_str(), charFigure.c_str()); auto figure = Sprite::createWithSpriteFrameName(imageFile); figure->setPosition(Point(baseX - i * _span, 0)); figure->setTag(1 + i); this->addChild(figure); } } // 数字をクリアー void Number::removeNumber() { std::string number = StringUtils::format("%d", _number); long length = number.length(); for (int i=0; i<length; i++) { auto pNumber = this->getChildByTag(1 + i); pNumber->removeFromParentAndCleanup(true); } } // 数字の画像ファイル名を設定 void Number::setPrefix(std::string prefix) { _prefix = prefix; } // 数字の間隔を設定 void Number::setSpan(int span) { _span = span; } // 数字の表示を中央寄せに設定 void Number::setAlignCenter() { _alignCenter = true; } // 表示する数字を設定 void Number::setNumber(int number) { removeNumber(); createNumber(number); } // このオブジェクトを削除 void Number::remove() { removeNumber(); this->removeFromParentAndCleanup(true); } |
大事な事は何百数字の画像を入れ替えてもメモリリークを起こさないように作る事です。新しい数字を表示する前に古い数字の画像をメモリから削除しています。
これを使いカウントダウンするサンプルです
HelloWorldScene.h
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 |
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Number.h" USING_NS_CC; class HelloWorld : public cocos2d::Layer { private: // カウンターの数字 Number* _counter1; Number* _counter2; // カウンターを表示 void showCounter(int num); public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__ |
HelloWorldScene.cpp
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include "HelloWorldScene.h" Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if ( !Layer::init() ) { return false; } // 背景表示 auto bg1 = LayerColor::create(Color4B::GRAY, 100, 40); bg1->setPosition(Point(124, 300)); this->addChild(bg1); auto bg2 = LayerColor::create(Color4B::GRAY, 100, 40); bg2->setPosition(Point(350, 300)); this->addChild(bg2); /* 数字の画像をキャッシュへ読込み ----------------------------------------------------- */ // figure_score_0.pngからfigure_score_0.pngの画像 SpriteFrameCache::getInstance()->addSpriteFramesWithFile("figure_score.plist"); /* カウンター1(右寄せ) ----------------------------------------------------- */ // 数字のオブジェクトを生成 _counter1 = Number::create(); // 表示位置を設定 _counter1->setPosition(200, 320); // 数字の桁の間隔(px)を設定 _counter1->setSpan(24); // 数字の画像名を設定(ファイル名の数字より前の部分) _counter1->setPrefix("figure_score_"); // 数字を設定 _counter1->setNumber(200); // 画面に表示 this->addChild(_counter1); /* カウンター2(中央寄せ) ----------------------------------------------------- */ _counter2 = Number::create(); _counter2->setPosition(400, 320); _counter2->setSpan(24); _counter2->setPrefix("figure_score_"); _counter2->setNumber(200); this->addChild(_counter2); // 文字を中央寄せに設定 _counter2->setAlignCenter(); /* カウントダウン ----------------------------------------------------- */ showCounter(200); return true; } void HelloWorld::showCounter(int num) { // 指定の数字を表示 _counter1->setNumber(num); _counter2->setNumber(num); // 数字が0よりも大きい場合は-1して表示 if (0 < num) { this->runAction(Sequence::create( DelayTime::create(0.05), CallFunc::create([&,num](){ showCounter(num - 1); }), nullptr)); } } |
サンプルで使用している数字の画像は以下にあります。
http://gameshonen.com/blog/uploads/figure_score.plist
http://gameshonen.com/blog/uploads/figure_score.png
きれいなコードではありませんが、そこそこ使い易いのでご紹介しました。ご参考になればと思います。