SpriteKit中的正弦波运动

时间:2014-02-21 16:58:43

标签: ios sprite-kit

我想从屏幕的第一个点到屏幕的最后一个点进行正弦波运动,与屏幕的大小无关。

这是我的代码,但它无法正常工作:

 SKSpriteNode* RedBird = (SKSpriteNode*)[self childNodeWithName:@"RedBird"];
CGPoint currentPoint=CGPointMake(-60,0);
double width=self.frame.size.width/4;
CGPoint cp1=CGPointMake(width, self.frame.size.height/2);
CGPoint cp2=CGPointMake((width*3), 0);
CGPoint e=CGPointMake(self.frame.size.width+200, 0);


CGMutablePathRef cgpath = CGPathCreateMutable();


CGPathMoveToPoint(cgpath,NULL, currentPoint.x, currentPoint.y);
CGPathAddCurveToPoint(cgpath, NULL, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);



[RedBird runAction:[SKAction group:@[[SKAction repeatActionForever:RedBirdAnimation],[SKAction followPath:cgpath asOffset:YES orientToPath:NO duration:12.0]]]];


CGPathRelease(cgpath);

3 个答案:

答案 0 :(得分:13)

我同意@Gord,因为我觉得SKAction是最好的方式。但是,当您可以使用sin函数时,无需近似正弦曲线。

首先,你需要π,因为它对计算有用:

// Defined at global scope.
let π = CGFloat(M_PI)

其次,扩展SKAction(在Objective-C中这将通过类别完成)以轻松创建一个振荡相关节点的SKAction

extension SKAction {
    static func oscillation(amplitude a: CGFloat, timePeriod t: CGFloat, midPoint: CGPoint) -> SKAction {
        let action = SKAction.customActionWithDuration(Double(t)) { node, currentTime in
            let displacement = a * sin(2 * π * currentTime / t)
            node.position.y = midPoint.y + displacement
        }

        return action
    }
}

在上面的代码中:amplitude是振荡的高度; timePeriod是一个完整周期的时间,midPoint是振荡发生的点。 displacement的公式来自Simple Harmonic Motion的公式。

第三,将所有这些放在一起。您可以将SKAction.oscillation操作与SKAction.moveByX结合使用,以使精灵沿曲线的路径移动。

class GameScene: SKScene {
    override func didMoveToView(view: SKView) {
        let node = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: 50, height: 50))
        node.position = CGPoint(x: 25, y: size.height / 2)
        self.addChild(node)

        let oscillate = SKAction.oscillation(amplitude: 200, timePeriod: 1, midPoint: node.position)
        node.runAction(SKAction.repeatActionForever(oscillate))
        node.runAction(SKAction.moveByX(size.width, y: 0, duration: 5))
    }
}

答案 1 :(得分:1)

这是一篇很老的帖子,但我想发布一个答案,让它具有google功能。 我在SKSpriteNode的子类中创建了这个函数,使sprite从一侧到另一侧的近似正弦波。

它很快,但可以很容易地在客观C中完成。 此外,你想要更聪明,并将路径构建在一个循环中,但我只是让它不受限制,以使数学易于理解。

(我不同意游戏循环的答案,但它违背了Sprite Kit的理念)

.image {
  background: url(http://nintendo-online.de/img/bg-game-header-cover.png) repeat, url(http://media2.giga.de/2013/06/osx_hero_2x.jpg) no-repeat;
}

答案 2 :(得分:0)

我会创建一个基于游戏循环来更新所有游戏元素而不是依赖SKActions。 SKActions通常是一种执行动画的方式,因为游戏元素的连续移动可以创建一个简单的引擎并让它更新红鸟的位置。