お世話になっております。
しゃまとんです。
cocos2dxをいじっていて、画面の一定領域を流れるメッセージを作りたいなぁと思い、クリッピング処理はできないだろうかと模索していたときのメモです。
この時は横に流れるメッセージを作ろうとしていました。
cocosのバージョンは3.2です。
クリッピングのやり方に関するwebページはいろいろと出てくるのですが、マスク用の画像を用意して、クリッピング処理するようなやり方だったのですが、これのためだけに画像用意するのもなぁ・・・と思い調べていたら、プログラムでスプライトを合成して、一枚のスプライトを生成できるみたいなので、利用してみました。
RenderTextureを利用して、テクスチャを生成し、スプライトを作成します。
流れるメッセージはそのままLabelを利用し、クリッピング処理をして、addChildします。
下記サンプルコードです。作成しているSceneから呼び出せば、表示される(はず)と思います。
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 |
// ヘッダへの定義も忘れずに void HelloWorld::_clippingTest() { auto layer_size = this->getContentSize(); auto pos_y = layer_size.height - 50.0f; auto font_size = 30; auto label = Label::createWithSystemFont("abcdefghijklmnopqrstuvwxvz", "Arial", font_size); auto init_pos = Vec2(layer_size.width * 3/4, pos_y); label->setPosition(init_pos); label->setAnchorPoint(Vec2(0, 0.5)); // 説明文を右から左に流す auto move = MoveTo::create(12.0f, Vec2(layer_size.width/4 - label->getContentSize().width, pos_y)); auto res = MoveTo::create(0.0f, init_pos); auto seq = RepeatForever::create(Sequence::create(move, res, nullptr)); label->runAction(seq); // クリッピングマスク用のテクスチャ作成 // NOTE:addChildしないものはretainする auto render_tex = RenderTexture::create(layer_size.width, layer_size.height); render_tex->retain(); { render_tex->begin(); // 表示しない領域(透明画像) auto invisible = Sprite::create(); invisible->setTextureRect(Rect(0.0f ,0.0f ,layer_size.width, font_size)); invisible->setColor(Color3B::GREEN); invisible->setOpacity(0); invisible->setPosition(layer_size.width/2, layer_size.height/2); invisible->retain(); // 表示する領域(黒) auto visible = Sprite::create(); visible->setTextureRect(Rect(0.0f ,0.0f ,layer_size.width/4, font_size)); visible->setColor(Color3B::BLACK); visible->setPosition(layer_size.width/2, layer_size.height/2); visible->retain(); // render_texに焼き付ける invisible->visit(); visible->visit(); render_tex->end(); } // 生成したテクスチャでスプライト作成 auto stencil = Sprite::createWithTexture(render_tex->getSprite()->getTexture()); stencil->setPosition(layer_size.width/2, pos_y); // クリッピング処理 auto clipping = ClippingNode::create(); clipping->setAnchorPoint(Vec2(0, 0)); clipping->setPosition(0, 0); // くり抜く設定 clipping->setStencil(stencil); clipping->setInverted(false); // 変数visibleの部分を可視化する clipping->setAlphaThreshold(0.01f); // クリッピングして表示したいもの clipping->addChild(label); this->addChild(clipping, 100); } |
こちらのようにクリッピングされるかと思います。
ちなみにAndroidではクリッピング処理がうまくいかない場合があるようですので、下記のサイトを参考にさせていただきました。
cocos2dxのClippingNodeが変になったときの対処(for android) (。・ω・。)
ハマケン100%開発: cocos2d-x Androidプロジェクトの場合はStencilバッファを明示的に有効化しておかないとクリッピングできない事がある
以上です。
■参考リンク
Clipping
スプライトのマスク処理(Cocos Code IDE, Lua言語)
chroot – cocos2dx3.0 スポットライトみたいなのを作る
Cocos2dx 3.0でクリッピングマスクの実現
RenderTexture
ladywendy – Cocos2d-x:動的にテクスチャを作成
【Cocos2d-x 3.x】複数の画像を1枚のSpriteに合成する