2010-10-24 4 views
1

J'écris une application pour l'iPhone en utilisant cocos2d où j'ai 4 Sprites qui sont des boutons. J'ai pensé que j'implémenterais la fonctionnalité du bouton en utilisant 2 sprites avec différents fichiers .png représentant les états pressés/non pressés. Je pensais que ce serait mieux que d'utiliser une animation. En plus de détecter quand les boutons sont pressés et relâchés, j'ai besoin de détecter quand une combinaison de deux boutons presser/relâcher se produit (comme un accord). Je pourrais même porter ceci vers l'avant aux combinaisons de 3 et 4 boutons. Et une autre fonctionnalité que je voudrais mettre en œuvre serait de détecter si un film provient d'un bouton et répond avec une autre séquence d'action.Simultanée Détection tactile Sprite - iPhone & cocos2d

Quelle serait une approche optimale pour cela? Est-ce que j'utiliserais un rectangle de délimitation/ou un sprite pour les quatre boutons (ils sont dans une formation carrée) et avaler des touches? Alors, est-ce que j'utiliserais les plus petits sprints pour déterminer le (s) quel (s) le (s) touché (s) est arrivé (s)? Ou aurais-je les sprints individuels faire la détection et ensuite les faire vérifier pour voir si les autres boutons sont également pressés puis relâchés en même temps? Aurais-je utiliser une variable d'état Bool pour l'une ou l'autre de ces façons? J'ai eu tout ce qui fonctionne bien en utilisant CCMenu et CCMenuitem, en faisant un menu/élément de menu pour chaque sprite de bouton; Cependant, je ne pouvais pas comprendre comment détecter si un élément de menu d'un menu était pressé et relâché en même temps qu'un élément de menu d'un menu différent était pressé et relâché. J'ai utilisé des menus séparés car si j'utilisais le même menu avec plusieurs éléments de menu, un seul pouvait être pressé à la fois. Je dis que cela fonctionnait bien, ce qui signifiait qu'il fonctionnait avec des presses simples et multiples, mais il traiterait les multiples comme deux presses successives au lieu d'une pression simultanée. IE: une seule presse a entraîné l'exécution d'une seule séquence d'action (comme prévu), et une combinaison de presse simultanée a entraîné l'exécution de séquences d'action individuelles pour chaque bouton comme si je les avais pressées séparément (je veux exécuter une séquence d'actions spécifique à cette combinaison de boutons). C'est pourquoi j'ai décidé qu'il serait peut-être préférable d'essayer d'implémenter mon propre système de boutons au lieu d'utiliser le système CCMenu. Ai-je raison de m'éloigner de CCMenu?

Désolé pour la description longue, mais elle a été vraiment spécifique. B)

Tout aperçu de la façon dont quelqu'un d'autre mis en œuvre ou implémenterait ce serait grandement apprécié!

+0

Vous avez des idées? S'il vous plait aidez si vous le pouvez. – Mark7777G

+0

désolé, je suis un peu occupé ici. Je peux également vous recommander de copier et coller cette question dans gamedev.stackexchange.com? il y aura plus d'avis de jeu :) des excuses. –

+0

J'ai essayé de poster là aussi, merci. – Mark7777G

Répondre

2

Voici comment j'ai implémenté ceci au cas où quelqu'un d'autre essaye de le faire.

spuButton.h (un CCSprite Sous)

#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 (Juste ma tique: méthode pour garder mes autres fonctions de confondre l'exemple)

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