如何在Spritekit中使用NSTimer触发操作?

时间:2016-04-15 21:01:20

标签: swift sprite-kit swift2

我试图让我的"播放器" (通过运行计时器触摸屏幕后,(中间的圆圈)增大尺寸。

一旦计时器超过0秒,它的大小就会增加。一旦计时器超过3秒,它就会减小到原来的刻度尺寸,一旦计时器超过7秒,它就会重置,并且会一直重复。

我做错了什么?

[TestClass]
public class MyTestClass
{
     [TestMethod]
     public void Test()
     {
         var fixture = new Fixture().Customize(new AutoMoqCustomization());

         var objMock = fixture.Freeze<Mock<IObject>>();
         var sut = fixture.Create<Dependant2>();

         sut.Obj.Should().BeSameAs(objMock);
     }
}

public interface IObject { }

public interface IDependant { IObject Obj { get; } }

public class MyObject : IObject { }

public class Dependant2
{
    public Dependant2(IDependant dependant)
    {
       Obj = dependant.Obj; 
    }

    public IObject Obj { get; }
}

1 个答案:

答案 0 :(得分:1)

这可以通过几种不同的方式完成:

1)使用SKActions(我的示例使用)

2)使用update:方法及其传递的currentTime参数

3)使用我不推荐的NSTimer,因为它不受场景,视图或节点的暂停状态的影响,所以它可能会让你在将来遇到麻烦。阅读StackOverflow answer

中的更多内容

4)好吧,可能还有一些,但我会在这里停下来。

我的示例使用SKAction。这意味着我并没有真正检查传递了多少时间,而是将动作组织成序列(其中动作按顺序执行)和组织(动作并行组织)。意思是我使用SKActions就像我正在玩LEGO's :)

以下是代码...我故意留下调试代码,因为它可以帮助您了解如何在不同情况下使用SKActions

class GameScene: SKScene, SKPhysicsContactDelegate {

    let player = SKSpriteNode(color: .blackColor(), size: CGSize(width: 50, height: 50))

    var timePassed = 0.0 {
        didSet {
            self.label.text = String(format: "%.1f",timePassed)
        }
    }

    let label = SKLabelNode(fontNamed: "ArialMT")

    override func didMoveToView(view: SKView) {

        /* Debugging - Not really needed, I added it just because of a better example */
        let wait = SKAction.waitForDuration(0.1)

        let updateLabel = SKAction.runBlock({[unowned self] in self.timePassed += wait.duration})

        self.label.position = CGPoint(x: frame.midX, y: frame.midY+100.0)
        addChild(self.label)
        let timerSequence = SKAction.sequence([updateLabel, wait])
        self.runAction(SKAction.repeatActionForever(timerSequence), withKey: "counting")

        //This is used later, at the end of scaleUpAndDownSequence to reset the timer
        let resetTimer = SKAction.runBlock({[unowned self] in self.timePassed = 0.0})


        /* End Debugging */


        self.player.position = CGPoint(x: frame.midX, y: frame.midY)
        addChild(self.player)

        let waitBeforeScaleToOriginalSize = SKAction.waitForDuration(3.0)
        let waitBeforeRestart = SKAction.waitForDuration(4.0)

        let scaleUp = SKAction.scaleTo(2.0, duration: 1)
        let scaleDown = SKAction.scaleTo(1.0, duration: 1)

        let scaleUpGroup = SKAction.group([waitBeforeScaleToOriginalSize, scaleUp])
        let scaleDownGroup = SKAction.group([scaleDown, waitBeforeRestart])

        //One cycle, scale up, scale down, reset timer
        let scaleUpAndDownSequence = SKAction.sequence([scaleUpGroup, scaleDownGroup, resetTimer])

        let loop = SKAction.repeatActionForever(scaleUpAndDownSequence)

        self.player.runAction(loop, withKey: "scalingUpAndDown")
    }
}

所以在这里,我有两组行动:

1)scaleUpGroup

2)scaleDownGroup

scaleUpGroup一组操作中包含两个操作:一个scaleUp操作,以及一个操作,指出在缩小操作发生之前需要等待多少。因为我们希望立即进行扩展,所以我们将其与waitBeforeScaleToOriginalSize并行运行。

同样的逻辑适用于scaleDownGroup。当scaleUpGroup完成时(其持续时间由longest action in the group确定),我们开始scaleDownGroup,将玩家缩小到默认大小,并等待一定的时间重复整个事情。

结果如下:

Scaling Up and Down

我在触摸时启动动画(我删除了该代码),正如您所看到的,立即开始放大动画,然后在3秒后将播放器缩小到原始大小,并在4秒后完成整个动画重复(玩家再次扩大规模等)。