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で生成する事でしょうか。
根が深そうなのでソースコードまでは追っていません。


