Реализация параллакса по оси Z в cocos2d-x V3.10

Не так давно я использую cocos2d-x. Это весело и довольно легко получить в руки. Но недавно я застрял при реализации чего-то. (Прошло уже некоторое время).

Я реализовал парлакс по осям X и Y. Была легкая работа. Но когда я пытаюсь реализовать это на оси Z (представить вид в перспективе), я просто не могу. >Представьте себе этот вид

Пожалуйста, предложите что-нибудь. Объяснение в контексте cocos2d-x будет высоко оценено. Я использую его с С++. Спасибо !


person Vineet    schedule 30.06.2016    source источник
comment
Боюсь, я просто не могу, это не то, с чем мы можем вам помочь. Где ты застрял? Что вы пробовали?   -  person nvoigt    schedule 05.07.2016
comment
Я пытаюсь реализовать это, но между ними есть промежутки, которые невозможно восстановить.   -  person Vineet    schedule 06.07.2016
comment
Я тоже попробовал камеру. Но создается 2 представления. Я не знаю, как какой-нибудь мотыге заставить камеру по умолчанию исчезнуть   -  person Vineet    schedule 06.07.2016


Ответы (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 );
       }
   }
}

надеюсь, что это поможет :)

person Meysam Mohammadi    schedule 07.07.2016