2014-02-21 82 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

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