TiledMapを使わずにSpriteを敷き詰める場合、
描画高速化と継ぎ目を目立たなくする対策としてRenderTextureを使用しているのですが、
以下の条件を満たしているとオフスクリーンの一部の描画がされないケースがありました。
- 一定サイズより大きいRenderTextureを作成する
- タッチイベント内で描画を行う
理屈はよくわかりませんが、再現したのでコードをメモしておきます。
- プロジェクト作成
cocos new cocos-test -p com.test -l cpp
- HelloWorld に onEnter を追加します。
class HelloWorld : public cocos2d::Layer { public: ... + void onEnter(); ... }
- HelloWorld.cpp に下記のコードを追記します。
#define SIZE 64 void HelloWorld::onEnter() { Layer::onEnter(); testRenderTextureBug(); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [=](Touch*, Event*){ testRenderTextureBug(); auto delay = DelayTime::create(2); auto call = CallFunc::create([=]{ this->testRenderTextureBug(); }); runAction(Sequence::create(delay, call, NULL)); return true; }; getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); } void HelloWorld::testRenderTextureBug() { auto tex = RenderTexture::create(SIZE*10, SIZE*10); tex->setPosition(SIZE*2, SIZE*5); tex->beginWithClear(0.3, 0.3, 0.3, 1); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { auto color = Color3B(0, i*16, j*16); auto s = Sprite::create(); s->setTextureRect(Rect(0, 0, SIZE, SIZE)); s->setColor(color); s->getTexture()->setAliasTexParameters(); s->setPosition(j*SIZE, i*SIZE); s->visit(); } } tex->end(); addChild(tex); }
testRenderTextureBug() を呼ぶ度にRenderTextureを生成して重ねます。(下のRenderTextureは見えなくなる)
実行し、画面タッチするとバグの再現を確認できます。
- onEnterで生成すると、正常なRenderTextureが表示される
- 画面タッチイベント内で生成すると、一部欠けたRenderTextureが表示される
- 画面タッチ後のCallFunc内で生成すると、正常なRenderTextureが表示される
この通り、対策としてはCallFuncで生成する事でしょうか。
根が深そうなのでソースコードまでは追っていません。