【问题标题】:Sine Wave Motion In SpriteKitSpriteKit 中的正弦波运动
【发布时间】:2014-02-21 16:58:42
【问题描述】:

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

这是我的代码,但它不能正常工作:

 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);

【问题讨论】:

标签: ios sprite-kit


【解决方案1】:

我同意@Gord,因为我认为SKActions 是最好的选择。但是,当您可以使用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))
    }
}

【讨论】:

【解决方案2】:

这是一篇旧帖子,但我想发布一个答案以使其可在 Google 上搜索。 我在 SKSpriteNode 的一个子类中创建了这个函数,它使精灵从一侧到另一侧以近似正弦波的形式移动。

它很快,但可以在目标 C 中轻松完成。 此外,您可能希望更智能并将路径构建置于循环中,但我只是将其保持为非循环以使数学易于理解。

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

func setSineAction()
{
    let scene = self.parent as! SKScene

    let y42 = scene.size.height/2
    let x1 = scene.size.width
    let x2 = scene.size.width * 0.875
    let x3 = scene.size.width * 0.750
    let x4 = scene.size.width * 0.625
    let x5 = scene.size.width * 0.500
    let x6 = scene.size.width * 0.375
    let x7 = scene.size.width * 0.250
    let x8 = scene.size.width * 0.125
    let x9 = 0.0 as CGFloat

    let path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, x1, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x1/2)+(x2/2), scene.size.height*0.7, x2, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x2/2)+(x3/2), scene.size.height*0.3, x3, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x3/2)+(x4/2), scene.size.height*0.7, x4, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x4/2)+(x5/2), scene.size.height*0.3, x5, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x5/2)+(x6/2), scene.size.height*0.7, x6, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x6/2)+(x7/2), scene.size.height*0.3, x7, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x7/2)+(x8/2), scene.size.height*0.7, x8, y42)
    CGPathAddQuadCurveToPoint(path, nil, (x8/2)+(x9/2), scene.size.height*0.3, x9, y42)

    self.runAction(SKAction.followPath(path, asOffset: false, orientToPath: false, duration: 10))

}

【讨论】:

  • ABakerSmith 的回答很好。我对 iOS 编程还很陌生,我不会想到扩展 SKAction。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    相关资源
    最近更新 更多