在cocos2d中滚动背景时,对象是否保持固定

时间:2011-01-02 13:16:41

标签: cocos2d-iphone

当无限背景滚动完成时,我有一个问题,对象是否保持固定(如涂鸦跳转中的涂鸦,papi跳跃中的papy)或这些对象真正移动。只有背景移动或两者(背景和对象)移动。 PLZ有人帮我。我正在寻找这个解决方案4/5天,但无法得到解决方案。所以有人帮助我。如果对象不移动如何创建这样一个对象移动的错觉。

2 个答案:

答案 0 :(得分:1)

如果将对象添加到与滚动背景相同的图层,则它将在背景滚动时滚动。

如果你在涂鸦中寻找像英雄一样的效果,你可能想要看一下场景中有两层或更多层。

  1. 第1层:滚动背景图层
  2. 第2层:精灵层
  3. SomeScene.m

    CCLayer *backgroundLayer = [[CCLayer alloc] init];
    CCLayer *spriteLayer= [[CCLayer alloc] init];
    
    [self addChild:backgroundLayer z:0];
    [self addChild:spriteLayer z:1];
    
    //Hero stays in one spot regardless of background scrolling.
    CCSprite *squidHero = [[CCSprite alloc] initWithFile:@"squid.png"];
    [spriteLayer addChild:squidHero]; 
    

    如果您希望对象以背景滚动,请将其添加到背景图层:

    //Platform moves with background.
    CCSprite *bouncePlatform= [[CCSprite alloc] initWithFile:@"bouncePlatform.png"];
    [backgroundLayer addChild:bouncePlatform]; 
    

答案 1 :(得分:0)

另一种方法是使用CCFollow操作。你会编写代码,好像背景是静态的(它将是)并且玩家正在移动(它将会移动),但是向玩家添加CCFollow动作。这基本上会移动相机,以便跟踪您的播放器。

你也可以修改这些类,这样你就可以得到CCFollow动作跟随一个偏移(即,所以玩家不在屏幕中间)以及对它有平滑效果,这样当玩家移动时,跟随动作不是生涩的。请参阅以下代码:

*注意我使用的是cocos2d-x,即c ++端口。 cocos2d中的方法类似,您应该能够修改这些方法以适应cocos2d语法。或者四处搜索 - 我发现了这些用于cocos2d,然后移植到c ++。

//defines the action to constantly follow the player (in my case, "runner.p_sprite is the sprite pointing to the player)
FollowWithOffset* followAction = FollowWithOffset::create(runner.p_sprite, CCRectZero);
runAction(followAction);

另外,我已经复制了CCFollow的类定义来创建我自己的类CCFollowWithAction。这也有平滑效果(你可以在网上查看更多),这样当玩家移动时,动作不会生涩。我修改了“initWithTarget”以考虑偏移量,并修改了“步骤”以添加平滑动作。您可以在下面的评论中看到修改。

bool FollowWithOffset::initWithTarget(CCNode *pFollowedNode, const CCRect& rect/* = CCRectZero*/)
{
    CCAssert(pFollowedNode != NULL, "");

    pFollowedNode->retain();
    m_pobFollowedNode = pFollowedNode;
    if (rect.equals(CCRectZero))
    {
        m_bBoundarySet = false;
    }
    else
    {
        m_bBoundarySet = true;
    }

    m_bBoundaryFullyCovered = false;

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    m_obFullScreenSize = CCPointMake(winSize.width, winSize.height);

    //m_obHalfScreenSize = ccpMult(m_obFullScreenSize, 0.5f);
    m_obHalfScreenSize = CCPointMake(m_obFullScreenSize.x/2 + RUNNER_FOLLOW_OFFSET_X,
                                     m_obFullScreenSize.y/2 + RUNNER_FOLLOW_OFFSET_Y);

    if (m_bBoundarySet)
    {
        m_fLeftBoundary = -((rect.origin.x+rect.size.width) - m_obFullScreenSize.x);
        m_fRightBoundary = -rect.origin.x ;
        m_fTopBoundary = -rect.origin.y;
        m_fBottomBoundary = -((rect.origin.y+rect.size.height) - m_obFullScreenSize.y);

        if(m_fRightBoundary < m_fLeftBoundary)
        {
            // screen width is larger than world's boundary width
            //set both in the middle of the world
            m_fRightBoundary = m_fLeftBoundary = (m_fLeftBoundary + m_fRightBoundary) / 2;
        }
        if(m_fTopBoundary < m_fBottomBoundary)
        {
            // screen width is larger than world's boundary width
            //set both in the middle of the world
            m_fTopBoundary = m_fBottomBoundary = (m_fTopBoundary + m_fBottomBoundary) / 2;
        }

        if( (m_fTopBoundary == m_fBottomBoundary) && (m_fLeftBoundary == m_fRightBoundary) )
        {
            m_bBoundaryFullyCovered = true;
        }
    }

    return true;
}

void FollowWithOffset::step(float dt)
{
    CC_UNUSED_PARAM(dt);

    if(m_bBoundarySet){
        // whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
        if(m_bBoundaryFullyCovered)
            return;

        CCPoint tempPos = ccpSub( m_obHalfScreenSize, m_pobFollowedNode->getPosition());

        m_pTarget->setPosition(ccp(clampf(tempPos.x, m_fLeftBoundary, m_fRightBoundary), 
                                   clampf(tempPos.y, m_fBottomBoundary, m_fTopBoundary)));
    }
    else{
        //custom written code to add in support for a smooth ccfollow action
        CCPoint tempPos = ccpSub( m_obHalfScreenSize, m_pobFollowedNode->getPosition());
        CCPoint moveVect = ccpMult(ccpSub(tempPos,m_pTarget->getPosition()),0.25); //0.25 is the smooth constant.
        CCPoint newPos = ccpAdd(m_pTarget->getPosition(), moveVect);
        m_pTarget->setPosition(newPos);
    }
}