写一个CCPageLayer

过关小游戏常带一个关卡界面,分页显示不同的关卡,可左右滑动。cocos2d-x中竟然不带类似cocoa中UIScrollView的控件,只好自己从继承CCLayerColor开始写新类,姑名之CCPageLayer。

初始化时要确定高度和显示宽度(为了简化代码,让页宽等于显示宽度,这样符合笔者的需求):

 1 bool CCPageLayer::init(const float &width,
 2                        const float &height)
 3 {
 4     if (CCLayerColor::init()) {
 5         this->setOpacity(255);
 6         size_ = CCSizeMake(width, height);
 7         data_source_ = NULL;
 8         delegate_ = NULL;
 9         this->setIsTouchEnabled(true);
10 
11         return true;
12     } else {
13         return false;
14     }
15 }

笔者没有在这个函数中设置layer的contentSize,因此把传入参数暂存于size_中。

 

为了避免初始化接口过于庞大,不易维护,笔者创建了CCPageLayerDataSource抽象类,用于获取其余数据:

 

1 class CCPageLayerDataSource
2 {
3 public:
4     virtual PagesCount getPagesCount() = 0;
5     virtual CCLayer *layerOfPageIndex(const PagesCount &c) = 0;
6 };

 

在类中则有CCPageLayerDataSource *类型的弱引用指针成员:

1 CCPageLayerDataSource *data_source_;

初始化完之后,使用者可以设置data_source_:

1 layer->setDataSource(this);

如此在CCPagerLayer::onEnter函数中可完整初化:

 1 void CCPageLayer::onEnter()
 2 {
 3     DASSERT(data_source_ != NULL);
 4     CCLayerColor::onEnter();
 5 
 6     PagesCount c = data_source_->getPagesCount();
 7     this->setContentSize(CCSizeMake(c * size_.width, size_.height));
 8     this->addLayersOfEachPage();
 9     cur_page_ = 0;
10 }

DASSERT宏在debug环境下为assert。

addLayersOfEachPage函数会调用data_source->layerOfPageIndex(const PageCount &c)来获得每页的layer。

初始化完之后,希望让layer随手指左右移动:

1 bool CCPageLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
2 {
3     began_touch_x = getTouchPosition(*pTouch).x;    began_layer_x = getNodeLeft(*this);
4     return true;
5 }
1 //因为为会被频繁调用,也许内联效率上好些。
2 inline void CCPageLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
3 {
4     CCPoint now = getTouchPosition(*pTouch);
5     setNodeLeft(this, began_layer_x + now.x - began_touch_x);
6 }

目前只是让layer随手指移动,手指离开后不会不会自动定位。自动定位需要重写ccTouchEnded:

 1 void CCPageLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
 2 {
 3     float now_x = getNodeLeft(*this);
 4     int t = (began_layer_x - now_x) / CHNAGE_PAGE_DIS;
 5     int page_inc = t / fabs(t);
 6     int to_page = cur_page_ + page_inc;   
 7     if (this->isPageIndexLegal(to_page)) {
 8         this->moveToPage(to_page);
 9     } else {
10         this->moveToPage(cur_page_);
11     }
12 }

完整代码:https://github.com/chncwang/cocos2d-x_classes.git

以上代码经过测试。

这样就实现了CCPageLayer的基本功能,当然有一些可以改进之处:

1) 增加一些代理接口,让CCPageLayer在执行某些动作时(如换页)可以执行代理接口;

2) 改善不同页layer的内存管理(这个的内容就多得去了,话说cocoa中的UITableView类的设计堪为典范)。

and so on...

你可能感兴趣的:(page)