1

I have been trying to make a simple app where when you tap a circle, it will disappear, and a new one will come up somewhere else.

Here is all my code, edited, but it still does not work.

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {



[self LabelShow];
}

int Count = 0;
int CountCheck = 0;

-(void) LabelShow {

//Nothing yet

}



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


while (CountCheck == Count) {

int FNum1 = 350;
int TNum1 = 650;
int newx = (arc4random()%(TNum1-FNum1))+FNum1;

NSLog(@"RandomXCoord: %i", newx);

int FNum2 = 100;
int TNum2 = 700;
int newy = (arc4random()%(TNum2-FNum2))+FNum2;
NSLog(@"RandomYCoord: %i", newy);

//Location to newx and newy
CGPoint location =  CGPointMake(newx, newy);


SKSpriteNode *Circle = [SKSpriteNode spriteNodeWithImageNamed:@"Circle.png"];

Circle.xScale = 0.2;
Circle.yScale = 0.2;
Circle.position = location;


//Shows chircle

[self addChild:Circle];
CountCheck++;




for (UITouch *touch in touches)
        {
            CGPoint locationTouch = [touch locationInNode:self];

            if ([Circle containsPoint:locationTouch]) {

                    NSLog(@"Success!");
                    [Circle runAction:[SKAction fadeOutWithDuration:0]];
                    Count++;
            }
        }

}
}
@end

As I stated, I have the code that puts the circle on the screen in another method. But whenever I run this code (click the circle), the if statement at the bottom does not get executed.

I tried all the things in this thread: Can't tap SKSpriteNode - no touch detected ios , but I can't get it to work still, and have changed the code back to the original.

Could anyone tell me how I could be able to get the if statement executed when you tap the SKSpriteNode?

Thank you for reading this question.

Edit I changed the code, but it still doesn't work

Community
  • 1
  • 1
  • 1) you didn't add Circle to the scene, 2) you aren't specifying the position of Circle, and 3) you are comparing node.name, a string, with Circle, an SKSpriteNode; it should be @"Circle". – 0x141E Nov 18 '14 at 21:52
  • Please add Edit at the top, If you use everything from my answer and comments so we know u change your code. – Jakub Truhlář Nov 19 '14 at 11:03

4 Answers4

1

Add the following above your Circle.xScale = 0.2; statement

Circle.name = @"Circle";

and replace your for-loop with the following

for (UITouch *touch in touches) {
    CGPoint location = [touch locationInNode:self];

    SKNode *node = [self nodeAtPoint:location];
    if ([node.name isEqualToString:@"Circle"]) {
        NSLog(@"Success!");
        [node removeFromParent];
        ++Count;
    }
}
0x141E
  • 12,613
  • 2
  • 41
  • 54
0

What you need is containsPoint method.

Here is the touchesBeganWithEvent: method you are looking for:

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

    for (UITouch *touch in touches)
        {
            CGPoint location = [touch locationInNode:self];

            if ([circle containsPoint:location] {
               // executed when you touch a circle
            }
        }
}

Note that you can add more statements and conditions.

Jakub Truhlář
  • 20,070
  • 9
  • 74
  • 84
  • First: If I edit your code in your Question (bcs SKSpriteNode *Circle is not following the convention), take it. Second: What exactly is not working, you ask for help then give us a feedback, because this code works perfectly. You have probably a problem with your implementation – Jakub Truhlář Nov 18 '14 at 21:19
  • Basically, would I need to 'declare' the sprite node just under the touchesBegan: method? –  Nov 19 '14 at 07:11
  • Basic logic tells you that my code should be the first, then do everything else. I see you declare everything in one method, which is quite confusing and also still not fallowing convention. – Jakub Truhlář Nov 19 '14 at 10:59
0

I created a game for myself, and I had to do the same thing for a character in it. I subclassed SKNode, and added the character details (SKSpriteNode, name, SKAction, etc) in the subclassed model. Then I added the UITouchBegin method to the subclass, so my character would listen to touches.

It is a lot easier to use subclassing, as you can leave all the legwork to the subclass, and focus on the rest of your game. Adding this code to your subclass will take care of it all:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self removeFromParent];
}

You can even set your scene as your character class's delegate, and as soon as the character is removed from parentview, you can create a new one.

If you get stuck on the subclass issues, this answer really helped me out. Let me know if any questions and good luck :)

Community
  • 1
  • 1
Septronic
  • 1,156
  • 13
  • 32
0

The other responses seem to detect touches on a SKSpriteNode, not a tap. This code detects tap events.

Edit TapMaxDelta to change how much movement is allowed before cancelling the tap gesture.

class TapNode : SKSpriteNode {

    // Tap Vars
    var firstPoint : CGPoint?
    var TapMaxDelta = CGFloat(10)


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    init() {
        let texture = SKTexture(imageNamed: "Test.png")
        super.init(texture: texture, color: UIColor.clear, size: texture.size())

        isUserInteractionEnabled = true
    }


    // ================================================================================================
    // Touch Functions
    // ================================================================================================
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first {
            firstPoint = firstTouch.location(in: self)
        }
    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {}


    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first, let firstPoint = firstPoint {
            let curPoint = firstTouch.location(in: self)

            if abs(curPoint.x - firstPoint.x) <= TapMaxDelta && abs(curPoint.y - firstPoint.y) <= TapMaxDelta {
                print("tap yo")
            }
        }
    }
}
Crashalot
  • 33,605
  • 61
  • 269
  • 439