大家好.我刚开始研究cocos2d库.我听说如果你习惯于在ActionScript中编程,这是一个很容易进入的库,我发现很多概念确实相似.
我开始查看示例项目(此处链接的示例游戏特别有用),我看到触摸的处理通常不在CCSprite中完成.相反,实例化CCSprites的CCLayer会对触摸事件作出反应,并迭代它创建的精灵以检测触摸了哪个CCSprite(如果有的话).
我想CCSprites处理是否已经打动自己,并调用了,通知它已经触及(如果需要).Paddle
在/ tests/TouchesTest下找到的类就是这样 - 它自己处理触摸.
所以,我的问题是:对此最佳做法是什么?在中心位置处理触摸并通过子节点迭代以查看触摸的内容是否更好?或者每个孩子应该处理自己的触摸事件?或者没关系?
我希望每个孩子都能处理自己的触摸事件,但我想遵循这方面的最佳实践(如果存在的话).谢谢!
我认为这是一个偏好问题,但我喜欢通过子类化CCSprite来触及sprite.我在我的CCSprite子类中创建一个getter方法,从子类中检索状态变量,然后主程序可以相应地执行.
这是我的CCSprite子类"spuButton"的示例头文件:
#import "cocos2d.h" typedef enum tagButtonState { kButtonStatePressed, kButtonStateNotPressed } ButtonState; typedef enum tagButtonStatus { kButtonStatusEnabled, kButtonStatusDisabled } ButtonStatus; @interface spuButton : CCSprite{ @private ButtonState state; CCTexture2D *buttonNormal; CCTexture2D *buttonLit; ButtonStatus buttonStatus; } @property(nonatomic, readonly) CGRect rect; + (id)spuButtonWithTexture:(CCTexture2D *)normalTexture; - (void)setNormalTexture:(CCTexture2D *)normalTexture; - (void)setLitTexture:(CCTexture2D *)litTexture; - (BOOL)isPressed; - (BOOL)isNotPressed; @end
这是.m文件的示例:
#import "spuButton.h" #import "cocos2d.h" @implementation spuButton - (CGRect)rect { CGSize s = [self.texture contentSize]; return CGRectMake(-s.width / 2, -s.height / 2, s.width, s.height); } + (id)spuButtonWithTexture:(CCTexture2D *)normalTexture { return [[[self alloc] initWithTexture:normalTexture] autorelease]; } - (void)setNormalTexture:(CCTexture2D *)normalTexture { buttonNormal = normalTexture; } - (void)setLitTexture:(CCTexture2D *)litTexture { buttonLit = litTexture; } - (BOOL)isPressed { if (state == kButtonStateNotPressed) return NO; if (state == kButtonStatePressed) return YES; return NO; } - (BOOL)isNotPressed { if (state == kButtonStateNotPressed) return YES; if (state == kButtonStatePressed) return NO; return YES; } - (id)initWithTexture:(CCTexture2D *)aTexture { if ((self = [super initWithTexture:aTexture]) ) { state = kButtonStateNotPressed; } return self; } - (void)onEnter { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; [super onEnter]; } - (void)onExit { [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; [super onExit]; } - (BOOL)containsTouchLocation:(UITouch *)touch { return CGRectContainsPoint(self.rect, [self convertTouchToNodeSpaceAR:touch]); } - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { if (state == kButtonStatePressed) return NO; if ( ![self containsTouchLocation:touch] ) return NO; if (buttonStatus == kButtonStatusDisabled) return NO; state = kButtonStatePressed; [self setTexture:buttonLit]; return YES; } - (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { // If it weren't for the TouchDispatcher, you would need to keep a reference // to the touch from touchBegan and check that the current touch is the same // as that one. // Actually, it would be even more complicated since in the Cocos dispatcher // you get NSSets instead of 1 UITouch, so you'd need to loop through the set // in each touchXXX method. if ([self containsTouchLocation:touch]) return; //if (buttonStatus == kButtonStatusDisabled) return NO; state = kButtonStateNotPressed; [self setTexture:buttonNormal]; } - (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { state = kButtonStateNotPressed; [self setTexture:buttonNormal]; } @end
希望这有助于和快乐编码!
添加滴答方法和解释(适用于Stephan的问题):
为了检查按钮的状态,我有一个tick:方法,它基本上会触发每一帧并检查我所有按钮的状态.
-(void)tick:(ccTime)dt { do my button checks here.... }
我通过调用isPressed或isNotPressed函数来检查我的按钮的状态,该函数是我的spuButton类的一部分.
for (spuButton *aButton in _fourButtonsArray) { if ([aButton isNotPressed]) continue; //this button is not pressed .....otherwise record that it is pressed..... }
然后我做同样的检查,看它是否已被释放并做出相应的反应.我是这样做的,因为我希望能够对多个按钮按下组合做出反应,而且我想在按下它时做一些事情,然后在它被释放时做其他事情.我使用ccTouchBegan和ccTouchEnded来更改纹理(精灵图像)并相应地更改状态变量.