7

I am pretty new to iOS, objective C and working with Xcode. I only did one simple news type app, but now I would like to create a game I had published on another platform.

Basically, I have one object that will appear randomly and then fade out and the purpose is to tap on the object to make it go away.

However I can't seem to tap the object, even though I set mySKSpriteNode.userInteractionEnabled = YES;

Here is what I have in my touchesBegan method:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    NSLog(@"Something was touched");
    UITouch *touch = [touches anyObject];
    NSLog(@"%@", touch);
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    if(node == mySKSpriteNode)
    [node runAction:[SKAction fadeOutWithDuration:0]];

}

In my log I get this when i tap the screen (not where I have objects):

2014-02-17 23:18:30.870 BubbleChallenge[48541:70b] Something was touched
2014-02-17 23:18:30.875 BubbleChallenge[48541:70b] <UITouch: 0x1130ea530> phase: Began tap count: 1 window: <UIWindow: 0x109c2ab60; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x109c274d0>; layer = <UIWindowLayer: 0x109c26810>> view: <SKView: 0x109c2e5e0; frame = (0 0; 320 568); autoresize = RM+BM; layer = <CAEAGLLayer: 0x109c0e180>> location in window: {147.5, 128.5} previous location in window: {147.5, 128.5} location in view: {147.5, 128.5} previous location in view: {147.5, 128.5}

When I touch mySKSpriteNode I get nothing in the log, not even "Something was touched";

Any idea why this could be happening?

The other questions I found said the answer is to set userInteractionEnabled = YES.... maybe there's a specific point in the code where I should set this?..

All help is appreciated!

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Deea B
  • 301
  • 6
  • 15

4 Answers4

10

Have you tried setting the name property of your spritenode?

In your initialization for mySKSpriteNode:

mySKSpriteNode = [[SKSpriteNode alloc] initWithTexture:sometexture];
mySKSpriteNode.name = @"thisIsMySprite"; // set the name for your sprite
mySKSpriteNode.userInteractionEnabled = NO; // userInteractionEnabled should be disabled

Then:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    if ([node.name isEqualToString:@"thisIsMySprite"]) {
        NSLog(@"mySKSpriteNode was touched!");
        [node runAction:[SKAction fadeOutWithDuration:0]];
    }
}
DoctorClod
  • 323
  • 2
  • 8
  • Tried this, but still doesn't log anything. I've added NSLog(@"Something was touched"); above UITouch declaration and it only logs when I touch the screen, not the sprite. – Deea B Feb 18 '14 at 18:35
  • Thanks for the help! Issue solved with the comment below combined with your input. – Deea B Feb 18 '14 at 18:41
  • No problem. I've edited the answer to match the correct code for clarity. – DoctorClod Feb 18 '14 at 23:31
  • LOL it's the same way in Swift, i used your ObjectiveC code to detect if a sprite was touched and using Swift's syntax made it work the same way, thank you sir! – msqar Jun 23 '16 at 14:27
5

Your code is essentially correct. Just a few minor changes are required.

You have implemented the -touchesBegan: method in your scene class. If you want to handle touches from within the scene class, then all the child nodes should have the userInteractionEnabled property set to NO. A sprite node's userInteractionEnabled property should be set to YES only when it is capable of handling touches on it's own.

So, in your case you should make the following changes:

1 - Set the spriteNode's userInteraction to NO.

mySKSpriteNode.userInteractionEnabled = NO;

2 - Change the way you check for your own sprite.

if([node isEqual: mySKSpriteNode])

You will find your code is working as intended.

ZeMoon
  • 20,054
  • 5
  • 57
  • 98
  • Thanks!! That was it. As you and DoctorClod above suggested I named my node and checked the sprite in -touchesBegan: and userInteractionEnabled should be set to NO as you said. – Deea B Feb 18 '14 at 18:39
1

In Swift 2.0!

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

  let touch = touches.first!
  let location = touch.locationInNode(self)
  let node = self.nodeAtPoint(location)

  if node.name == "spriteName" {
    // Present new game scene
  }
}
lovelikelando
  • 7,593
  • 6
  • 32
  • 50
0

I never used the SKSprite framework but I will try to help. First, your function "-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event" has to be set in your custom SKSpriteNode class, if not it's normal if that doesn't work.

If it's already done, you have to search where the tap is handle (by an other object) then you can use : "- (BOOL)gestureRecognizer:(UIPanGestureRecognizer )gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer)otherGestureRecognizer"

hope that will help !

Nicolas Bonnet
  • 1,275
  • 11
  • 15