当无限背景滚动完成时,我有一个问题,对象是否保持固定(如涂鸦跳转中的涂鸦,papi跳跃中的papy)或这些对象真正移动。只有背景移动或两者(背景和对象)移动。 PLZ有人帮我。我正在寻找这个解决方案4/5天,但无法得到解决方案。所以有人帮助我。如果对象不移动如何创建这样一个对象移动的错觉。
答案 0 :(得分:1)
如果将对象添加到与滚动背景相同的图层,则它将在背景滚动时滚动。
如果你在涂鸦中寻找像英雄一样的效果,你可能想要看一下场景中有两层或更多层。
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);
}
}