cocos2d-x 建立自己的层级窗口消息机制-续
为了让控件加入我们的层级窗口消息机制。我们必须要派生所有cocos2d控件,去掉他们的消息注册功能。还需要为每个新添加的控件,到wmTouchDelegate里面添加nonTrivialTouchHandler标志。
以上两步让我觉得decorator模式或许能解决,但是实际上decorator模式和我现在面临的情况有很多区别。因为cocos2d本身的框架已经存在,而我的承诺的是不改变源码,所以不能像decorator模式那样,随便更改源码框架结构。另外当前我的问题不是添加新功能而是修改功能。所以decorator模式不是专门针对我这个情况的。但是那种解决问题的能力(不用为所有的类重新派生新类)却是我急需的。通过一些分析后,我找到一些方法,可以改善我的层级窗口消息机制,基本解决上面两个弊端。新的层级窗口机制将实现一下目标:
原本的所有cocos2d控件,不需经过任何修改即可加入层级窗口消息机制。
且新添加的控件不要到wmTouchDelegate中添加任何标志。
我是通过下面几点修改达到这个目标的:
其实能实现清除消息注册功能的方法,不止继承,派生这一种。这里使用了另一种,通过在祖层(实际是BYLayer)的onEnter中添加部分功能(并调用原来的CCLayer::onEnter()),来实现清除消息注册。onEnter里的这个功能是通过遍历所有的子对象,判断他们是否继承自CCLayer,如果是,我们将调用setTouchEnable( false )来去掉他们消息注册功能。
其实大部分控件都有自己有用(有重要意义)的ccTouchX函数处理,所以我们只需要记录那些继承自CCLayer(包括CCLayer),且有无重要意义的ccTouchX函数(CCLayer中的ccTouchBegan在debug模式下会调用assert导致崩溃,但我们又强调不修改源码)的类就可以了。然后我们反向判断,就知道这个传入的类是否需要调用其ccTouchX函数了。这样我们就不需要为每个新控件就添加记录了。
通过修改后的层级窗口消息机制(新的机制也更改了的类名前缀),可以让已经存在的工程很快采用这个体系,只需要将每个场景创建的Layer派生自BYLayerAncestor即可。其他代码不需修改,因为新的机制已经兼容cocos2d所有原始的控件。这里还是贴上一张效果图吧(没有变)。
上次由于种种原因没有给出完整源码,让部分读者只能私下给发信息才能获得源码。这次直接展示6个完整源码文件。以方便读者测试,使用,修改,请提出宝贵意见。
[cpp]
//
// BYCocos.h
// TableTest
//
// Created by jason on 12-12-26.
//
//
#ifndef TableTest_BYCocos_h
#define TableTest_BYCocos_h
#include "BYMacros.h"
#include "BYUtility.h"
#include "BYTouchDelegate.h"
#include "BYLayer.h"
#endif
[cpp]
//
// BYMacros.h
// TableTest
//
// Created by jason on 12-12-26.
//
//
#ifndef TableTest_BYMacros_h
#define TableTest_BYMacros_h
#define BY_ASSERT_POINTER( x ) assert( ( x ) != NULL )
#define BY_DEFAULT_CHARSET "Arial"
#define BY_DOUBLE_CLICK_DELTA 0.4f
//anchor point
#define BY_ANCHOR_POINT_CENTER ccp( 0.5f, 0.5f )
#define BY_ANCHOR_POINT_LEFTBOTTOM ccp( 0.0f, 0.0f )
#define BY_ANCHOR_POINT_RIGHTBOTTOM ccp( 1.0f, 0.0f )
#define BY_ANCHOR_POINT_RIGHTTOP ccp( 1.0f, 1.0f )
#define BY_ANCHOR_POINT_LEFTTOP ccp( 0.0f, 1.0f )
//size
#define BY_IPAD_SIZE_WIDTH 1024
#define BY_IPAD_SIZE_HEIGHT 768
#define BY_IPAD_SIZE_WIDTH_HALF 512
#define BY_IPAD_SIZE_HEIGHT_HALF 384
#define BY_WIN_SIZE_WIDTH ( CCDirector::sharedDirector()->getWinSize().width )
#define BY_WIN_SIZE_HEIGHT ( CCDirector::sharedDirector()->getWinSize().height )
#define BY_WIN_SIZE_WIDTH_HALF ( CCDirector::sharedDirector()->getWinSize().width * 0.5f )
#define BY_WIN_SIZE_HEIGHT_HALF ( CCDirector::sharedDirector()->getWinSize().height * 0.5f )
#define BY_WIN_CENTER_POINT ccp( BY_WIN_SIZE_WIDTH_HALF, BY_WIN_SIZE_HEIGHT_HALF )
#define BY_NODE_WIDTH( n ) ( ( n )->getContentSize().width )
#define BY_NODE_HEIGHT( n ) ( ( n )->getContentSize().height )
#define BY_NODE_WIDTH_HALF( n ) ( ( n )->getContentSize().width * 0.5f )
#define BY_NODE_HEIGHT_HALF( n ) ( ( n )->getContentSize().height * 0.5f )
//menu items
#define BY_MENU_ITEM_COMMON_SPACING 20
//functions
#define BY_GET_DIRECTOR() cocos2d::CCDirector::sharedDirector()
#define BY_GET_BROTHER( brotherClassName, brotherTag ) ( ( brotherClassName* )getParent()->getChildByTag( ( brotherTag ) ) )
#define BY_GET_CHILD( childClassName, childTag ) ( ( childClassName* )getChildByTag( ( childTag ) ) )
#define BY_MESSAGE_CONSTRUCTOR( ownerClassName ) \
ownerClassName() : BYTouchDelegate( this ){}
#define BY_MESSAGE_BRIDGE() \
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) \
{ \
return byTouchBegan( pTouch, pEvent ); \
} \
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) \
{ \
byTouchMoved( pTouch, pEvent ); \
} \
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) \
{
补充:移动开发 , 其他 ,
- 更多wap疑问解答:
- 新人求助QPainter
- 为什么程序都退出了还可以收到推送?如果大多设备都可以推送那运营商怎么办?
- qt 4.7 sqlserver2000 存储过程调用
- 关于ANDROID4.0.1编译问题!
- Android FrameBuffer读屏幕30秒后mmap失败
- 联通粗定位用java程序如何来请求和接受数据
- 为什么QT运行Android平台的程序时,mouseMoveEvent事件响应的间隔时间很长??????????
- android与PC蓝牙通讯
- 指定大小的label 内容可变,如果内容超出label的宽度,将未能显示的部分显示在另一个label上
- Android调试
- android如何通过wifi连接无线打印机
- 运行程序,release目录下产生一个乱码文件夹
- 分享个某机构最新安卓资料,自己验证了
- service启动不起来,掉不了service connection
- 求助:QT5.0 没有QPrinter吗