当前位置:  开发笔记 > 编程语言 > 正文

使用cocos2d处理CCSprite触摸的最佳实践

如何解决《使用cocos2d处理CCSprite触摸的最佳实践》经验,为你挑选了1个好方法。

大家好.我刚开始研究cocos2d库.我听说如果你习惯于在ActionScript中编程,这是一个很容易进入的库,我发现很多概念确实相似.

我开始查看示例项目(此处链接的示例游戏特别有用),我看到触摸的处理通常不在CCSprite中完成.相反,实例化CCSprites的CCLayer会对触摸事件作出反应,并迭代它创建的精灵以检测触摸了哪个CCSprite(如果有的话).

我想CCSprites处理是否已经打动自己,并调用,通知它已经触及(如果需要).Paddle在/ tests/TouchesTest下找到的类就是这样 - 它自己处理触摸.

所以,我的问题是:对此最佳做法是什么?在中心位置处理触摸并通过子节点迭代以查看触摸的内容是否更好?或者每个孩子应该处理自己的触摸事件?或者没关系?

我希望每个孩子都能处理自己的触摸事件,但我想遵循这方面的最佳实践(如果存在的话).谢谢!



1> Mark7777G..:

我认为这是一个偏好问题,但我喜欢通过子类化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来更改纹理(精灵图像)并相应地更改状态变量.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有