Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3791212
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 19, 20262026-05-19T12:26:06+00:00 2026-05-19T12:26:06+00:00

I would like to know how to detect and differentiate between touches in a

  • 0

I would like to know how to detect and differentiate between touches in a multi-touch view. 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.

[EDIT]
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;
                                }

        }
    }
  }
}

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?

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).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-19T12:26:07+00:00Added an answer on May 19, 2026 at 12:26 pm

    Here is how I implemented this 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 (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 (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;
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to know if there is an easy way to detect if
I would like to know how to detect that a node is not present
I would like to know whether it a possible to detect whether a HTML
I would like to know if there is a possibility to detect if the
i have this issue working but i would like to know if there is
I would like to detect strings that have non-whitespace characters in them. Right now
Greetings, I would like to detect if a segment only 'touches' a polygon or
I would like to know if I can open 2 different diagrams using MS
I would like to know which dependency described in my pom.xml brings a transitive
I would like to know what semaphores, messageQueues, etc... are active in my vxWorks

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.