HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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@错误(无法将两个孩子的内容添加到两个不同的父对象中).如何构建事物以避免这种冲突?

在此先感谢您的帮助!

解决方法

@H_618_33@ 简短的回答:你做不到.

答案很长:你可以得到同样的效果,但不是一样的.

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,请注明来意。