SpriteKit的相机抖动效果

Krz*_*ski 14 ios7 sprite-kit

有没有人知道一些开箱即用的库可能会提供相机抖动等效果SKNode

如果没有,是否有一种简单的方法来实现使用动作的相机抖动?

谢谢

Mar*_*tin 15

我找到了一种使用SKAction的优雅方法,可以让你的节点震动.例如,水平摇晃:

-(void)shake:(NSInteger)times {
    CGPoint initialPoint = self.position;
    NSInteger amplitudeX = 32;
    NSInteger amplitudeY = 2;
    NSMutableArray * randomActions = [NSMutableArray array];
    for (int i=0; i<times; i++) {
        NSInteger randX = self.position.x+arc4random() % amplitudeX - amplitudeX/2;
        NSInteger randY = self.position.y+arc4random() % amplitudeY - amplitudeY/2;
        SKAction *action = [SKAction moveTo:CGPointMake(randX, randY) duration:0.01];
        [randomActions addObject:action];
    }

    SKAction *rep = [SKAction sequence:randomActions];

    [self runAction:rep completion:^{
        self.position = initialPoint;
    }];
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*nzi 13

接受的答案中的摇动方法有一个警告 - 它只能应用于没有x,y坐标被其他正在运行的SKAction修改的节点.这是因为我们在摇动完成后将节点的位置重置为其初始位置.

如果你想要一个同样适用于其他SKAction的摇动动作,它可以按顺序/并行方式修改摇动节点的位置(x或y坐标),你需要添加你正在应用的随机摇动的反向动作.

Swift扩展名供参考:

extension SKAction {
class func shake(duration:CGFloat, amplitudeX:Int = 3, amplitudeY:Int = 3) -> SKAction {
    let numberOfShakes = duration / 0.015 / 2.0
    var actionsArray:[SKAction] = []
    for index in 1...Int(numberOfShakes) {
        let dx = CGFloat(arc4random_uniform(UInt32(amplitudeX))) - CGFloat(amplitudeX / 2)
        let dy = CGFloat(arc4random_uniform(UInt32(amplitudeY))) - CGFloat(amplitudeY / 2)
        let forward = SKAction.moveByX(dx, y:dy, duration: 0.015)
        let reverse = forward.reversedAction()
        actionsArray.append(forward)
        actionsArray.append(reverse)
    }
    return SKAction.sequence(actionsArray)
}
}
Run Code Online (Sandbox Code Playgroud)

请注意,此修改不要求将节点作为参数传入


Haz*_*azA 5

如果您已经使用Swift,可以使用以下代码...

let shake = SKAction.shake(node.position, duration: 0.3)
node.runAction(shake)
Run Code Online (Sandbox Code Playgroud)

或者对于更强烈的震动,您也可以配置振幅

let shake = SKAction.shake(node.position, duration: 0.3, amplitudeX: 12, amplitudeY: 3)
node.runAction(shake)
Run Code Online (Sandbox Code Playgroud)

这是扩展....

extension SKAction {
    class func shake(initialPosition:CGPoint, duration:Float, amplitudeX:Int = 12, amplitudeY:Int = 3) -> SKAction {
        let startingX = initialPosition.x
        let startingY = initialPosition.y
        let numberOfShakes = duration / 0.015
        var actionsArray:[SKAction] = []
        for index in 1...Int(numberOfShakes) {
            let newXPos = startingX + CGFloat(arc4random_uniform(UInt32(amplitudeX))) - CGFloat(amplitudeX / 2)
            let newYPos = startingY + CGFloat(arc4random_uniform(UInt32(amplitudeY))) - CGFloat(amplitudeY / 2)
            actionsArray.append(SKAction.moveTo(CGPointMake(newXPos, newYPos), duration: 0.015))
        }
        actionsArray.append(SKAction.moveTo(initialPosition, duration: 0.015))
        return SKAction.sequence(actionsArray)
    }
}
Run Code Online (Sandbox Code Playgroud)

积分转到Stephen Haney实施我刚刚将其转移到扩展中


caf*_*eyd 5

如果你想动摇整个场景,这里是 Rob 用 Swift 写的答案的一个版本:

    func sceneShake(shakeCount: Int, intensity: CGVector, shakeDuration: Double) {
        let sceneView = self.scene!.view! as UIView
        let shakeAnimation = CABasicAnimation(keyPath: "position")

        shakeAnimation.duration = shakeDuration / Double(shakeCount)
        shakeAnimation.repeatCount = Float(shakeCount)
        shakeAnimation.autoreverses = true
        shakeAnimation.fromValue = NSValue(cgPoint: CGPoint(x: sceneView.center.x - intensity.dx, y: sceneView.center.y - intensity.dy))
        shakeAnimation.toValue = NSValue(cgPoint: CGPoint(x: sceneView.center.x + intensity.dx, y: sceneView.center.y + intensity.dy))

        sceneView.layer.add(shakeAnimation, forKey: "position")
      }
Run Code Online (Sandbox Code Playgroud)

我将此函数包含在 SKScene 子类中。这是一个示例调用:

    sceneShake(shakeCount: 3, intensity: CGVector(dx: shakeIntensity, dy: shakeIntensity), shakeDuration: shakeDuration)
Run Code Online (Sandbox Code Playgroud)