使用iPhone的Cocos2d中的哈希代码跟踪多个触摸

你如何实现触摸哈希码,并在以后参考? 我已经阅读了一个“散列”代码,但我不明白如何使用它。 我想知道当我的两个精灵同时被触摸时,就像在钢琴的两个键上按下一个和弦一样。

这里是我的ccTouchesBegan的例子:

- (void) ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { NSSet *allTouches = [event allTouches]; int validTouchCount = 0; for (UITouch* touch in allTouches) { BOOL touchIsValid = FALSE; CGPoint location = [touch locationInView: [touch view]]; CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location]; if (CGRectContainsPoint(_fourButtonsRect, convertedLocation)) { NSLog(@"Touch is within four buttons"); touchIsValid = TRUE; } _playerDidAction = 0; NSLog(@"before the loop"); if (touchIsValid) { validTouchCount++; NSLog(@"Within ValidTouches loop"); CGPoint validLocation = [touch locationInView: [touch view]]; CGPoint convertedValidLocation = [[CCDirector sharedDirector] convertToGL:validLocation]; if (CGRectContainsPoint(_redButtonSprite.boundingBox, convertedValidLocation)) { _redButtonStatus = TRUE; [_redButtonSprite setTexture:_redButtonLit]; if (validTouchCount == 1) { _playerDidAction = 1; } } else if (CGRectContainsPoint(_blueButtonSprite.boundingBox, convertedValidLocation)) { _blueButtonStatus = TRUE; [_blueButtonSprite setTexture:_blueButtonLit]; if (validTouchCount == 1) { _playerDidAction = 2; } } else if (CGRectContainsPoint(_greenButtonSprite.boundingBox, convertedValidLocation)) { _greenButtonStatus = TRUE; [_greenButtonSprite setTexture:_greenButtonLit]; if (validTouchCount == 1) { _playerDidAction = 3; } } else if (CGRectContainsPoint(_yellowButtonSprite.boundingBox, convertedValidLocation)) { _yellowButtonStatus = TRUE; [_yellowButtonSprite setTexture:_yellowButtonLit]; if (validTouchCount == 1) { _playerDidAction = 4; } } if (validTouchCount > 1) { if (_redButtonStatus && _blueButtonStatus) { _comboRB = TRUE; _playerDidAction = 5; } else if (_redButtonStatus && _greenButtonStatus) { _comboRG = TRUE; _playerDidAction = 6; } else if (_redButtonStatus && _yellowButtonStatus) { _comboRY = TRUE; _playerDidAction = 7; } else if (_blueButtonStatus && _greenButtonStatus) { _comboBG = TRUE; _playerDidAction = 8; } else if (_blueButtonStatus && _yellowButtonStatus) { _comboBY = TRUE; _playerDidAction = 9; } else if (_greenButtonStatus && _yellowButtonStatus) { _comboGY = TRUE; _playerDidAction = 10; } } } } } 

这是我的ccTouchesEnded的开始:

 - (void)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { for (UITouch *touch in touches) { CGPoint location = [touch locationInView: [touch view]]; CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location]; if (CGRectContainsPoint(_redButtonSprite.boundingBox, convertedLocation)) { _redButtonStatus = FALSE; [_redButtonSprite setTexture:_redButtonNormal]; } if (CGRectContainsPoint(_blueButtonSprite.boundingBox, convertedLocation)) { _blueButtonStatus = FALSE; [_blueButtonSprite setTexture:_blueButtonNormal]; } if (CGRectContainsPoint(_greenButtonSprite.boundingBox, convertedLocation)) { _greenButtonStatus = FALSE; [_greenButtonSprite setTexture:_greenButtonNormal]; } if (CGRectContainsPoint(_yellowButtonSprite.boundingBox, convertedLocation)) { _yellowButtonStatus = FALSE; [_yellowButtonSprite setTexture:_yellowButtonNormal]; } } } 

你可以给我一个例子,我将如何在touchesBegan中对哈希代码的捕获进行编码,然后在touchesEnded中引用哈希代码? 我一直在挣扎,无法使哈希码工作 – 只是不理解如何使用哈希码来引用稍后的触摸。 我想我想做什么将被称为哈希跟踪?

我确信使用散列码和更less的状态variables来做这件事情的方式要简单得多。 我还没有充实ccTouchesEnded方法与其他状态variables效果,因为我希望find一个更简单的方法(我知道我仍然需要制作ccTouchesMoved和取消方法)。

任何建议将非常赞赏,因为我卡住了! B)

为了减lessif语句的数量,您需要将数据驱动为您的解决scheme,而不是为需要交互的每个UI组件手动添加逻辑。

你可以通过将你的button数据(比如每个button的边界框和状态)存储在一个结构数组或类的NSArray(或NSMutableArray )中。 然后当你收到一个触摸,你只需要遍历列表,看看是否有触摸是在边界框内,如果它然后更新对象的纹理。

为了跟踪他们生命中的触摸,我使用一个NSMutableDictionary (触摸指针作为键)和一个自定义类作为它的值。 这允许我存储每次触摸的信息(例如,如果我已经处理了它),并对持有而不移动的触摸作出反应。

我猜你正在拼命input所有这些如果陈述。

也许一个简单的除了你现在已经做的事情就是向你的精灵类添加一个setStatus方法。 也使得sprite对象跟踪它的状态TRUE和状态FALSE纹理是什么。 那么你可以迭代通过触摸,并检查所有的对象在一个单一的setState调用循环。

除非你有一百万个精灵,否则它可能不会比你现在正在做的事更慢。

即时通讯不能确定你在这个例子中的哈希代码是什么意思?

这里是我如何实现这一点,以防其他人试图做到这一点(我已经限制为2键组合,但我可以很容易地将逻辑扩展到3和4button组合)以及。 我select使用ccTouchBegan / Ended / Moved单独处理每个触摸,而不是使用ccTouchesBegan / Ended / Moved,因为我只是无法让它与哈希码一起工作。 任何替代的想法都会受到欢迎。

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(只是我的tick:方法让我的其他函数不会混淆这个例子)

 -(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; } }