How to make CCFollow follow the mouse and move camera with mouse?

How to make CCFollow follow the mouse and move camera with mouse?

1 - How to make like angrybirds, move around scene using mouse with cocos2d-x?
2 - How to make CCFollow, follow the mousejoint, and where i drag the physicsprite the camera follow it.

When you drag the physicsprite, you can get the position and use “CCMoveTo” to move current layer

But i dont understand it. If i move the current layer and i have only one layer, it go out of screen. Im using the HelloCpp project that come with cocos2d-x.

I made:

CCMoveTo* action = CCMoveTo::create(1.0f, selectedObject->getBodyPosition());
runAction(action);

Nothing happen. When i debug the property endPosition of action change when i move the object, but the camera stay on the same place :frowning:

you should move current layer with opposite position,
@
CCMoveTo* action = CCMoveTo::create(1.0f, ccpMult(selectedObject~~>getBodyPosition,~~1));
runAction(action);
@

Nothing happen with this. Look my code:

#include "HelloWorldScene.h"

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer, 1);

    // return the scene
    return scene;
}

bool HelloWorld::init()
{
    CCLOG("INIT GAME");

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

    setTouchEnabled(true);

    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    createBox2DWorld();

    layerBackground = CCLayer::create();
    CCSprite *backgroundSprite = CCSprite::create("backgroundGame.png");
    backgroundSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    layerBackground->addChild(backgroundSprite, 0);
    addChild(layerBackground, 0);

    /*
    char1Sprite = CCSprite::create("character1.png");
    char1Sprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    addChild(char1Sprite);

    int num = 3;
    b2Vec2 verts[] = {
        b2Vec2(60.0f / PTM_RATIO, 0.0f / PTM_RATIO),
        b2Vec2(32.0f / PTM_RATIO, 75.0f / PTM_RATIO),
        b2Vec2(0.0f / PTM_RATIO, 0.0f / PTM_RATIO)
    };

    createBox2DBodyForSprite(char1Sprite, num, verts); 
    */

    for(int x = 1; x <= 7; x++)
    {   
        //std::string textureName = "character" + Util::intToString(x) + ".png";
        std::string textureName = "object" + Util::intToString(x) + ".png";
        CCSprite *charTexture = CCSprite::create(textureName.c_str());
        CCSize charSize = charTexture->getContentSize();

        PhysicsSprite *charPhysicsSprite = new PhysicsSprite();
        charPhysicsSprite->initWithTexture(charTexture->getTexture(), CCRectMake(0, 0, charSize.width, charSize.height));

        CCPoint p = ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y);

        // Define the dynamic body.
        //Set up a 1m squared box in the physics world
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);

        b2Body *body = world->CreateBody(&bodyDef);

        b2PolygonShape dynamicBox;
        dynamicBox.SetAsBox(charSize.width/PTM_RATIO/2, charSize.height/PTM_RATIO/2);

        // Define the dynamic body fixture.
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &dynamicBox;    
        fixtureDef.density = 0.5f;
        fixtureDef.friction = 0.2f;
        body->CreateFixture(&fixtureDef);

        charPhysicsSprite->setPhysicsBody(body);

        addChild(charPhysicsSprite);
    }

    addCheckPoints();
    createObjects();
    scheduleUpdate();

    return true;
}

void HelloWorld::createObjects()
{
    // selected and camera object
    //selectedObject = new PhysicsSprite();
    //cameraObject = CCSprite::create();
    //cameraObject->retain();

    //CCFollow* actionFollow = CCFollow::create(cameraObject, CCRect::CCRect(0.0f, 0.0f, 20000.0f, 20000.0f));
    //runAction(actionFollow);
}

void HelloWorld::addCheckPoints()
{
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    std::string textureName = "checkpoint1.png";
    CCSprite *charTexture = CCSprite::create(textureName.c_str());
    CCSize charSize = charTexture->getContentSize();

    selectedObject = new PhysicsSprite();
    selectedObject->initWithTexture(charTexture->getTexture(), CCRectMake(0, 0, charSize.width, charSize.height));

    CCPoint p = ccp(240, 180);

    // Define the dynamic body.
    //Set up a 1m squared box in the physics world
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);

    b2Body *body = world->CreateBody(&bodyDef);

    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(charSize.width/PTM_RATIO/2, charSize.height/PTM_RATIO/2);

    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 0.5f;
    fixtureDef.friction = 0.2f;
    body->CreateFixture(&fixtureDef);

    selectedObject->setPhysicsBody(body);

    addChild(selectedObject);
}

