SpriteKit:淡出SKNode - 孩子们闪耀着光芒

时间:2015-04-10 23:32:37

标签: swift sprite-kit fadeout skaction

我有一个SKSpriteNode,我用baseNode.runAction(SKAction.fadeOutWithDuration(0.5))

淡出

精灵有一个孩子。也是一个SKSpriteNode。 (图像中的红色块)

baseNode 淡出时,会有子节点的轮廓。

避免这种情况的最佳方法是什么,并且让孩子同时淡出整个节点?我想在子节点中播放纹理动画。如此扁平化是没有解决方案的。

enter image description here

5 个答案:

答案 0 :(得分:6)

这个问题引起了我的好奇心。我有一个解决方案,但是,由于缺乏我对Swift的了解,我已经用Objective-C编写了它。但是,它非常简单,移植对您来说应该没问题。

诀窍是将整个节点压扁成一个纹理,然后淡化它。

我使用类别实现了这一点。下面的代码用平铺纹理替换SKSpriteNode的texture属性。关键方法是SKView类中的-textureFromNode:

@interface SKSpriteNode (Fading)

- (void)flattenForFading;

@end

...

#import "SKSpriteNode+Fading.h"

@implementation SKSpriteNode (Fading)

- (void)flattenForFading {
  SKTexture *flattenedContents = [self.scene.view textureFromNode:self];

  /// Copy the children array, so when we are iterating the removing doesn't cause any problems
  NSArray *children = [self.children copy];

  for (SKNode *child in children) {
    [child removeFromParent];
  }

  self.texture = flattenedContents;
  self.size = self.texture.size;
}

@end

对于非SKSpriteNode情况,您只需添加一个新的SKSpriteNode作为被展平的节点的子节点。由于您正在烘焙单个纹理,因此不支持节点内的动画。当然,你也可以隐藏,而不是删除所有孩子。如果要为删除的纹理添加额外属性,您甚至可以保存内部状态并使用-unflatten方法恢复此方法的效果。但这超出了你的问题的范围。

我在模拟器中截取了这个截图。请注意,节点计数器对应3个褪色SKSpriteNodes,1个SKLabelNode和1个扁平精灵(SKSpriteNode)。

Non-flattened vs. flattened SKSpriteNode

答案 1 :(得分:1)

您还必须在节点的子节点上调用相同的操作。

baseNode.runAction(SKAction.fadeOutWithDuration(0.5))

for node in baseNode.children as! [SKSpriteNode]
{
    node.runAction(SKAction.fadeOutWithDuration(0.5))
}

答案 2 :(得分:1)

对于屏幕之间的转换,一个很酷的效果是让黑色节点覆盖整个屏幕,然后将其淡出。我想出了以下内容: Swift 3

import SpriteKit

override func didEnter(from previousState: GKState?) {

let blackNode = SKSpriteNode(color: SKColor.black, size: scene.size)
blackNode.position = CGPoint(x: scene.size.width / 2, y: scene.size.height / 2)
blackNode.zPosition = Layer.top.rawValue
scene.worldNode.addChild(blackNode)
blackNode.alpha = 1.0
blackNode.run(SKAction.fadeOut(withDuration: 0.5)) }

我很难找到解决方案,所以我希望这可以帮助那里的人。 干杯

答案 3 :(得分:0)

代替子节点上的fadeOutWIthDuration(),为什么不使用colorizeWithColor(_:colorBlendFactor:duration:)。

https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKAction_Ref/index.html#//apple_ref/occ/clm/SKAction/colorizeWithColor:colorBlendFactor:duration

  

colorizeWithColor(_:colorBlendFactor:duration :)

     

创建动画   它会激活精灵的颜色和混合因子。

     

宣言

     

SWIFT

     

class func colorizeWithColor(_ color:UIColor,               colorBlendFactor colorBlendFactor:CGFloat,                       持续时间秒:NSTimeInterval) - > SKAction

     

参数

     

color精灵的新颜色。

     

colorBlendFactor精灵的新混合因子。

     

秒动画的持续时间。

     

返回值一个新的操作对象。

     

讨论   此操作只能由SKSpriteNode对象执行。   当动作执行时,精灵的颜色和colorBlendFactor   属性动画为新值。

     

这个动作不可逆转;这个动作的反面呢   什么都没有。

     

导入声明

     

SWIFT

     

导入SpriteKit

     

iOS中可用的可用性

     

7.0及更高版本。

答案 4 :(得分:0)

您可以使用包装基本节点和子节点的父SKEffectNode,并在效果节点本身上执行淡入淡出。

即使您没有使用SKEffectNode的过滤器或其他功能,它也会将其子项呈现在私有帧缓冲区中,因此最终会执行扁平化建议尝试执行的操作,但它会为您完成所有操作,即使孩子们在每一帧都有动画,就像你在你的榜样中所做的一样。

为了提高性能,您还可以通过设置shouldEnableEffects = false来禁用使用父SKEffectNode的额外费用,并且只在需要执行淡入淡出时打开/关闭此功能。