CCFollow question

I’m just new to using the cocos2d-x engine… But I’ve managed to do the simplegame series…
Now, I’ve been trying to make the background scroll as the player moves and CCFollow did the job… thanks!
But I’ve added a health bar for the player, but it moves with the background…

Is there a way to make it not move with the background? Thanks for helping

Haven’t used CCFollow but I think the best solution is to put the Bckground in a different layer, the player and health bar sprite, in another layer, and the scores, timers, etc in another layer. So you have three child layers in your main layer.

Thanks for the reply… Oh I see… But I still don’t know how to put them on separate layers… :frowning:
I followed the simplegame tutorial… I just put on the sprite on the init of Gameplay.cpp…
Could you please guide me to the right way of doing it? Thanks :slight_smile:

I did it like this…

bool Gameplay::init()
{
do
{
CCSprite* bg = CCSprite::create(“background.png”);
bg~~>setPosition);
addChild;
CCSprite* player = CCSprite::create;
player~~>setPosition(ccp(50,50) );
addChild(player, 1);

CCSprite* bar = CCSprite::create(“hpbar.png”);
bar~~>setPosition );
addChild;
this~~>setTouchEnabled(true);

bRet = true;
} while (0);

return bRet;

}

I would subclass CCLayer and do everything in those subclasses but that’s a bit complicated. So this is something similar:

// Gameplay.H
#include "cocos2d.h"
class Gameplay : public cocos2d::CCLayer {
private:
   // Create child layers
   cocos2d::CCLayer * mPlayerSpriteLayer;
   cocos2d::CCLayer * mBackgroundLayer;

   // Sprites in the game
   cocos2d::CCSprite * mPlayerSprite;
   cocos2d::CCSprite * mBackgroundSprite;
public:
   // Create a method to draw everything on screen so that init( ) is not crowded
   void drawLayer( );

   static cocos2d::CCScene * scene( );
   virtual bool init( );
   LAYER_CREATE_FUNC( Gameplay );
};

// Gameplay.CPP
#include "Gameplay.h"
using namespace cocos2d;
bool Gameplay::init( ) {
   if ( !CCLayer::init( ) ) return false;

   drawLayer( );

   return true;
}

void Gameplay::drawLayer( ) {
   CCSize winSize = CCDirector::shareDirector( ) -> getWinSizeInPixels( );

   mBackgroundLayer = CCLayer::create( );
   mBackgroundLayer -> setPosition( CCPointZero );
   this -> addChild( mBackgroundLayer, 0 ); // Z-index = 0 so that it's in the back

   mPlayerSpriteLayer = CCLayer::create( );
   mPlayerSpriteLayer -> setPosition( CCPointZero );
   this -> addChild( mPlayerSpriteLayer, 1 ); // Z-index > 0 so that it is in front of mBackgroundLayer

   mPlayerSprite = CCSprite::create( "player.png" );
   mPlayerSprite -> setPosition( CCPointMake( 50, 50 ) ); // CCPointMake( x, y ) = ccp( x, y )
   mPlayerSpriteLayer -> addChild( mPlayerSprite );

   mBackgroundSprite = CCSprite::create( "background.png" );
   mBackgroundSprite -> setPosition( CCPointMake( winSize.width * 0.5, winSize.height * 0.5 ) );
   mBackgroundLayer -> addChild( mBackgroundSprite );
}

Hmm… I’ve tried your code… I’ve replaced mine… so I can try the separate layers….
but when I try to move my player, an “unhandled exception” occurs… :frowning:
Well I added some lines at your code… at drawLayer function…

this~~>setTouchEnabled;
and I added some tags with the player and bg so i can access them by my movement code
mPlayerSpriteLayer~~> addChild( mPlayerSprite , 0, playerTag);
mBackgroundLayer > addChild;
my movement code is just like this
void Gameplay::ccTouchesEnded
{
CCSetIterator it = touches
>begin();
CCTouch* touch = (CCTouch*)(*it);
CCPoint location = touch~~>getLocation;
CCNode* s = getChildByTag;
s~~>stopAllActions();
s->runAction( CCMoveTo::create(1, ccp(location.x, location.y) ) );
}

Any ideas? thanks a lot

Oh Yeah! I’ve got it working now![](…
Thanks a lot dude… I’ve learned something new…
All I did before was putting in a single layer…
Separating them is the solution…
Thanks a lot)! :):):slight_smile:

I made a typo, instead of sharedDirector( ), I typed shareDirector( ) you might want to check that part if you copy pasted the code.

Instead of putting setTouchEnabled( ) inside the drawLayer( ) method, put it in the init( ) method after drawLayer( ) has been called and add CCDirector::sharedDirector( ) -> getTouchDelegate( ) -> addTargetedDelegate( this, 0, true ); below it.
Try putting break points inside the drawLayer method to determine where the error takes place.

Anyway, from what I’ve seen, the error is on the line CCNode * s = getChildByTag( playerTag );. You are calling the getChildByTag( ) method inside the Gameplay layer and not in the mPlayerSpriteLayer layer. mPlayerSprite is not a child of Gameplay layer and the app cannot find it in that layer.

An analogy: You have three drawers labeled “Garments”, “Underwear”, and “Socks”. Garments is a large drawer containing two smaller drawers, Underwear and Socks You told your kid to get a pair of socks inside the “Garments” drawer. However, there are no socks in the “”Garments" drawer and the kid will not look for the sock inside he other drawers because you told the kid to look for the sock in the “Garments” drawer. So the kid comes back saying he didn’t find it on the “Garments” drawer. Since you know where the socks are, you should tell the kid to look for the socks inside the Socks drawer instead.

Try changing it to mPlayerSpriteLayer -> getChildyTag( playerTag ); because that’s where you added the mPlayerSprite object.

EDIT: Ninja’d but good for you. Always glad to help. :smiley: