iOS7 SpriteKit 如何对两个或多个精灵节点子节点的动画进行分组?
Posted
技术标签:
【中文标题】iOS7 SpriteKit 如何对两个或多个精灵节点子节点的动画进行分组?【英文标题】:iOS7 SpriteKit how to group animations of two or more sprite node children? 【发布时间】:2014-05-20 01:12:35 【问题描述】:如何为具有多个子节点的节点创建 SpriteKit 动画,并将节点的多个部分作为一个组制作动画?
我有以下节点结构:
Bird 有身体、尾巴、头部等的子节点 头部有上喙、下喙等子节点在下面的示例中,我想为整个小鸟制作动画,所有孩子都弯腰捡起一颗种子。在弯腰时,鸟张开嘴吃种子。请注意,喙不是鸟的孩子,而是头节点的孩子。
//body does this action
SKAction* bendDown = [SKAction rotateToAngle:M_PI*0.3 duration:lookUpTiming];
//beak does this action
SKAction* openBeak = [SKAction rotateToAngle:-M_PI*0.175 duration:beakDuration + arc4random()%20/100.0];
//I need both actions to be played together as a group:
SKAction* bendAndOpenBeak = [SKAction group:@[bendDown, openBeak]];
//if I call this, the body will perform both actions.
[self runAction:bendAndOpenBeak completion:^
];
这是我可以在头节点上运行的代码,以使其子节点使用 runAction:onChildWithName:
执行操作但是,我需要将其作为一个组与主体(父节点的父节点)节点一起运行
-(SKAction*)openBeak
float angleUp = -M_PI*0.175;
float duration = beakDuration + arc4random()%20/100.0;
SKAction* rotateUp = [SKAction rotateToAngle:angleUp duration:duration];
rotateUp.timingMode = SKActionTimingEaseOut;
SKAction* rotateDown = [SKAction rotateToAngle:-angleUp duration: duration];
rotateUp.timingMode = SKActionTimingEaseOut;
return [SKAction group:@[[SKAction runAction:rotateUp onChildWithName:@"beakUpper"],
[SKAction runAction:rotateDown onChildWithName:@"beakLower"] ]];
【问题讨论】:
你需要展示更多才能得到真正的答案 自己是鸟的身体 这个问题你解决了吗? @rptwsthi 我刚刚发布了一个完整的答案。 【参考方案1】:[SKAction runAction:onChildWithName:]
具有瞬时持续时间,因此您的组操作不会等待其完成。
让组等待所有动作完成的简单方法是在组中添加一个[SKAction waitForDuration:]
,并使用传递给[SKAction runAction:onChildWithName:]
的动作的持续时间属性
所以在您的示例中,所需的代码如下所示
-(SKAction*)openBeak
float angleUp = -M_PI*0.175;
float duration = beakDuration + arc4random()%20/100.0;
SKAction* rotateUp = [SKAction rotateToAngle:angleUp duration:duration];
rotateUp.timingMode = SKActionTimingEaseOut;
SKAction* waitForRotateUp = [SKAction waitForDuration:rotateUp.duration];
SKAction* rotateDown = [SKAction rotateToAngle:-angleUp duration: duration];
rotateUp.timingMode = SKActionTimingEaseOut;
SKAction* waitForRotateDown = [SKAction waitForDuration:rotateDown.duration];
return [SKAction group:@[[SKAction runAction:rotateUp onChildWithName:@"beakUpper"],
[SKAction runAction:rotateDown onChildWithName:@"beakLower"],
waitForRotateDown, waitForRotateUp]];
我在上面的示例中使用了 SKActions 持续时间属性,即使您明确设置持续时间值,因为这种方法可用于诸如精灵动画之类的动作,其中持续时间没有明确设置。
【讨论】:
【参考方案2】:您不需要使用group
,只需在每个节点上分别运行它们,一个一个:
//body does this action
SKAction* bendDown = [SKAction rotateToAngle:M_PI*0.3 duration:lookUpTiming];
//beak does this action
SKAction* openBeak = [SKAction rotateToAngle:-M_PI*0.175 duration:beakDuration + arc4random()%20/100.0];
[bodyNode runAction:bendDown];
[beakNode runAction:openBeak];
【讨论】:
我需要重复序列 3 次,所以如果我并行运行动作,我需要进行各种计算以确保它们的时间同步。【参考方案3】:这正是您所要求的解决方案。此答案使用 Swift 3。
import SpriteKit
class Scene: SKScene
// 1
let lookUpTiming = 0.2
let beakDuration = 0.2
// 2
let body = SKNode()
let beak = SKNode()
override func sceneDidLoad()
// 3
let bendDown = SKAction.run
let action = SKAction.rotate(toAngle: .pi * 0.3, duration: self.lookUpTiming)
self.body.run(action)
// 4
let openBeak = SKAction.run
let duration = self.beakDuration + Double(arc4random_uniform(20)) / 100
let action = SKAction.rotate(toAngle: -.pi * 0.175, duration: duration)
self.beak.run(action)
// 5
let group = SKAction.group([bendDown, openBeak])
// 6
run(group)
以下是这段代码中发生的事情:
-
初始化设置
初始化节点
为第一个动画创建一个 SKAction
为第二个动画创建一个 SKAction
创建一组这两个动作
从现场运行小组。即使它们在不同的节点上,两个动画也会同时触发! ?
【讨论】:
以上是关于iOS7 SpriteKit 如何对两个或多个精灵节点子节点的动画进行分组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS7 SpriteKit 中为不同大小的图像设置动画?
多个 SKSpriteNode 的 SpriteKit 多个 SKActions - 等待全部完成