大佬教程收集整理的这篇文章主要介绍了ios – 创建可触摸的CCNode的问题,其CCSprites是CCBatchNode的子级,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
简短版本:如何创建@L_450_1@TouchableButton(它自己检测触摸),其CCSprite图像是另@L_450_1@类中CCSpriteBatchNode的子代? (通常,CCSprite将是TouchableButton本身的子代).
长版:
我正在使用COcos2d构建游戏.游戏侧重于@L_450_1@充满代理(类AgentView:CCNodE)的环境(类EnvironmentView:CCLayer),它们相互运行并相互交互.
EnvironmentView维护@L_450_1@AgentView对象列表,并根据需要创建/销毁它们(取决于它们如何交互).
每个AgentView都有@L_450_1@CCSprite @property,它被添加为CCBatchNode(EnvironmentView的@property)的子级,它被添加为EnvironmentView的子级.
我正在尝试实现@L_450_1@@L_801_9@,用户可以触摸代理并将其从@L_450_1@地方移动到另@L_450_1@地方.
因为有许多代理在EnvironmentView中移动,所以我不想使用标准方法获取触摸位置并循环遍历所有AgentView CCSprites以查看触摸是否触及其中@L_450_1@(这会大大降低帧速率,请:对推广这种方法的答案不感兴趣).
相反,我想将每个AgentView变成@L_450_1@可触摸的节点(@L_450_1@知道它何时被触摸的节点,而不是@L_450_1@被触及的节点(上面提到的方法)).
基本上我想用某种TouchableButton对象替换或扩充每个AgentView的CCSprite.
我正在使用@L_450_1@类(我称之为TouchableButton),它将这种方法用于我游戏中与UI相关的按钮,他们知道何时触摸它们而不在其父层中实现任何CCTouchesBegan方法.但我一直无法使TouchableButton适应这个用例,原因如下:
TouchableButtons将CCSprite作为init参数.此CCSprite设置为按钮的可触摸部分,并添加为按钮本身的子项.因为我还将CCSprite添加为EnvironmentView中CCSpriteBatchNode的子代,所以我得到@L_450_1@错误(无法将两个孩子的内容添加到两个不同的父对象中).如何构建事物以避免这种冲突?
在此先感谢您的帮助!
答案很长:你可以得到同样的效果,但不是一样的.
CCSpriteBatchNode的工作原理是在@L_450_1@glDrawElements调用中使用@L_450_1@通用纹理(精灵表)绘制所有CCSprite子项,这就是它具有如此优异的性能.但结果是,每个子节点必须是@L_450_1@精灵,如果你将@L_450_1@子节点添加到精灵中,它将被忽略.
所以,你现在唯一的办法是将CCSprite子类化为@L_450_1@按钮并复制许多@L_801_9@,如下所示:
ButtonSprite.h:
// // ButtonSprite.h // TESTButtonSprite // // Created by Karl Stenerud on 9/1/11. // #import "cocos2d.h" @class ButtonSprite; typedef void (^ButtonPressCallBACk)(ButtonSprite* button); /** * A sprite that can respond to touches. * Most of this code was taken from CCLayer. */ @interface ButtonSprite : CCSprite <CCStandardTouchDelegate,CCTargetedTouchDelegate> { BOOL touchEnabled_; int touchPriority_; BOOL swallowTouches_; BOOL registeredWithDispatcher_; BOOL touchInProgress_; BOOL buttonWasDown_; ButtonPressCallBACk onButtonPressedCallBACk_; } /** Priority position in which this node will be handled (lower = sooner) */ @property(nonatomic,readwrite,assign) int touchPriority; /** If true,no other node will respond to touches this one responds to */ @property(nonatomic,assign) BOOL swallowTouches; /** If true,this node responds to touches. */ @property(nonatomic,assign) BOOL touchEnabled; /** Called whenever a full touch completes */ @property(nonatomic,copy) ButtonPressCallBACk onButtonPressedCallBACk; /** Called when a button press is detected. */ - (void) onButtonPressed; /** Called when a button is pushed down. */ - (void) onButtonDown; /** Called when a button is released. */ - (void) onButtonUp; - (BOOL) touchHitsSelf:(UITouch*) touch; - (BOOL) touch:(UITouch*) touch hitsnode:(CCNode*) node; @end
ButtonSprite.m:
// // ButtonSprite.m // TESTButtonSprite // // Created by Karl Stenerud on 9/1/11. // #import "ButtonSprite.h" @interface ButtonSprite () - (void) registerWithTouchDispatcher; - (void) unregisterWithTouchDispatcher; @end @implementation ButtonSprite @synthesize touchEnabled = touchEnabled_; @synthesize touchPriority = touchPriority_; @synthesize swallowTouches = swallowTouches_; @synthesize onButtonPressedCallBACk = onButtonPressedCallBACk_; - (id) init { if(nil != (self = [super init])) { touchPriority_ = 0; swallowTouches_ = YES; touchEnabled_ = YES; self.isRelativeAnchorPoint = YES; self.anchorPoint = ccp(0.5,0.5); } return self; } - (void) dealloc { [self unregisterWithTouchDispatcher]; [onButtonPressedCallBACk_ release]; [super dealloc]; } - (void) registerWithTouchDispatcher { [self unregisterWithTouchDispatcher]; [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:self.touchPriority swallowsTouches:self.swallowTouches]; registeredWithDispatcher_ = YES; } - (void) unregisterWithTouchDispatcher { if(registeredWithDispatcher_) { [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; registeredWithDispatcher_ = NO; } } - (void) setSwallowTouches:(BOOL) value { if(swallowTouches_ != value) { swallowTouches_ = value; if(isRunning_ && touchEnabled_) { [self registerWithTouchDispatcher]; } } } - (void) setTouchPriority:(int) value { if(touchPriority_ != value) { touchPriority_ = value; if(isRunning_ && touchEnabled_) { [self registerWithTouchDispatcher]; } } } -(void) setTouchEnabled:(BOOL)enabled { if( touchEnabled_ != enabled ) { touchEnabled_ = enabled; if( isRunning_ ) { if( touchEnabled_ ) { [self registerWithTouchDispatcher]; } else { [self unregisterWithTouchDispatcher]; } } } } - (void)cleanup { self.touchEnabled = NO; } #pragma mark TouchableNode - CallBACks -(void) onEnter { // register 'parent' nodes first // since events are propagated in reverse order if (self.touchEnabled) { [self registerWithTouchDispatcher]; } // then iterate over all the children [super onEnter]; } -(void) onExit { if(self.touchEnabled) { [self unregisterWithTouchDispatcher]; } [super onExit]; } -(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { if([self touchHitsSelf:touch]) { touchInProgress_ = YES; buttonWasDown_ = YES; [self onButtonDown]; return YES; } return NO; } -(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { if(touchInProgress_) { if([self touchHitsSelf:touch]) { if(!buttonWasDown_) { [self onButtonDown]; } } else { if(buttonWasDown_) { [self onButtonUp]; } } } } -(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { if(buttonWasDown_) { [self onButtonUp]; } if(touchInProgress_ && [self touchHitsSelf:touch]) { touchInProgress_ = NO; [self onButtonPressed]; } } -(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event { if(buttonWasDown_) { [self onButtonUp]; } touchInProgress_ = NO; } - (void) onButtonDown { buttonWasDown_ = YES; } - (void) onButtonUp { buttonWasDown_ = NO; } - (void) onButtonPressed { self.onButtonPressedCallBACk(self); } - (BOOL) touchHitsSelf:(UITouch*) touch { return [self touch:touch hitsnode:self]; } - (BOOL) touch:(UITouch*) touch hitsnode:(CCNode*) node { CGRect r = CGRectMake(0,node.contentSize.width,node.contentSize.height); CGPoint local = [node convertTouchToNodeSpace:touch]; return CGRectContainsPoint(r,local); } @end
像这样使用它:
ButtonSprite* myButton = [ButtonSprite spriteWithFile:@"button_image.png"]; myButton.onButtonPressedCallBACk = ^(ButtonSprite* button) { NSLog(@"Pressed!"); }; [self addChild: myButton];
请注意,如果您在批处理节点中使用此类,则它必须没有自己的子级!
以上是大佬教程为你收集整理的ios – 创建可触摸的CCNode的问题,其CCSprites是CCBatchNode的子级全部内容,希望文章能够帮你解决ios – 创建可触摸的CCNode的问题,其CCSprites是CCBatchNode的子级所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。