SetFlippedX not work after SetDisplayFrame and position wrong

I just changed my project from 2.2.6 to 3.8.1 this week, some problem happened.
at 2.2.6, I used setFlipX() after I create sprite by SpriteBatchNode::create(), and the sprite work fine after I change the texture by setDisplayFrame()
on 3.8.1 I changed setFlipX() to setFlippedX(), but flip not working after I call the setDisplayFrame(), I fix this problem in a oddly way like below…

if(sprite.isFlippedX() == true)
{
sprite.setFlippedX( false );
}
sprite.setDisplayFrame( newFrame );
if(sprite.isFlippedX() == false)
{
sprite.setFlippedX( true );
}

But, another problem happen, my Frame have several different size, at 2.2.6 sprite will draw on center position (I didn’t change anchor), but now, sprite will draw on different X depend on the width of frame…

Should I give up the BatchNode ?

Not certain why you are seeing the issues you described.
But in 3.x there is auto batching, so the SpriteBatchNode is not really needed.

Here is the code I changed the cpp-tests project’s “SpriteBatchNodeFlip” sample for report the issues.
Strong word is where I changed or added.

SpriteTest.h

class SpriteBatchNodeFlip : public SpriteTestDemo
{
int no;
public:
CREATE_FUNC(SpriteBatchNodeFlip);
SpriteBatchNodeFlip();
void flipSprites(float dt);
virtual std::string title() const override;
virtual std::string subtitle() const override;
};

SpriteTest.cpp

//------------------------------------------------------------------
//
// SpriteBatchNodeFlip
//
//------------------------------------------------------------------
SpriteBatchNodeFlip::SpriteBatchNodeFlip()
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(“Images/blocks9ss.plist”);

auto batch = SpriteBatchNode::create(“Images/blocks9ss.png”, 10);
addChild(batch, 0, kTagSpriteBatchNode);

auto s = Director::getInstance()->getWinSize();

auto sprite1 = Sprite::createWithSpriteFrameName(“grossini_dance_01.png”);
sprite1->setPosition( Vec2( s.width/2 - 100, s.height/2 ) );
batch->addChild(sprite1, 0, kTagSprite1);

auto sprite2 = Sprite::createWithSpriteFrameName(“grossini_dance_01.png”);
sprite2->setPosition( Vec2( s.width/2 + 100, s.height/2 ) );
batch->addChild(sprite2, 0, kTagSprite2);

no = 0;

CCLOG(“Pre: %f”, sprite1->getContentSize().height);
sprite1->setFlippedX( true );
sprite2->setFlippedX( false );
CCLOG(“Post: %f”, sprite1->getContentSize().height);

schedule(CC_CALLBACK_1(SpriteBatchNodeFlip::flipSprites, this), 1, “flip_sprites_key”);
}

void SpriteBatchNodeFlip::flipSprites(float dt)
{
auto batch= static_cast<SpriteBatchNode*>(getChildByTag( kTagSpriteBatchNode ));
auto sprite1 = static_cast<Sprite*>(batch->getChildByTag(kTagSprite1));
auto sprite2 = static_cast<Sprite*>(batch->getChildByTag(kTagSprite2));

char ResourceName[291];
sprintf(ResourceName, “grossini_dance_%02d.png”, no+1);

no++;
if(no==3) no=0;

*SpriteFrame FrameRole = SpriteFrameCache::getInstance()->getSpriteFrameByName(ResourceName);
sprite1->setSpriteFrame(FrameRole);
sprite2->setSpriteFrame(FrameRole);
}

The code is simple, I just draw 2 sprite with same FrameCache, sprite #1 on left set flip X ‘true’, sprite #2 on the right set flip X ‘false’, and do the same thing in flipSprites(), just call setSpriteFrame() to change the SpriteFrame of sprite #1 & #2 every time.

run the cpp-tests, 46.Node:Sprite ->38:Testing SpriteBatchNode, And you will see the left Sprite#1’s position is change every time, but Sprite#2 is OK.

And if you look more carefully, you will see the Sprite#1’s flip X only work on first time, after setSpriteFrame() the flip X not work anymore.

That is what I mean.