From http://www.richarddz.net/archives/52

八月 21st, 2011cocos2d学习笔记(2) – touch事件处理

CCLayer是cocos2d处理事件的地方。文档写的很清楚。

CCLayer is a subclass of CCNode that implements the TouchEventsDelegate protocol.
All features from CCNode are valid, plus the following new features:

  • It can receive iPhone Touches
  • It can receive Accelerometer input

CCLayer有两个属性,控制是否响应事件。

BOOL isTouchEnabled
BOOL isAccelerometerEnabled


处理touch事件,第一个属性要设置成YES。


先看看iOS的事件响应机制。事件由UIApplication交给它的key window来分发。
事件分成两类multi-touch事件和非touch事件。
前一类事件,window会做hitTest,找到包含触点的最终view作为响应事件的first responder。
后一类事件,事先指定first responder,window直接交给它。
如果first responder没有处理这个事件,事件就沿着responder chain逐层向上寻找能够处理事件的responder object。第一站通常是view controller (if any),然后就是super view,最后到window和UIApplication的singleton。如图。

作为所有responder objects的超类,UIResponder声明了如下接口用来响应touch事件。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

Began发生在手指在屏幕上落下时;Moved发生在落下的手指位置变化时;Ended发生在手指抬起时;如果有以外的来电等事件打断了这个 multi-touch事件,touch就会被系统Cancel。一个完整的touch event,始于第一个手指落在屏幕上,结束于最后一个手指抬起,或者结束于Cancelled。touches是UITouch对象的集 合,UITouch对象包含了touch的时空信息。

现在回头再看cocos2d的响应机制。CCLayer继承了两个协议:CCStandardTouchDelegate和 CCTargetedTouchDelegate。前一个协议的方法就是iOS的UIResponder里面声明的那四个方法,只不过前缀了cc。后一个 协议声明如下:

@protocol CCTargetedTouchDelegate 
   - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
   @optional
   - (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
   - (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
   - (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end

文档说,用CCTargetedTouchDelegate有两个好处:第一,你不需要自己去处理NSSet,cocos2d每次只给你一个 touch;第二,在ccTouchBegan里面,return YES来claim一下,那么只有claim了这个touch的delegate才能收到关于此touch的更新。但是,要用Targeted方式接收事 件,必须重写CCLayer的registerWithTouchDispatcher方法。
方法默认是这样实现的:

-(void) registerWithTouchDispatcher {
   [[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:0];
}

文档给了一个重写的示例:

-(void) registerWithTouchDispatcher {
   [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
      priority:INT_MIN+1
      swallowsTouches:YES];
}

这个swallowsTouches的意思是吃掉claimed touches,于是,没有claim这些touches的delegate就无法接收到响应的touch事件了。

arrow
arrow
    全站熱搜

    zer931 發表在 痞客邦 留言(0) 人氣()


    留言列表 留言列表

    發表留言