Frage

Ich würde gerne wissen, wie zu erkennen und zwischen Berührungen in einer Multi-Touch-Ansicht zu unterscheiden. Ich habe von einem „Hash“ Code lesen, aber ich verstehe nicht, wie es zu benutzen. Ich möchte wissen, wenn zwei meiner Sprites sind zugleich berührt, wie als ob Sie einen Akkord auf zwei Tasten eines Klaviers drücken.

[EDIT] Hier ist ein Beispiel dafür, was ich für meine 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;
                                }

        }
    }
  }
}

Und hier ist der Anfang meiner 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];
        }


    }
}

Könnten Sie mir vielleicht ein Beispiel, wie Sie berührt erfassen würde, die auf einem Sprite begann und auf ein Sprite zu Ende? Ich habe zu kämpfen und kann den Hash-Code zur Arbeit nicht bekommen - einfach nicht verstehen, wie der Hash-Code verwendet werden kann, später einen Hauch zu verweisen. Ich denke, was ich zu machen versuchen, einen Hash-Tracker genannt werden würde?

Ich bin sicher, gibt es einen viel weniger gewundenen Weg, es zu tun, um den Hash-Codes und weniger Zustandsvariablen verwendet wird. Ich habe nicht die ccTouchesEnded Methode mit den anderen Zustandsvariablen Effekte konkretisiert, weil ich hoffte, einen einfacheren Weg zu finden (ich weiß, dass ich immer noch die ccTouchesMoved und zu Abgebrochen Methoden machen müssen).

War es hilfreich?

Lösung 2

Hier ist, wie ich realisierte dies, falls jemand versucht, dies zu tun (ich habe es beschränkt auf 2-Tasten-Kombinationen, aber ich konnte die Logik 3 & 4-Tasten-Kombinationen als auch leicht erweitern). Ich entschied ich für jede Note einzeln zu handhaben mit dem ccTouchBegan / Ended / Verschoben anstelle der ccTouchesBegan / Ended / die Verwendung verschoben, weil ich kann es einfach nicht zur Arbeit mit dem Hash-Code erhalten. Alle mögliche alternative Ideen wäre willkommen.

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

#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 (Nur mein tick: Methode meiner andere Funktionen, um zu verhindern verwirrend das Beispiel)

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

Andere Tipps

Angenommen, Sie zwei Berührungen haben. Sie erhalten einen Aufsetzpunkt Ereignis für die beiden, sagen bei (1,1) und (2,2). Nehmen wir an, der Benutzer die Seiten beide Finger, Sie dann ein anderes Ereignis, aber diesmal vielleicht bei (3,3) und (4,4).

Die Frage ist, tat (1,1) Umzug nach (3,3) und (2,2) bewegen zu (4,4) - oder hat das Gegenteil geschehen - wo (1,1) bewegt (4 , 4) und (2,2) bewegt zu (3,3).

Dies ist, was der „Hash-Code“ verwendet wird - jede Note geben einen „Namen.“ - so kann man sagen, was das passiert insbesondere berühren wie die folgenden Ereignisse sind für sie erzeugt

Also für Ihren Fall würden Sie die Touch-Events - Blick auf die Koordinaten und bestimmen, welche Taste für jede gedrückt wird. Sie halten dann den Überblick über die Hash für jede Note, um zu bestimmen, wenn sie (das heißt die besondere Klaviertaste) berühren freigegeben wird.

Sie können die Koordinaten für diese, weil zu Koordinaten können Veränderung als Finger glitten werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top