Sprite Kit 只允许一键式

Posted

技术标签:

【中文标题】Sprite Kit 只允许一键式【英文标题】:Sprite Kit only allow one touch 【发布时间】:2014-02-07 13:52:19 【问题描述】:

我已经寻找了一个类似的问题,但没有找到,所以如果已经有人问过这个问题,我深表歉意,但是我在限制 SKScene 允许我进行的触摸数量方面遇到了问题。我已经实现了 touchesBegan:withEvent: 方法,并为动画设置了我的 SKAction(s),但是我想要的是在精灵节点动画时,我不希望它能够接受另一个触摸.

我试图计算正在发生的触摸次数,但无论如何都不起作用,所以我在一个停止点。

所以,我的基本问题是:如何在我的场景中创建“一次触摸,然后等待动画结束后再进行另一次触摸”?

代码如下:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
/* Called when a touch begins */

SKAction *jump = [SKAction moveToY:400 duration:.4];
SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
SKAction *action = [SKAction sequence:@[jump, down]];

for (UITouch *touch in touches) 
    NSInteger touchesMax = 1;
    NSInteger actualTouches = [touches count];
    NSLog(@"%ld", (long)actualTouches);

    actualTouches++;

    if (actualTouches > touchesMax) 
        [farmer removeAllActions];
    
    else 
        [farmer runAction:action];
    


感谢任何帮助

【问题讨论】:

您可以尝试将变量“actualTouches”创建为该方法的全局变量。由于可能是由于 actualTouches 变量正在重新初始化。 【参考方案1】:

我相信这会奏效。在touchesBegan开头做

self.userInteractionEnabled = NO;

然后定义一个新的SKAction 来启用用户交互:

SKAction *enable = [SKAction runBlock:^ self.userInteractionEnabled = YES; ];

将其添加到您的序列中:

SKAction *action = [SKAction sequence:@[jump, down, enable]];

【讨论】:

感谢您的提示,这对我很有用。但是,请注意,运行 removeAllActions 会阻止重新启用触摸。【参考方案2】:

最简单的解决方案:

如何在我的场景中创建“一次触摸,然后等待动画结束后再进行另一次触摸”?

是在启动动画时使用[self setUserInteractionEnabled:NO];禁用触摸

并在动画完成后重新启用它。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    /* Called when a touch begins */

    SKAction *jump = [SKAction moveToY:400 duration:.4];
    SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
    SKAction *action = [SKAction sequence:@[jump, down]];

    [self setUserInteractionEnabled:NO];

    [farmer runAction:action completion^
          [self setUserInteractionEnabled:YES];
    ];

现在,如果您仍想拥有触摸功能,只需不执行操作即可。 将属性添加到您的场景中,我们称之为动画。

@property (nonatomic,assign)BOOL animating;

然后更改您的代码以考虑此值:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    /* Called when a touch begins */

    SKAction *jump = [SKAction moveToY:400 duration:.4];
    SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
    SKAction *action = [SKAction sequence:@[jump, down]];

    self.animating = YES;
    [farmer runAction:action completion^
        self.animating = NO;
    ];


这种方式在动作运行时动画标志将为YES,完成后将设置为NO,并且可以运行新动作。

【讨论】:

【参考方案3】:

您不必那样检查。您可以在 SKSpriteNode 上使用 runAcrion:forKey,然后您可以查看操作是否正在运行:

if (![farmer actionForKey:@"ActionKey"])
    [farmer runAction: runAction:action withKey:@"ActionKey"]

现在,如果精灵没有运行它,你只需运行它。

【讨论】:

【参考方案4】:

查看本教程: http://www.raywenderlich.com/44270/sprite-kit-tutorial-how-to-drag-and-drop-sprites

它在那里实现 - 一旦精灵被触摸并移动,再次触摸并没有任何反应。

【讨论】:

以上是关于Sprite Kit 只允许一键式的主要内容,如果未能解决你的问题,请参考以下文章

Sprite Kit:为所有场景只创建一次节点

背景图像大小 Sprite Kit 游戏

如何在 sprite kit 中引用多个同名的 sprite?

Sprite Kit,删除 Sprite 以进行碰撞

Sprite Kit 场景未呈现

swift 2 sprite-kit 中的多行标签?