[SOLVED] - "CCSprite is not using the same texture id"

I got a problem while using SpriteBatchNode. I’m developing SpaceShip game myself, I create a ship (base on Sprite class) in MissionScene class by using SpriteBatchNode, and it run perfectly.

 void MissionScene::createPlayerShip(){
	
        auto shipBatch = SpriteBatchNode::create("PlayerShip.png", 40);
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("PlayerShip.plist");

	Vector<SpriteFrame*> shipFrame;
	for (int i = 0; i < 30; i++){
		char name[32] = { 0 };
		sprintf(name, "PlayerShip%d.png", i);
		shipFrame.reserve(30);
		shipFrame.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName(name));
	}

	auto animation = Animation::createWithSpriteFrames(shipFrame, 0.1f);
	auto animate = Animate::create(animation);

	auto ship = Sprite::createWithSpriteFrameName("PlayerShip0.png");

	auto repeatAnimate = RepeatForever::create(animate);

	ship->runAction(repeatAnimate);
	
	this->addChild(shipBatch);
	
	shipBatch->addChild(ship);

}

but then, When I create a ship base on Ship class, it said "“CCSprite is not using the same texture id”

Here is the Ship class:

#include "Ship.h"

using namespace cocos2d::ui;

static bool shipToFrameCache = false;

Ship* Ship::createShip(float startX, float startY){

	if (!shipToFrameCache){
		SpriteFrameCache::getInstance()->addSpriteFramesWithFile("PlayerShip.plist");
		shipToFrameCache = true;
	}

	auto ship = Ship::create();

	ship->setPosition(startX, startY);

	return ship;
}


bool Ship::init(){

	if (!Sprite::init()){
		return false;
	}

	Vector<SpriteFrame*> shipFrame;
	for (int i = 0; i < 30; i++){
		char name[32] = { 0 };
		sprintf(name, "PlayerShip%d.png", i);
		shipFrame.reserve(30);
		shipFrame.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName(name));
	}

	auto animation = Animation::createWithSpriteFrames(shipFrame, 0.1f);
	auto animate = Animate::create(animation);

	this->createWithSpriteFrameName("PlayerShip0.png");
	
	auto repeatAnimate = RepeatForever::create(animate);

	this->runAction(repeatAnimate);

	return true;
}

and back in MissionScene class

    void MissionScene::createPlayerShip(){
    	
    	auto shipBatch = SpriteBatchNode::create("PlayerShip.png", 40);
    	auto ship = Ship::createShip(320,-50);

    	this->addChild(shipBatch);
    	shipBatch->addChild(ship);
  
    }

and now when I run the game, it said “CCSprite is not using the same texture id”.
Please help me…I have spent a lot hours finding the cause but nothing…

[SOLVED]

To fix this error, I have to add one more line before adding ship to shipBatch

ship ->setTexture(shipBatch->getTexture());

The obvious thing to check, would be that PlayerShip.png, and all the numbered variants, ARE all on the same texture atlas?

@farproc: The problem is here…I have checked by getting the texture of the ship and the SpriteBatchNote to compare , it totally matched !

This is how I checked their textures, you see the texure of shipFrom_Sprite_Class is the same as the texture of shipBatch - but not the same as the texture of shipFrom_Ship_Class

and this is code of Ship class.

The problem is I don’t know how different they are ? Why don’t they have the same texture although they are created by the same way !

Well, if you have created a SpriteSheet for your application in Cocos Studio - or in Texture Packer - you should have a .plist file in your Resources folder.

Then, in your application initialization code, before you create any Ships - you would have a line like:

cocos2d::SpriteFrameCache::getInstance()->addSpriteFramesWithFile("ShipsSpriteSheet.plist");

Then delete the PlayerShip*.png files from your Resources folder to make sure the sprite sheet is being used.

If I delete the PlayerShip.png files from my Resources folder, I can’t create a SpriteBatchNode like

auto shipBatch = SpriteBatchNode::create("PlayerShip.png", 40);

and can’t add ship to shipBatch to draw on scene. People said that using SpriteBatchNode to increase graphic perfomance…so I want to use SpriteBatchNode in this case too.

To use the SpriteBatchNode, all the sprites being batched need to share the same texture. This requires you to use a tool like TexturePacker, or Cocos Studio, to create a SpriteSheet and add the individual png images to that.

You then copy the SpriteSheet (.png and .plist) files to your projects resources folder in place of the individual .png files you had previously, and register the sprite sheet with the sprite frame cache before creating any sprites.

With this done, “PlayerShip.png” and “PlayerShip1.png” do not represent individual .png files, but two rectangles on the single texture that was loaded from SpriteSheet.png.

If you still need the individual png files after creating the sprite sheet then the sprite sheet has not been created properly, or you are using one of the overloaded sprite creation functions that does not use the SpriteFrameCache. So, rather than calling SpriteBatchNode::create and passing the image name, perhaps first get the image as a SpriteFrame* from the SpriteFrameCache, and use the ::create overload that takes a SpriteFrame*.

@farproc thank you so much for your help, in order to solve this problem, I have to add one more line before adding the ship to the SpriteBatchNode.

shipFrom_Ship_Class->setTexture(shipBatch->getTexture());