简短版本:如何创建一个touchablebutton(它自己检测触摸),其CCSprite图像是另一个类中CCSpriteBatchNode的子代? (通常,CCSprite将是touchablebutton本身的子代).
长版:
我正在使用Cocos2d构建游戏.游戏侧重于一个充满代理(类AgentVIEw:CCNode)的环境(类EnvironmentVIEw:cclayer),它们相互运行并相互交互.
EnvironmentVIEw维护一个AgentVIEw对象列表,并根据需要创建/销毁它们(取决于它们如何交互).
每个AgentVIEw都有一个CCSprite @property,它被添加为CCBatchNode(EnvironmentVIEw的@property)的子级,它被添加为EnvironmentVIEw的子级.
我正在尝试实现一个功能,用户可以触摸代理并将其从一个地方移动到另一个地方.
因为有许多代理在EnvironmentVIEw中移动,所以我不想使用标准方法获取触摸位置并循环遍历所有AgentVIEw CCSprites以查看触摸是否触及其中一个(这会大大降低帧速率,请:对推广这种方法的答案不感兴趣).
相反,我想将每个AgentVIEw变成一个可触摸的节点(一个知道它何时被触摸的节点,而不是一个被触及的节点(上面提到的方法)).
基本上我想用某种touchablebutton对象替换或扩充每个AgentVIEw的CCSprite.
我正在使用一个类(我称之为touchablebutton),它将这种方法用于我游戏中与UI相关的按钮,他们知道何时触摸它们而不在其父层中实现任何CCtouchesBegan方法.但我一直无法使touchablebutton适应这个用例,原因如下:
touchablebuttons将CCSprite作为init参数.此CCSprite设置为按钮的可触摸部分,并添加为按钮本身的子项.因为我还将CCSprite添加为EnvironmentVIEw中CCSpriteBatchNode的子代,所以我得到一个错误(无法将两个孩子的内容添加到两个不同的父对象中).如何构建事物以避免这种冲突?
在此先感谢您的帮助!
解决方法 简短的回答:你做不到.答案很长:你可以得到同样的效果,但不是一样的.
CCSpriteBatchNode的工作原理是在一个glDrawElements调用中使用一个通用纹理(精灵表)绘制所有CCSprite子项,这就是它具有如此优异的性能.但结果是,每个子节点必须是一个精灵,如果你将一个子节点添加到精灵中,它将被忽略.
所以,你现在唯一的办法是将CCSprite子类化为一个按钮并复制许多功能,如下所示:
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的子级所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)