Реализация параллакса на оси Z в cocos2d-x V3.10
Прошло не так много времени, я использую cocos2d-x. Это весело и довольно легко достать. Но недавно я застрял во время реализации чего-либо. (Это было какое-то время).
Я реализовал Parllax на осях X и Y. Была легкая работа. Но когда я пытаюсь реализовать его на оси Z (представьте себе перспективный вид), я просто не могу.
Пожалуйста, предложите что-нибудь. Объяснение в контексте cocos2d-x будет высоко ценится. Я использую это с C++. Благодарю вас!
1 ответ
Я написал код для бесконечной прокрутки фона по оси Z.
Самый важный совет - где я вычисляю расстояние между фоновыми плитками. Я использую высоту фонового изображения в качестве расстояния между плитками, но сохраняю его, прежде чем вращать спрайт вокруг оси X.
Вот переменные, определенные в заголовочном файле (LevelScene.h):
...
private:
std::vector<Sprite*> mBackgrounds; // background tiles
Layer* mlayer; // main layer where background tiles are in
Camera* mMainCamera; // main camera
int count = 0; // number of tiles that fills distance between camera and its far plane
float height = 1; // this is distance between each tile indeed
...
и файл LevelScene.cpp содержит:
bool LevelsScene::init()
{
if( !Layer::init() )
{
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
auto origin = Director::getInstance()->getVisibleOrigin();
mlayer = Layer::create();
mlayer->setCameraMask( (unsigned short)CameraFlag::USER2 );
addChild( mlayer );
float far = 3500;
mMainCamera = Camera::createPerspective(80, (float)visibleSize.width/visibleSize.height,
1.0, far);
mMainCamera->setCameraFlag(CameraFlag::USER2);
this->addChild(mMainCamera);
auto bg = Sprite::create();
bg->initWithFile("asphalt.png");
//The line below is very important. We use height of image as distance between tiles. We store height before rotating sprite.
height = bg->getBoundingBox().size.height;
bg->setRotation3D( Vec3(-90,0,0) );
bg->setPosition3D( Vec3(visibleSize.width/2,0,-200 ) );
bg->setCameraMask( (unsigned short)CameraFlag::USER2 );
mlayer->addChild( bg );
mMainCamera->setPosition3D(bg->getPosition3D() + Vec3(0,150,300));
mMainCamera->lookAt(bg->getPosition3D()+Vec3(0,100,0), Vec3(0.0,1.0,0.0));
float lastZ = bg->getPositionZ() - height;
count = ceil(far/height) + 2;
mBackgrounds.push_back( bg );
for( int i = 0; i< count; i++ )
{
auto bg = Sprite::create();
bg->initWithFile("asphalt.png");
bg->setRotation3D( Vec3(-90,0,0) );
bg->setPosition3D( Vec3(visibleSize.width/2,0, lastZ) );
bg->setCameraMask( (unsigned short)CameraFlag::USER2 );
mlayer->addChild( bg );
lastZ = bg->getPositionZ() - height;
mBackgrounds.push_back( bg );
}
scheduleUpdate();
return true;
}
void LevelsScene::update(float dt)
{
mMainCamera->setPosition3D( mMainCamera->getPosition3D() +
Vec3( 0, 0, -10) );
for( std::vector<Sprite*>::iterator bgit = mBackgrounds.begin();
bgit != mBackgrounds.end(); bgit++ )
{
Sprite* bg = (Sprite*)*bgit;
if( bg->getPositionZ() > mMainCamera->getPositionZ() )
{
bg->setPositionZ( bg->getPositionZ() - height * count );
}
}
}
надеюсь, это поможет:)