void HelloWorld::createBox2DWorld()
{
    // create world
    b2Vec2 gravity;
    gravity.Set(0.0f, -10.0f);
    world = new b2World(gravity);
    world->SetAllowSleeping(true);
    world->SetContinuousPhysics(true);    

    // m_debugDraw = new GLESDebugDraw( PTM_RATIO );
    // world->SetDebugDraw(m_debugDraw);

    uint32 flags = 0;
    flags += b2Draw::e_shapeBit;
    //        flags += b2Draw::e_jointBit;
    //        flags += b2Draw::e_aabbBit;
    //        flags += b2Draw::e_pairBit;
    //        flags += b2Draw::e_centerOfMassBit;
    //m_debugDraw->SetFlags(flags);


    // Define the ground body.
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0, 0); // bottom-left corner

    // Call the body factory which allocates memory for the ground body
    // from a pool and creates the ground box shape (also from a pool).
    // The body is also added to the world.
    b2Body* groundBody = world->CreateBody(&groundBodyDef);

    // Define the ground box shape.
    b2EdgeShape groundBox;

    // bottom
    groundBox.Set(b2Vec2(VisibleRect::leftBottom().x/PTM_RATIO,VisibleRect::leftBottom().y/PTM_RATIO), b2Vec2(VisibleRect::rightBottom().x/PTM_RATIO,VisibleRect::rightBottom().y/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

    /*
    // top
    groundBox.Set(b2Vec2(VisibleRect::leftTop().x/PTM_RATIO,VisibleRect::leftTop().y/PTM_RATIO), b2Vec2(VisibleRect::rightTop().x/PTM_RATIO,VisibleRect::rightTop().y/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

    // left
    groundBox.Set(b2Vec2(VisibleRect::leftTop().x/PTM_RATIO,VisibleRect::leftTop().y/PTM_RATIO), b2Vec2(VisibleRect::leftBottom().x/PTM_RATIO,VisibleRect::leftBottom().y/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

    // right
    groundBox.Set(b2Vec2(VisibleRect::rightBottom().x/PTM_RATIO,VisibleRect::rightBottom().y/PTM_RATIO), b2Vec2(VisibleRect::rightTop().x/PTM_RATIO,VisibleRect::rightTop().y/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    */

    // create contact listener
    contactListener = new ContactListener();
    world->SetContactListener(contactListener);   
}


void HelloWorld::updateBox2DWorld(float dt)
{
    CCLOG("BODY2D COUNT: %i", world->GetBodyCount());

    int velocityIterations = 8;
    int positionIterations = 1;
    world->Step(dt, velocityIterations, positionIterations);

    for(b2Body *b = world->GetBodyList(); b; b=b->GetNext()) 
    {
        if (b->GetUserData() != NULL) 
        {   
            CCSprite *entity = (CCSprite*)b->GetUserData();

            CCPoint Pos = entity->getPosition();
            b2Vec2 b2Position = b2Vec2(Pos.x/PTM_RATIO, Pos.y/PTM_RATIO);
            float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(entity->getRotation());

            b->SetTransform(b2Position, b2Angle);
        }
    }

    std::vectortoDestroy; 
    std::vector::iterator pos;
    for(pos = contactListener->_contacts.begin(); pos != contactListener->_contacts.end(); ++pos) 
    {
        ContactData contact = *pos;

        // Get the box2d bodies for each object
        b2Body *bodyA = contact.fixtureA->GetBody();
        b2Body *bodyB = contact.fixtureB->GetBody();

        if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) 
        {
            //CCSprite *spriteA = (CCSprite*)bodyA->GetUserData();
            //CCSprite *spriteB = (CCSprite*)bodyB->GetUserData();

            //int iTagA = spriteA->getTag();
            //int iTagB = spriteB->getTag();

            // Is sprite A a cat and sprite B a car?  If so, push the cat on a list to be destroyed...
            /*
            if (iTagA == 1 && iTagB == 2)
                toDestroy.push_back(bodyA);
            // Is sprite A a car and sprite B a cat?  If so, push the cat on a list to be destroyed...
            else if (iTagA == 2 && iTagB == 1) 
                toDestroy.push_back(bodyB);


            or


            if (iTagA == GameObjects::TAG_PLAYER && iTagB == GameObjects::TAG_COIN)
            {
                Coin *coin = (Coin*)spriteB;
                GameObjects::points += coin->getPoints();
                updatePoints();

                toDestroy.push_back(bodyB);
            }    
            */
        }        
    }

    // Loop through all of the box2d bodies we wnat to destroy...
    std::vector::iterator pos2;
    for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) 
    {
        b2Body *body = *pos2;     

        // See if there's any user data attached to the Box2D body
        // There should be, since we set it in addBoxBodyForSprite
        if (body->GetUserData() != NULL) 
        {

            // We know that the user data is a sprite since we set
            // it that way, so cast it...
            CCSprite *entity = (CCSprite*)body->GetUserData();
            removeChild(entity, true);

            // Remove the sprite from the scene
            //[_spriteSheet removeChild:sprite cleanup:YES];
            //sprite->removeFromParentAndCleanup(true);
            //m_spriteSheet->removeChild( sprite, true );
        }

        // Destroy the Box2D body as well
        world->DestroyBody(body);
    }

    // If we've destroyed anything, play an amusing and malicious sound effect!  ;]
    if (toDestroy.size() > 0) 
    {
        //CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect( "cat_ouch.wav" );
    } 
}

