通过触摸节点SpriteKit SKAction

时间:2014-07-20 16:17:29

标签: objective-c sprite-kit

如果触摸了我的SKSpriteNode Sorcerer,我想运行SKAction。 使用我当前的代码,每当我触摸时,我的SpriteNode'stone'将移动到Sorcerer。 我可以用特定的x和y坐标来调用触摸的位置,但是由于'巫师'正在移动,我不能那样做。 我该如何解决这个问题?

- (void)Sorcerer {

Sorcerer = [SKSpriteNode spriteNodeWithImageNamed:@"Sorcerer.png"];
Sorcerer.size = CGSizeMake(85, 85);
Sorcerer.zPosition = 2;

Sorcerer.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(50, 50)];
Sorcerer.physicsBody.dynamic = NO;
Sorcerer.physicsBody.allowsRotation = NO;
Sorcerer.physicsBody.usesPreciseCollisionDetection = YES;
Sorcerer.physicsBody.restitution = 0;

Sorcerer.position = CGPointMake(self.frame.size.width * 1.25, self.frame.size.height / 2.2);

SKAction * actionMove = [SKAction moveToX:self.frame.size.width / 2 duration:10];

[Sorcerer runAction:[SKAction repeatActionForever:[SKAction sequence:@[actionMove]]]];

[self addChild:Sorcerer];

}

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

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:Sorcerer];

Stone = [SKSpriteNode spriteNodeWithImageNamed:@"Stone.png"];

Stone.position = Human.position;
Stone.zPosition = 1;
Stone.scale = 0.6;

SKAction *action = [SKAction moveTo:Sorcerer.position duration:0.5];
SKAction *remove = [SKAction removeFromParent];

[Stone runAction:[SKAction sequence:@[action,remove]]];

[self addChild:Stone];

}

2 个答案:

答案 0 :(得分:0)

//给石头或者Sorcere一个名字

通过此名称,您可以轻松访问该节点

- (void)touchesEnded:(NSSet *)触及withEvent:(UIEvent *)事件{

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];

// decide if the node is of interest or can be ignored, something like this:



if ([node.name isEqualToString:@“stone”]) {
      //apply action on stone

       }

}

答案 1 :(得分:0)

有许多情况,SKNode需要通知其场景有关某些事件或想要强制只有场景可以提供的特定行为。

当然你可以在场景中实现一个touchesEnded:方法并迭代遍历节点但是如果你在屏幕上有几千个它们呢?最简单的方法是使用委派或通知

我们将创建一个协议并将场景设置为其委托。当被触摸时,Sourcerer将调用委托的方法。让我们定义协议:

@class Sorcerer;
@protocol SorcererInteractionDelegate <NSObject>

- (void)sorcererTapped:(Sorcerer)sorcerer;

@end

将委托属性添加到Sorcerer类:

@interface Sorcerer : SKSpriteNode
@property (nonatomic, weak) id <SorcererInteractionDelegate> delegate;
@end

最后,实施touchesEnded:方法。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    if ([_delegate respondsToSelector:@selector(sorcererTapped:)])
    {
        [_delegate performSelector:@selector(sorcererTapped:)
                        withObject:self];
    }
}

请记住在userInteractionEnabled类的init方法中将YES设置为Sourcerer。 在场景中创建源代理时,请设置委托:

Sourcerer *sourcerer = ...
sourcerer.delegate = self;

并实现了sorcererTapped:方法:

- (void)sorcererTapped:(Sorcerer)sorcerer;
{
    // Do stuff with sorcerer.
}

通知

委托很酷,但如果您需要立即通知多个对象有关更改,该怎么办?然后,您应该使用通知。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    [[NSNotificationCenter defaultCenter]
             postNotificationName:@"UserDidTapSourcererNotification" object:self];
}

您的场景需要注册为@"UserDidTapSourcererNotification"通知的观察者并处理它。

 [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(handleUserDidTapSourcererNotification:)
                                                 name:@"UserDidTapSourcererNotification";
                                               object:nil]; 

- (void)handleUserDidTapSourcererNotification:(NSNotification *)notification
{
    Sorcerer *sorcerer = (Sorcerer *)[notification object];

    // Do stuff with sorcerer.
}

希望它有所帮助。