【问题标题】:Simultaneous Sprite Touch Detection - iPhone & cocos2d同时检测精灵触摸 - iPhone & cocos2d
【发布时间】:2010-10-24 01:38:16
【问题描述】:

我正在使用 cocos2d 为 iPhone 编写一个应用程序,其中我有 4 个作为按钮的 Sprite。我想我会通过使用 2 个具有不同 .png 文件的精灵来实现按钮功能,这些文件代表按下/未按下状态。我认为这比使用动画更好。除了检测何时按下和释放按钮之外,我还需要检测何时发生两个按钮组合按下/释放(如和弦)。我什至可以将它推进到 3 和 4 按钮组合。我想实现的另一个功能是检测是否来自按钮内的轻弹并以另一个动作序列响应。

对此,最佳方法是什么?我会为四个按钮(它们呈方形)使用边界矩形/精灵并吞下触摸吗?那么我会使用较小的精灵矩形来确定触摸发生在哪一个上吗?或者我会让各个精灵进行检测,然后让他们检查其他按钮是否也被按下然后同时释放?我会为这两种方式中的任何一种使用 Bool 状态变量吗?

通过为每个按钮精灵制作一个菜单/菜单项,我使用 CCMenu 和 CCMenuitem 让这一切工作得很好;但是,我不知道如何检测一个菜单中的菜单项是否在按下和释放另一个菜单中的菜单项的同时被按下和释放。我使用了单独的菜单,因为如果我将同一个菜单与多个菜单项一起使用,那么一次只能按下一个。我说它工作得很好,这意味着它可以与单台和多台印刷机一起使用,但它将多台印刷机视为两个连续的印刷机,而不是同时印刷。 IE:单次按下导致运行单个动作序列(如预期的那样),同时按下组合导致为每个按钮运行单独的按钮动作序列,就好像我分别按下它们一样(我希望它运行一个特定的动作序列到那个按钮组合)。这就是为什么我决定尝试实现我自己的按钮系统而不是使用 CCMenu 系统可能会更好。离开 CCMenu 是否正确?

抱歉,描述太长了,但确实说得很具体。 B)

任何关于其他人如何实施或将实施这一点的见解将不胜感激!

【问题讨论】:

  • 没人有什么想法吗?如果可以,请提供帮助。
  • 抱歉,这里有点忙。我还可以建议您尝试将此问题复制并粘贴到 gamedev.stackexchange.com 中?它将获得更多游戏意见:) 道歉。
  • 也试过在那里发帖,谢谢。
  • 我会使用委托,每个精灵都有一个委托方法,该方法会返回到作为其父(委托)的 CCLayer,当它们被按下时,发送一条消息,增加 CCLayer 上的计数器,在释放或取消时,发送一个递减计数器。处理 CCLayer 上精灵按钮的实际功能。

标签: iphone button cocos2d-iphone touch sprite


【解决方案1】:

这是我如何实现的,以防其他人尝试这样做。

spuButton.h(CCSprite 子类)

#import <Foundation/Foundation.h>
#import "cocos2d.h"

typedef enum tagButtonState {
    kButtonStatePressed,
    kButtonStateNotPressed
} ButtonState;

typedef enum tagButtonStatus {
    kButtonStatusEnabled,
    kButtonStatusDisabled
} ButtonStatus;

@interface spuButton : CCSprite <CCTargetedTouchDelegate> {
@private
    ButtonState buttonState;
    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;
- (void)makeDisabled;
- (void)makeEnabled;
- (BOOL)isEnabled;
- (BOOL)isDisabled;
- (void)makeLit;
- (void)makeNormal;
- (void)dealloc;

@end

spuButton.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 (buttonState== kButtonStateNotPressed) return NO;
    if (buttonState== kButtonStatePressed) return YES;
    return NO;
}

- (BOOL)isNotPressed {
    if (buttonState== kButtonStateNotPressed) return YES;
    if (buttonState== kButtonStatePressed) return NO;
    return YES;
}

