ParallaxNode就是视差节点的意思,这个玩意是干嘛用的呢?当我们面对一个背景画面的时候,如果背景在滚动的时候可以使用这个节点,它的功能就是让子节点拥有不同的移动速率,这样,我们就可以让某一些子节点移动的慢一些,而某些子节点移动的快一些。这样营造出的效果就是远处的景物移动的快,而近处的景物移动的快,给人一种更加真实的感觉。说到它的用法,首先我们需要明确的是这个类是一个node,所以,它就像我们各种各样的node一样,拥有node的特性,它就是一个抽象出来的点,坐标默认是在0,0处。我们需要做的是将需要产生这种移动效果的背景图片添加到这个node上,让这个node移动,然后这些子节点就会以不同的速率去动。其实,它的用法相当简单,可以直接看一下代码。

1 void HelloWorld::menuCloseCallback()
2 {
3     //创建俩张背景图片,添加到ParallaxNode节点上
4     auto bg1 = Sprite::create("HelloWorld.png");
5     bg1->setAnchorPoint(Point(0,0));
6     auto bg2 = Sprite::create("HelloWorld.png");
7     bg2->setAnchorPoint(Point(0,0));
8     //再创建一个精灵好做对比
9     auto sprite = Sprite::create("CloseNormal.png");
10  
11     //ParallaxNode的使用方法如下
12     parallax = ParallaxNode::create();
13     //将节点添加到ParallaxNode上边,各个参数的意义:第一个参数是要添加的节点,第二个参数是zorder,决定显示的顺序,第三个参数是速率,这个如何理解,就是如果你得node移动的速度是1,那么你得速度是相对于这个1的多少,我这里写得是(0.5,0)意思就是当我的parallax向左移动的1个单位的时候,bg1移动的就是0.5个单位,y方向上没有速度,最后一个是坐标,注意这个坐标是相对于node节点的坐标,而不是当前的层
14     parallax->addChild(bg1, 1, Point(0.5,0), Point(0,0));
15     parallax->addChild(bg2,1,Point(0.5,0),Point(bg1->getContentSize().width,0));
16     parallax->addChild(sprite,2,Point(1.1,0),Point(Point(400,200)));
17  
18     this->addChild(parallax);
19 }
20  
21 //改变parallax的坐标
22 void HelloWorld::update(float tm)
23 {
24     auto x = parallax->getPositionX()-1;
25     parallax->setPositionX(x);
26 }

最主要的就是addChild函数,它的参数注释有写,这里再写一下。第一个参数是要添加的节点,第二个参数是zorder,决定显示的顺序,第三个参数是速率,这个如何理解,就是如果你的node移动的速度是1,那么节点的速度是相对于这个1的多少,比如Point是(0.5,0)意思就是当我的parallax向左移动1个单位的时候,bg1移动的就是0.5个单位,y方向上没有速度,最后一个是坐标,注意这个坐标是相对于node节点的坐标,而不是当前的层。运行起来游戏,我们就会看到bg1移动的慢,而sprite移动的快,这样给人的感觉就会比较真实了。

视差节点ParallaxNode

这个类的用法比较简单,本篇博客的目的也不是真正为了说明这个类的用法。当我在实际使用的时候,想做一个滚动的背景,加几张不同的背景图片,然后近处的背景滚动的快,远处的慢,用ParallaxNode来做的时候发现,当一张背景滚动出去,想要重新设置它的坐标在第二张背景图片的后边,发现坐标是无法设置的,也就是说重新设置ParallaxNode节点的子节点坐标是无效的,如果没法设置这个子节点的坐标,那么怎么才能够做到循环滚动的效果呢?最后的答案是,将Parallax的子节点不直接添加到它上面,而是添加到一个node节点上,然后将这个node节点再添加到Parallax上面,这样的话,当我们要实现滚动背景的时候,不需要改变这个node节点的坐标,当然你也改变不了,而是改变背景图片的坐标,因为背景图片是添加到一个node节点上的,不是添加到Parallax上的,所以改变就是有效地,这样的话就实现了循环滚动背景的效果了,代码如下。

1 void HelloWorld::menuCloseCallback()
2 {
3     //创建俩张背景图片,添加到ParallaxNode节点上
4     auto bg1 = Sprite::create("HelloWorld.png");
5     bg1->setAnchorPoint(Point(0,0));
6     bg1->setPosition(Point(0,0));
7     bg1->setTag(1);
8     auto bg2 = Sprite::create("HelloWorld.png");
9     bg2->setAnchorPoint(Point(0,0));
10     bg2->setPosition(Point(bg1->getContentSize().width,0));
11     bg2->setTag(2);
12     //创建一个node,将bg1和bg2添加到node上
13     auto node = Node::create();
14     node->addChild(bg1);
15     node->addChild(bg2);
16     node->setTag(1);
17  
18     //ParallaxNode的使用方法如下
19     parallax = ParallaxNode::create();
20     parallax->addChild(node, 1, Point(1,0), Point(0,0));
21  
22     this->addChild(parallax);
23 }
24  
25 //改变parallax的坐标
26 void HelloWorld::update(float tm)
27 {
28     auto x = parallax->getPositionX()-5;
29     parallax->setPositionX(x);
30  
31     auto node = parallax->getChildByTag(1);
32     auto bg1 = node->getChildByTag(1);
33     auto bg2 = node->getChildByTag(2);
34     //这里需要先进行一下坐标的转化,转化为相对于当前层的坐标
35     auto point1 = node->convertToWorldSpace(bg1->getPosition());
36     point1 = this->convertToNodeSpace(point1);
37     if(point1.x<-bg1->getContentSize().width)
38     {
39         bg1->setPositionX(bg2->getPositionX()+bg2->getContentSize().width);
40     }
41  
42     auto point2 = node->convertToWorldSpace(bg2->getPosition());
43     point2 = this->convertToNodeSpace(point2);
44     if(point2.x<-bg2->getContentSize().width)
45     {
46         bg2->setPositionX(bg1->getPositionX()+bg1->getContentSize().width);
47     }
48 }

视差节点ParallaxNode