Reputation:
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
Upvotes: 1
Views: 570
Reputation: 34513
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")
}
}
}
}
Upvotes: 0
Reputation: 1176
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 :)
Upvotes: 0
Reputation: 12753
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;
}
}
Upvotes: 1
Reputation: 20710
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.
Upvotes: 0