Parallax Scrolling
Parallax Scrolling là hiện tượng được tạo ra bởi mắt của người nhìn so với các vật thể xa, gần khác nhau. Vật nào ở càng xa (so với mắt) thì góc nhìn càng nhỏ, vật nào ở gần thì góc nhìn càng rộng. Khi 2 vật di chuyển cùng vận tốc thì vật ở xa (có vẻ) di chuyển chậm hơn vật ở gần.
Trong cuộc sống hằng ngày, Parallax Ccrolling rất hay được bắt gặp. Ví dụ khi đang đi xe trên đường, nếu quan sát sẽ dễ dàng thấy rằng các cột điện trên đường di chuyển rất nhanh so với ngọn núi ở xa hơn, và ngọn núi sẽ di chuyển nhanh hơn mặt trời. Hay khi đứng nhìn 2 tòa nhà (kích thước ngang nhau) trước mắt, thì tòa nhà ở xa nhìn sẽ nhỏ hơn tòa nhà ở gần.
Hiệu ứng Parallax Scrolling được dùng trong game 2D nhằm tạo chiều sâu cho game.
Hiện thực
Ảnh minh họa:
Tạo class InfiniteParallaxNode
Hiện thực file file InfiniteParallaxNode.h
class InfiniteParallaxNode :public ParallaxNode { public: static InfiniteParallaxNode* create(); void updatePosition(); };
Hiện thực file file InfiniteParallaxNode.cpp
Method create
InfiniteParallaxNode* InfiniteParallaxNode::create() { InfiniteParallaxNode* node = new InfiniteParallaxNode(); if (node) { node->autorelease(); } else { delete node; node = 0; } return node; }
Method updatePossition
void InfiniteParallaxNode::updatePosition() { int safeOffset = -10; Size visibleSize = Director::getInstance()->getVisibleSize(); for (int i = 0; i < _children.size(); i++) { auto node = _children.at(i); if (convertToWorldSpace(node->getPosition()).x + node->getContentSize().width < safeOffset) { for (int j = 0; j < _parallaxArray->num; j++) { auto po = (PointObject*)_parallaxArray->arr[j]; if (po->getChild() == node) po->setOffset(po->getOffset() + Point(visibleSize.width + node->getContentSize().width, 0)); } } } }
Ở đầu file khởi tạo thêm 1 class PointObject như sau:
class PointObject : public Ref { public: inline void setRation(Point ratio) { _ratio = ratio; } inline void setOffset(Point offset) { _offset = offset; } inline void setChild(Node *var) { _child = var; } inline Point getOffset() const { return _offset; } inline Node* getChild() const { return _child; } private: Point _ratio; Point _offset; Node* _child; };
Cách dùng
Khai báo và khởi tạo biến
InfiniteParallaxNode* backgroundElements; backgroundElements = InfiniteParallaxNode::create();
Thêm các đối tượng vào
// add rock unsigned int rocksQuantity = 7; for (unsigned int i = 0; i < rocksQuantity; i++) { auto rock = Sprite::create("rock.png"); rock->setAnchorPoint(Point::ZERO); rock->setScale(randomValueBetween(0.6, 0.75)); backgroundElements->addChild(rock, randomValueBetween(-10, -6), Point(0.05, 1), Point((visibleSize.width / 5) * (i + 1) + randomValueBetween(0, 100), ground->getContentSize().height - 5)); } // add tree unsigned int treesQuantity = 35; for (unsigned int i = 0; i < treesQuantity; i++) { auto tree = Sprite::create("tree.png"); tree->setAnchorPoint(Point::ZERO); tree->setScale(randomValueBetween(0.5, 0.75)); backgroundElements->addChild( tree, randomValueBetween(-5, -1), Point(0.5, 1), Point(visibleSize.width / (treesQuantity - 5) * (i + 1) + randomValueBetween(25, 50), ground->getContentSize().height - 8)); }
Thêm parallax vào và update scene
addChild(backgroundElements, 2); schedule(schedule_selector(HelloWorld::update), 0.01);