При прокрутке фона в cocos2d объект остается зафиксированным - PullRequest
0 голосов
/ 02 января 2011

У меня есть один вопрос, когда бесконечная фоновая прокрутка выполняется, остается ли объект неподвижным (например, каракули в прыжке в каракули, папа в прыжке в папу) или этот объект действительно движется. Пожалуйста, кто-нибудь, помогите мне. Я ищу это решение в течение 4/5 дней, но не могу найти решение. И если объект не движется, как создать такую ​​иллюзию движения объекта.

Ответы [ 2 ]

1 голос
/ 02 января 2011

Если вы добавите объект в тот же слой, что и фон прокрутки, он будет прокручиваться при прокрутке фона.

Если вы ищете эффект, подобный герою в каракули прыжке, вы можете захотеть взглянуть на наличие двух или более слоев в сцене.

  1. Слой 1: прокрутка фона Слой
  2. Слой 2: спрайтовый слой

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]; 
0 голосов
/ 11 марта 2013

Другой альтернативой является использование действия 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, чтобы учесть смещение, и step, чтобы добавить сглаживающее действие. Вы можете увидеть изменения в комментариях ниже.

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...