在cocos2d中,如何实现触摸哈希码并在以后引用它?

时间:2010-11-06 01:11:10

标签: iphone cocos2d-iphone detection hashcode multi-touch

如何实现触摸哈希码并在以后引用?我读过有关“哈希”代码的内容,但我不明白如何使用它。我想知道我的两个精灵何时被同时触摸,就好像在钢琴的两个琴键上按下一个和弦一样。

以下是我对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];
        }


    }
}

你能不能给我一个例子,说明如何捕捉从精灵开始并以雪碧结束的触摸?我一直在努力,无法使哈希码工作 - 只是不了解哈希代码如何用于以后引用触摸。我想我想做的事情会被称为哈希跟踪器吗?

我确信使用哈希码和更少的状态变量可以解决这个问题。我还没有使用其他状态变量效果充实ccTouchesEnded方法,因为我希望找到一种更简单的方法(我知道我仍然需要制作ccTouchesMoved和Canceled方法)。

任何建议都会非常感激!

2 个答案:

答案 0 :(得分:2)

[touch hash]返回唯一标识触摸的哈希码。使用它,您可以通过多个事件(即向下,向上和向上)跟踪特定触摸,以区分多个触摸。

因此,例如,当您收到“向下”事件时,使用与之关联的精灵记录每次触摸的哈希值。然后在随后的move和up事件中,使用这些事件的散列来查找每个引用的精灵。

示例:我有两次触摸,(1,1)触摸精灵“A”和(2,2)触摸精灵“B”。下一个事件告诉我,有两个触摸被拖到(3,3)和(4,4)。

问题是,“A”是否被拖到(3,3)和“B”到(4,4)或反之亦然?如果您记录了原始触摸的底部并用精灵记录它们,触摸的底部可以指向您回到相应的精灵。

答案 1 :(得分:0)

以下是我如何实现这个[我没有使用HASH代码,因为我无法让它工作]以防其他人试图这样做(我将其限制为2键组合但我可以轻松扩展3& 4按钮组合的逻辑)。我选择使用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;
 }
}