【问题标题】:SpriteKit SKAction by touching a NodeSpriteKit SKAction 通过触摸节点
【发布时间】:2014-07-21 16:27:32
【问题描述】:

如果我的 SKSpriteNode Sorcerer 被触摸,我想运行一个 SKAction。 使用我当前的代码,每当我触摸时,我的 SpriteNode “石头”都会移动到 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];

}

【问题讨论】:

    标签: objective-c sprite-kit


    【解决方案1】:

    在很多情况下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];
        }
    }
    

    记得在 Sourcerer 类的 init 方法中将 userInteractionEnabled 设置为 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.
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      //给石头或巫师起个名字

      通过这个名字你可以很容易地访问那个节点

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

      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
      
             }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-23
        • 1970-01-01
        • 2014-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多