在 cocos2d 中如何实现 touch hash code 并在后面引用呢?

In cocos2d how do you implement a touch hash code and reference it later?(在 cocos2d 中如何实现 touch hash code 并在后面引用呢?)

本文介绍了在 cocos2d 中如何实现 touch hash code 并在后面引用呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do you implement a touch hash code and reference it later? I have read about a "hash" code, but I don't understand how to use it. I want to know when two of my Sprites are touched at the same time, like as if pressing a chord on two keys of a piano.

以下是我的 ccTouchesBegan 示例:

Here is an example of what I have for my 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 的开始:

And here is the beginning of my 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];
        }


    }
}

您能否举个例子说明如何捕捉从精灵开始到精灵结束的触摸?我一直在苦苦挣扎,无法让哈希码工作 - 只是不明白如何使用哈希码来引用稍后的触摸.我猜我正在尝试制作的东西会被称为哈希跟踪器?

Could you maybe give me an example of how you would capture touches that began on a sprite and ended on a sprite? I have been struggling and can't get the hash code to work - just not understanding how the hash code can be used to reference a touch later. I guess what I'm trying to make would be called a hash tracker?

我确信使用散列码和更少的状态变量可以使用一种不那么复杂的方法.我没有用其他状态变量效果来充实 ccTouchesEnded 方法,因为我希望找到一种更简单的方法(我知道我仍然需要制作 ccTouchesMoved 和 Canceled 方法).

I am sure there is a much less convoluted way to do it using the hash codes and less state variables. I haven't fleshed out the ccTouchesEnded method with the other state variable effects because I was hoping to find a simpler way (I know I still need to make the ccTouchesMoved and Canceled methods too).

任何建议将不胜感激!

推荐答案

这是我如何实现的 [我没有使用哈希码,因为我无法让它工作],以防其他人尝试这样做(我已将其限制为 2 键组合,但我也可以轻松地将逻辑扩展到 3 和 4 键组合).我选择使用 ccTouchBegan/Ended/Moved 而不是使用 ccTouchesBegan/Ended/Moved 单独处理每个触摸,因为我无法让它与哈希码一起使用.欢迎任何替代想法.

Here is how I implemented this [I DID NOT USE A HASH CODE because I could not get it to work] in case anyone else is trying to do this (I have limited it to 2-button combos but I could easily extend the logic to 3 & 4-button combos as well). I chose to handle each touch individually using the ccTouchBegan/Ended/Moved instead of using the ccTouchesBegan/Ended/Moved because I just couldn't get it to work with the hash code. Any alternative ideas would be welcome.

spuButton.h(CCSprite 子类)

spuButton.h (a CCSprite Subclass)

#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

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(只是我的记号:防止我的其他函数混淆示例的方法)

HelloWorldScene.m (Just my tick: method to keep my other functions from confusing the example)

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

这篇关于在 cocos2d 中如何实现 touch hash code 并在后面引用呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:在 cocos2d 中如何实现 touch hash code 并在后面引用呢?