2014-02-21 40 views
9

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

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

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

,做这种事情在spritekit着色器有用链接:http://www.ymc.ch/en/making-a-pixel-shader-for-ios8-with-sprite-kit – MoDJ

回答

0

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

1

这是一个旧的帖子,但我想发布一个答案,使其谷歌能。 我在SKSpriteNode的一个子类中做了这个函数,它使精灵从一边到另一边以近似的正弦波进入。

它很快速,但可以很容易地在目标C中完成。另外,您希望更加智能化,并将路径构建放入循环中,但为了使数学易于理解,我只是保持不变。

(我不与游戏循环答案不同意,但它那种违背雪碧套件的哲学)

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

} 
+0

ABakerSmith的答案很好。 我对iOS编程还是新的,我不会想到扩展SKAction。 – Gord

10

我@Gord同意,因为我觉得SKAction s为的最佳方式去。但是,当您可以使用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)) 
    } 
} 
+0

非常好的答案,拯救我的一天,谢谢 –