void HelloWorld::createBox2DBodyForSprite(CCSprite *entity, int iNumVerts, b2Vec2 verts[])
{ 
    if(world==NULL)
    {
        return;
    }

    CCPoint pos = entity->getPosition();
    CCSize size = entity->getContentSize();

    b2BodyDef spriteBodyDef;
    spriteBodyDef.type = b2_dynamicBody;
    spriteBodyDef.position.Set(pos.x/PTM_RATIO, pos.y/PTM_RATIO);
    spriteBodyDef.userData = entity;
    b2Body *spriteBody = world->CreateBody(&spriteBodyDef);

    b2PolygonShape spriteShape;

    if( iNumVerts!=0 )
    {
        spriteShape.Set(verts, iNumVerts);
        b2FixtureDef spriteShapeDef;
        spriteShapeDef.shape = &spriteShape;
        spriteShapeDef.density = 10.0;
        spriteShapeDef.isSensor = false;

        spriteBody->CreateFixture(&spriteShapeDef);
    }
    else
    {
        // No Vertice supplied so just make a box round the sprite
        b2BodyDef spriteBodyDef;
        spriteBodyDef.type = b2_dynamicBody;
        spriteBodyDef.position.Set( pos.x/PTM_RATIO, pos.y/PTM_RATIO );
        spriteBodyDef.userData = entity;
        b2Body *spriteBody = world->CreateBody( &spriteBodyDef );

        b2PolygonShape spriteShape;
        spriteShape.SetAsBox( size.width/PTM_RATIO/2, size.height/PTM_RATIO/2 );
        b2FixtureDef spriteShapeDef;
        spriteShapeDef.shape = &spriteShape;
        spriteShapeDef.density = 10.0;
        spriteShapeDef.isSensor = true; // isSensor true when you want to know when objects will collide without triggering a box2d collision response
        spriteBody->CreateFixture( &spriteShapeDef );
    }
}

void HelloWorld::update(float dt)
{
    CCLOG("UPDATE GAME");

    updateBox2DWorld(dt);
    updateCamera(dt);    
}

void HelloWorld::updateCamera(float dt)
{
    CCLOG("UPDATE CAMERA");

    if (selectedObject)
    {
        //cameraObject->setPosition(selectedObject->getBodyPosition());
        //cameraObject->setPosition(selectedObject->getBodyPosition());
    }

    CCMoveTo* action = CCMoveTo::create(1.0f, ccpMult(selectedObject->getBodyPosition(), -1));
    runAction(action);


    //setPosition(selectedObject->getBodyPosition());

    /*
    CCFollow* actionFollow = CCFollow::create(selectedObject, CCRect::CCRect(0.0f, 0.0f, 20000.0f, 20000.0f));
    runAction(actionFollow);
    */

    /*
    stopAllActions();

    CCPoint position = CCPoint(selectedObject->getPhysicsBody()->GetPosition().x * PTM_RATIO, selectedObject->getPhysicsBody()->GetPosition().y * PTM_RATIO);

    CCNode *node = CCNode::create();
    node->setPosition(position);

    CCFollow* pFollowA = CCFollow::create(node, CCRect::CCRect(0.0f, 0.0f, 2000, CCDirector::sharedDirector()->getWinSizeInPixels().height));
    runAction(pFollowA);
    */
    /*

     // Bullet is moving.
     if (m_bulletBody && m_bulletJoint == NULL)
     {
     b2Vec2 position = m_bulletBody->GetPosition();
     CCPoint myPosition = this->getPosition();
     CCSize screenSize = CCDirector::sharedDirector()->getWinSize();

     // Move the camera.
     if (position.x > screenSize.width / 2.0f / PTM_RATIO)
     {
     myPosition.x = -MIN(screenSize.width * 2.0f - screenSize.width, position.x * PTM_RATIO - screenSize.width / 2.0f);
     this->setPosition(myPosition);

     */

    //b2Vec2 myPositionB = char1Sprite->getPhysicsBody()->GetPosition();
    //CCPoint myPosition = CCPoint(myPositionB.x * PTM_RATIO, myPositionB.y * PTM_RATIO);
    //setPosition(myPosition);
}