ios – 创建可触摸的CCNode的问题,其CCSprites是CCBatchNode的子级

ios – 创建可触摸的CCNode的问题,其CCSprites是CCBatchNode的子级,第1张

概述这可能需要一些解释,但在这里,非常感谢任何见解. 简短版本:如何创建一个TouchableButton(它自己检测触摸),其CCSprite图像是另一个类中CCSpriteBatchNode的子代? (通常,CCSprite将是TouchableButton本身的子代). 长版: 我正在使用Cocos2d构建游戏.游戏侧重于一个充满代理(类AgentView:CCNode)的环境(类Environ 这可能需要一些解释,但在这里,非常感谢任何见解.

简短版本:如何创建一个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的子级所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1034467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存