- (void)makeDisabled {
    buttonStatus = kButtonStatusDisabled;
    buttonState= kButtonStateNotPressed;
    [self makeNormal];
}
- (void)makeEnabled {
    buttonStatus = kButtonStatusEnabled;
    buttonState= kButtonStateNotPressed;
    [self makeNormal];
}

- (BOOL)isEnabled {
    if (buttonStatus== kButtonStatusDisabled) return NO;
    if (buttonStatus== kButtonStatusEnabled) return YES;
    return NO;
}

- (BOOL)isDisabled {
    if (buttonStatus== kButtonStatusEnabled) return NO;
    if (buttonStatus== kButtonStatusDisabled) return YES;
    return YES;
}

- (void)makeLit {
    [self setTexture:buttonLit];
}

- (void)makeNormal {
    [self setTexture:buttonNormal];
}

- (id)initWithTexture:(CCTexture2D *)aTexture {
    if ((self = [super initWithTexture:aTexture]) ) {       
        buttonState = kButtonStateNotPressed;
        buttonStatus = kButtonStatusEnabled;
    }
    return self;
}

- (void)onEnter {
    if (buttonStatus == kButtonStatusDisabled) return;
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];
    [super onEnter];
}

- (void)onExit {
    if (buttonStatus == kButtonStatusDisabled) return;
    [[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 (buttonStatus == kButtonStatusDisabled) return NO;
    if (buttonState== kButtonStatePressed) return NO;
    if ( ![self containsTouchLocation:touch] ) return NO;

    buttonState= kButtonStatePressed;
    [self makeLit];

    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 (buttonStatus == kButtonStatusDisabled) return;
    if ([self containsTouchLocation:touch]) return;

    buttonState= kButtonStateNotPressed;
    [self makeNormal];
}

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    if (buttonStatus == kButtonStatusDisabled) return;

    buttonState= kButtonStateNotPressed;
    [self makeNormal];
}

- (void)dealloc {
    [buttonNormal release];
    [buttonLit release];
    [super dealloc];
}

@end

HelloWorldScene.m(只是我的记号:防止我的其他函数混淆示例的方法)

-(void)tick:(ccTime)dt {
    if ([[_otherControlsArray objectAtIndex:0] wasPressed]) {
        [[_otherControlsArray objectAtIndex:0] setWasPressed:NO];
        [self removeChild:[_otherControlsArray objectAtIndex:0] cleanup:YES];
        [self addChild:[_otherControlsArray objectAtIndex:1]];
        NSLog(@"Play");

        _gameHasNotBeenPlayedYet = NO;
        Snarfle_s_PowerUPAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
        [delegate makeNotPaused];
        [self gameLogic];
    }

    if (_gameHasNotBeenPlayedYet) {
        return;
    }

    if (_buttonsPressedAndReleased > 0) {  //respond to button(s) released and reset
        NSLog(@"Buttons Pressed and Released-->%d",_buttonsPressedAndReleased);
        if ([self checkButtons:_buttonsPressedAndReleased]);
        _buttonsPressed = 0;
        _buttonsPressedAndReleased = 0;

        return;
    }
    if (_buttonsPressed <= 4) { // two buttons have not already been pressed
        for (spuButton *aButton in _fourButtonsArray) {
            if ([aButton isNotPressed]) continue; //this button is not pressed
            if (_buttonsPressed == 0) { //this button is pressed and no other buttons have been pressed
                _buttonsPressed = aButton.tag;
                continue;
            }
            //this button is pressed while another has been pressed
            //figure out which two buttons have been pressed
            if (_buttonsPressed == 1) {  //red plus another
                switch (aButton.tag) {
                    case 2:   //blue
                        _buttonsPressed = 5;
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 3:  //green
                        _buttonsPressed = 6;
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 4:  //yellow
                        _buttonsPressed = 7;
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        break;
                    default:
                        _buttonsPressed = 1;
                        break;
                }
            }
            if (_buttonsPressed == 2) {  //blue plus another
                switch (aButton.tag) {
                    case 1:   //red
                        _buttonsPressed = 5;
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 3:  //green
                        _buttonsPressed = 8;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 4:  //yellow
                        _buttonsPressed = 9;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        break;
                    default:
                        _buttonsPressed = 2;
                        break;
                }
            }
            if (_buttonsPressed == 3) {  //green plus another
                switch (aButton.tag) {
                    case 1:   //red
                        _buttonsPressed = 6;
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 2:  //blue
                        _buttonsPressed = 8;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                        break;
                    case 4:  //yellow
                        _buttonsPressed = 10;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        break;
                    default:
                        _buttonsPressed = 3;
                        break;
                }
            }
            if (_buttonsPressed == 4) {  //yellow plus another
                switch (aButton.tag) {
                    case 1:   //red
                        _buttonsPressed = 7;
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        break;
                    case 2:  //blue
                        _buttonsPressed = 9;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                        break;
                    case 3:  //green
                        _buttonsPressed = 10;
                        [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                        [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                        break;
                    default:
                        _buttonsPressed = 4;
                        break;
                }
            }
            if (_buttonsPressed > 4) break;  //more than one has been pressed and identified
        }
    }
    //now we know what buttons have been pressed now check to see if they have been released
    //if more than one has been pressed disable the other two
    //also if more than one has been pressed and one of them gets released disable the released one but keep it lit
    switch (_buttonsPressed) {
        case 1:  //red
            if ([[_fourButtonsArray objectAtIndex:0] isNotPressed]) _buttonsPressedAndReleased = 1;
            break;
        case 2:  //blue
            if ([[_fourButtonsArray objectAtIndex:1] isNotPressed]) _buttonsPressedAndReleased = 2;
            break;
        case 3:  //green
            if ([[_fourButtonsArray objectAtIndex:2] isNotPressed]) _buttonsPressedAndReleased = 3;
            break;
        case 4:  //yellow
            if ([[_fourButtonsArray objectAtIndex:3] isNotPressed]) _buttonsPressedAndReleased = 4;
            break;
        case 5:  //red & blue
            if (([[_fourButtonsArray objectAtIndex:0] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:1] isNotPressed])) _buttonsPressedAndReleased = 5;
            else {
                if ([[_fourButtonsArray objectAtIndex:0] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:0] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:1] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:1] makeLit];
                }
            }
            break;
        case 6:  //red & green
            if (([[_fourButtonsArray objectAtIndex:0] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:2] isNotPressed])) _buttonsPressedAndReleased = 6;
            else {
                if ([[_fourButtonsArray objectAtIndex:0] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:0] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:2] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:2] makeLit];
                }
            }
            break;
        case 7:  //red & yellow
            if (([[_fourButtonsArray objectAtIndex:0] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:3] isNotPressed])) _buttonsPressedAndReleased = 7;
            else {
                if ([[_fourButtonsArray objectAtIndex:0] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:0] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:0] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:3] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:3] makeLit];
                }
            }
            break;
        case 8:  //blue & green
            if (([[_fourButtonsArray objectAtIndex:1] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:2] isNotPressed])) _buttonsPressedAndReleased = 8;
            else {
                if ([[_fourButtonsArray objectAtIndex:1] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:1] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:2] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:2] makeLit];
                }
            }
            break;
        case 9:  //blue & yellow
            if (([[_fourButtonsArray objectAtIndex:1] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:3] isNotPressed])) _buttonsPressedAndReleased = 9;
            else {
                if ([[_fourButtonsArray objectAtIndex:1] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:1] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:1] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:3] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:3] makeLit];
                }
            }
            break;
        case 10:  //green & yellow
            if (([[_fourButtonsArray objectAtIndex:2] isNotPressed]) && ([[_fourButtonsArray objectAtIndex:3] isNotPressed])) _buttonsPressedAndReleased = 10;
            else {
                if ([[_fourButtonsArray objectAtIndex:2] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:2] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:2] makeLit];
                }
                if ([[_fourButtonsArray objectAtIndex:3] isNotPressed]) {
                    [[_fourButtonsArray objectAtIndex:3] makeDisabled];
                    [[_fourButtonsArray objectAtIndex:3] makeLit];
                }
            }
            break;
        default:
            _buttonsPressedAndReleased = 0;
            break;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多