如何使用count-Swift SpriteKit更改运动的持续时间?

时间:2015-08-03 10:19:36

标签: ios iphone swift sprite-kit

在我的游戏中,有一个类似于向左移动的“墙”。我想根据我添加到i方法的计数touchesBegan更改速度:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent {
    count++
}

func startMoving() {

    let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 1 )

    let move = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 0.5)

    if(count <= 10)
    {
        runAction(SKAction.repeatActionForever(moveLeft))
    }
    else
    {
    runAction(SKAction.repeatActionForever(move))
    }
}

但它不起作用。你能帮忙吗?

2 个答案:

答案 0 :(得分:1)

正如我所说,有很多变化需要做:

首先让我们改变MLWall类并添加一个将在startMoving方法中使用的持续时间属性:

var duration:NSTimeInterval = 0.5

然后仍在MLWall类中更改init方法:

 init(duration: NSTimeInterval) {

        self.duration = duration

       //...
    }

并更改startMoving方法以使用此传递的参数:

func startMoving() {

        let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: self.duration)
        runAction(SKAction.repeatActionForever(moveLeft))
    }

这些是Wall类内部的变化。现在让我们在WallGenerator类中进行一些更改:

第一个WallGenerator类应该知道墙应该有多快。所以我们正在添加属性来存储该信息:

var currentDuration: NSTimeInterval = 1 // I named it duration, because SKAction takes duration as a parameter, but this actually affects on speed of a wall.

之后,必须更改的第一个方法是startGeneratingWallsEvery(second :) into startGeneratingWallsEvery(second:duration:

//duration parameter added
    func startGeneratingWallsEvery(seconds: NSTimeInterval, duration : NSTimeInterval) {

       self.currentDuration = duration

        generationTimer = NSTimer.scheduledTimerWithTimeInterval(seconds, target: self, selector: "generateWall", userInfo: nil, repeats: true)

    }

在这里,我们正在让WallGenerator了解所需的墙速度。 并且为了使用该速度而必须改变的下一个方法是:

//duration parameter added
    func generateWall() {
        //...
        //Duration parameter added

        let wall = MLWall(duration: self.currentDuration)
       //...
    }

还有一个GameScene。在那里,我添加了tapCounter属性:

let debugLabel = SKLabelNode(fontNamed: "Arial") //I've also added a debug label to track taps count visually
var tapCounter = 0

如果您想查看点击次数,可以使用以下方法初始化标签:

 //Setup debug label

        debugLabel.text = "Tap counter : \(tapCounter)"
        debugLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMaxY(frame)-50.0)
        debugLabel.fontColor = SKColor.purpleColor()
        self.addChild(debugLabel)

首先我改变了开始方法:

func start() {
       //...

        // adding duration parameter in method call
        wallGenerator.startGeneratingWallsEvery(1,duration: 1)
    }

重要的部分是:wallGenerator.startGeneratingWallsEvery(1,duration: 1)表示每秒开始生成墙,持续时间为一秒(这会影响节点的速度)。

接下来,我已将场景中的touchesBegan修改为:

if isGameOver {
            restart()
        } else if !isStarted {
            start()
        } else {



            tapCounter++
            debugLabel.text = "Tap counter : \(tapCounter)"

            if(tapCounter > 10){
                wallGenerator.stopGenerating()
                wallGenerator.startGeneratingWallsEvery(0.5, duration:0.5)
            }

            hero.flip()
        }

然后,更改了restart()方法,以便在游戏结束时重新启动计数器:

func restart() {
        tapCounter = 0
       //...
 }

这就是它。我想我没有忘记一些东西,但在我身边,它可以正常工作。另请注意,使用此GitHub project中的NSTimer并不是您想要的SpriteKit。这是因为NSTimer不尊重场景,观看或节点的暂停状态。这意味着即使你认为游戏暂停,它也会继续产卵。 SKAction将是这种情况的首选替代品。

希望这会有所帮助,如果您有其他问题,请随时提出,但我想您可以从上面的代码中了解发生了什么。基本上所做的是WallGenerator已经意识到他们的墙节点应该有多快,并且Wall节点已经意识到它应该有多快......

修改

还有另一种通过使用键运行移动动作来改变墙壁速度的方法。然后,在产生的那一刻,根据tapCounter值,您可以通过键访问移动动作,并直接更改动作的速度属性......这可能是一种较短的方式,但仍需要一些更改(通过Wall类中的duration参数和在场景中实现tapCounter)。

答案 1 :(得分:0)

尝试这样做:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent {
    count++
    startMoving()

}

func startMoving() {
    removeAllActions()
    let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: count <= 10 ? 1.0 : 0.5)
    runAction(SKAction.repeatActionForever(moveLeft))

}

<击>

当我阅读你的问题下面的评论时,你提出了一个非常不清楚的问题,但是你的代码中仍存在思想问题。

如果我理解了所有内容,您的touchesBegan方法就会在墙上实施,因此它对新生成的墙没有任何影响。您必须将该逻辑移动到场景中,然后以速度作为参数生成新墙,或者至少使count成为类var,因此每个墙都可以访问它,但您仍需要处理场景,因为现在触摸是在用户直接在墙上点击时处理的。