一,iPhone OS 提供了关亍触摸(Touch)的以下 4 个事件响应凼数:
1,由两种方式获得事件:
(1) touches 参数:
NSMutableSet *mutableTouches = [touches mutableCopy];
(2)也可以通过 event 参数获得:
NSSet *allTouches = [event allTouches];
2,依次处理每一个触摸点 通过[allTouches count]来判断是多触点还是单触点,获叏第一个触摸点方法:
UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
获叏第二个触摸点:
UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];
第三、第四...多点触摸以此类推。
3,针对每个触摸点的处理
通过以下凼数考察每个触摸点是单击还是双击:
[touch tapCount]
二,Cocos2D 的事件处理机制
1,接管:从系统 iPhoneOS 的标准UIView 获得触摸输入。
Cocos2d-iPhone 的主控类 Director 通过下面的凼数实现了 Cocos2d-iPhone 与iPhone 应用程序主窗口乊间的联系:
EAGLView *view = [director openGLView];
该方法的具体实现
由CC_DIRECTOR_INIT();实例化CCDirector的内置变量openGLView,然后调用openGLView方法取得
(当然也由其他的方法实现这绑定[[Director sharedDirector] attachInView:view];)
@protocol EAGLTouchDelegate <NSObject>
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
同时,在EAGLView的一个成员变量id<
CCTouchDispatcher.h实现了EAGLTouchDelegate协议
整合部分:我门在CCDirector.h文件的-(BOOL)initOpenGLViewWithView:(UIView *)view withFrame:(CGRect)rect方法中,我们会发现
// 设定用户输入代理对象。单例对象 sharedDispatcher 在此引入。
[openGLView_ setTouchDelegate: [TouchDispatcher sharedDispatcher]];
...
// 通过添加子视图将 UIView 转化为直接支持 OpneGL ES 输出。 [view addSubview:openGLView_];
于是在,从UIView继承的四个方法中,调用协议的方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(touchDelegate_)
{
[touchDelegate_ touchesBegan:touches withEvent:event];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if(touchDelegate_)
{
[touchDelegate_ touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(touchDelegate_)
{
[touchDelegate_ touchesEnded:touches withEvent:event];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
if(touchDelegate_)
{
[touchDelegate_ touchesCancelled:touches withEvent:event];
}
}
这样就实现了CCTouchDispatcher的全面接管了,如果视线可以关注CCTouchDispatcher的实现了
2,分发:按照预先定义好的逻辑分収给各种注册对象。
我们发现touchDelegate_的四个方法都是调用
-(void) touches:(NSSet*)touches withEvent:(UIEvent*)event withTouchType:(unsigned int)idx;
该方法首先处理TargetedTouchDelegate协议,
方法由:
@protocol CCTargetedTouchDelegate <NSObject>
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
@optional
// touch updates:
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end
后StandardTouchDelegate协议,
@protocol CCStandardTouchDelegate <NSObject>
@optional
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
判断touches中哪些是第一个协议,哪个是第二个协议,主要看- (BOOL)ccTouchBegan:(UITouch
-(void) touches:(NSSet*)touches withEvent:(UIEvent*)event withTouchType:(unsigned
并由CCTouchHandler类实现具体的操作。
3,处理:注册对象乊间如何协调响应用户的输入。
CCTouchDispatcher的内部成员
NSMutableArray *targetedHandlers;
NSMutableArray *standardHandlers;
当用户设置自定义的Layer中的isTouchEnabled = YES时,会调用Layer中的方法
-(void) setIsTouchEnabled:(BOOL)enabled
{
if( isTouchEnabled != enabled ) {
isTouchEnabled = enabled;
if( isRunning_ ) {
if( enabled )
[self registerWithTouchDispatc
else
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
}
}
}
[self
一般该语句的意思是注册到StandardTouchDelegate,如果是MenuItem Layer则注册到TargetTouchDelegate中,具体的操作也就是将Layer实例放入到如下对应的NSMutableArray中
NSMutableArray *targetedHandlers;
NSMutableArray *standardHandlers;