0

I've been stuck on this problem for days. What I have is multiple SKSpriteNode's, one for a left arrow, right arrow and up arrow. When I hold down the right arrow I want my character to continue moving right while its being held down, on the other hand if you press the up Arrow then you will only jump once regardless of if you hold it down. So my problem for example is when i hold the right arrow and then i press the up arrow, touchesEnded is called and it stops my character from moving right even though I still have my finger on the right arrow

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesBegan:touches withEvent:event];

for (UITouch *touch in touches){


    CGPoint location = [touch locationInNode:self];


if (CGRectContainsPoint(rightArrow.frame, location)){

    [wizard setTexture:[SKTexture textureWithImageNamed:@"wizardRight"]];

    didTouchRightArrow = YES;
    isLookingRight = YES;
    isLookingLeft = NO;

    rightArrow.alpha = 0.5;
    NSLog(@"Touching right");

}

if (CGRectContainsPoint(leftArrow.frame, location)){

    [wizard setTexture:[SKTexture textureWithImageNamed:@"wizardLeft"]];

    isLookingRight = NO;
    isLookingLeft = YES;
    didTouchLeftArrow = YES;
    leftArrow.alpha = 0.5;
    NSLog(@"Touching left");

}

if (CGRectContainsPoint(upArrow.frame, location)){

    didTouchUpArrow = YES;
    upArrow.alpha = 0.5;
    NSLog(@"Touching up");

}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesBegan:touches withEvent:event];

if (rightArrow.alpha != 1.0){
    rightArrow.alpha = 1.0;
}
if (leftArrow.alpha != 1.0){
    leftArrow.alpha = 1.0;
}
if (upArrow.alpha != 1.0){
    upArrow.alpha = 1.0;

for (UITouch *touch in touches){

    CGPoint location = [touch locationInNode:self];

    if (CGRectContainsPoint(rightArrow.frame, location)){

        NSLog(@"Touching right");
        didTouchRightArrow = YES;
    } {

        NSLog(@"Not touching right");
        didTouchRightArrow = NO;
    }

    if (CGRectContainsPoint(leftArrow.frame, location)){

        NSLog(@"Touching Left");
        didTouchLeftArrow = YES;

    } else {

        NSLog(@"not touching left");
        didTouchLeftArrow = NO;
    }

    didTouchUpArrow = NO;



}

This may not be the right way to approach the problem, but in touchesEnded I am trying to see if the touch is still in the desired Rect.

sangony
  • 11,636
  • 4
  • 39
  • 55
Xsv23
  • 81
  • 1
  • 1
  • 6

1 Answers1

0

You need a way to identify the different nodes which are registering a touch. There is more than one way to do this but I have always found using the name property of a node to be the simplest and easiest to work with.

You already have the right idea by using the BOOLs to register the touch states.

I wrote some code to handle what you are trying to accomplish:

#import "GameScene.h"

@implementation GameScene {

    SKSpriteNode *node0;
    SKSpriteNode *node1;
    BOOL node0touch;
    BOOL node1touch;
}

-(void)didMoveToView:(SKView *)view {
    self.backgroundColor = [SKColor blackColor];

    node0 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
    node0.name = @"node0";
    node0.position = CGPointMake(100, 300);
    [self addChild:node0];

    node1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(100, 100)];
    node1.name = @"node1";
    node1.position = CGPointMake(400, 300);
    [self addChild:node1];

    node0touch = false;
    node1touch = false;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:touchLocation];

        if([node.name isEqualToString:@"node0"])
            node0touch = true;

        if([node.name isEqualToString:@"node1"])
            node1touch = true;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:touchLocation];

        if([node.name isEqualToString:@"node0"])
            node0touch = false;

        if([node.name isEqualToString:@"node1"])
            node1touch = false;
    }
}

-(void)update:(CFTimeInterval)currentTime {

    if(node0touch)
        NSLog(@"node0 touch");

    if(node1touch)
        NSLog(@"node1 touch"); 
}
sangony
  • 11,636
  • 4
  • 39
  • 55
  • Thank you! it worked! I just have a question about the touchesEnded part. I don't understand why the if statements work here. Can you explain why because it seems like it shouldn't work. – Xsv23 Mar 29 '15 at 15:43
  • @Xsv23 - The touchesEnded is basically the same as the touchesBegan or touchesMoved. Just different call states. The for loop in all the touches methods loops through all the touches currently registered. Remember there can be more than one touch at a time, hence the loop. The if statement checks the previously declared node's name property for a match. As we have 2 nodes with differently declared names, it has the ability to differentiate between the 2 using the string comparison "isEqualToString". – sangony Mar 29 '15 at 16:01
  • ok that makes sense. Thank you! One more question. I am trying to implement touchesMoved because if you touch the node and move your finger out of the node's rect then the variable will still be true. How would you implement this so that it detects if your finger is still in the rect when your finger moves? @sangony – Xsv23 Mar 29 '15 at 17:26
  • @Xsv23 - Exact same principal as began and ended. Use the for loop and check for each node's contact state. – sangony Mar 29 '15 at 17:32