Ios 如何通过SKEffectNode在精灵周围创建光晕
我有一个Ios 如何通过SKEffectNode在精灵周围创建光晕,ios,iphone,sprite-kit,skeffectnode,Ios,Iphone,Sprite Kit,Skeffectnode,我有一个SKSpriteNode,我希望在它的边缘周围有一个蓝色的光晕,以便高亮显示。我猜我需要将我的精灵设置为SKEffectNode的子元素,然后创建/应用某种过滤器 更新:我用所选答案的方法对此进行了大量调查,发现SKEffectNode对性能有很大影响,即使您将其设置为shouldRasterize并定义了“无过滤器”。我的结论是,如果游戏一次需要10个以上的移动对象,即使光栅化,它们也不能包含SKEffectNode 我的解决方案可能涉及预渲染的辉光图像/动画,因为SKEffectNo
SKSpriteNode
,我希望在它的边缘周围有一个蓝色的光晕,以便高亮显示。我猜我需要将我的精灵设置为SKEffectNode
的子元素,然后创建/应用某种过滤器
更新:我用所选答案的方法对此进行了大量调查,发现SKEffectNode
对性能有很大影响,即使您将其设置为shouldRasterize
并定义了“无过滤器”。我的结论是,如果游戏一次需要10个以上的移动对象,即使光栅化,它们也不能包含SKEffectNode
我的解决方案可能涉及预渲染的辉光图像/动画,因为SKEffectNode不会根据我的要求对其进行剪切
如果有人能洞察到我所遗漏的任何东西,我会很高兴听到你所知道的一切
我之所以接受答案,是因为它确实达到了我的要求,但我想向任何希望走这条路线的人添加这些注释,因此,您可以了解使用
SKEffectNode
的一些问题。您可以在精灵后面使用SKShapeNode
,并使用其glowWidth
和strokeColor
属性定义辉光。如果您的大小和位置正确,这将给您一个辉光的外观。这并没有为您提供许多定制选项,但我认为这比使用带有SKEffectNode
的CIFilter
要容易得多,这可能是您在这方面的另一个逻辑选项。您可以通过创建一个组成多个内置过滤器的CIFilter
子类,在核心图像中创建辉光效果。此类过滤器将包括以下步骤:
CIColorMatrix
创建输入图像的单色版本CiAffinetTransform
+CIGaussianBlur
)CISourceOverCompositing
)CIFilter
子类来完成这一切,你就可以将它与SKEffectNode
一起使用,在效果节点的子节点周围实时发光。在这里,它运行在iPad 4上的“精灵工具包游戏”Xcode模板中:
通过抄袭WWDC 2013场景工具包演示中用于类似效果的自定义过滤器类,我在几分钟内就实现了这一点——从位于的WWDC示例代码包中获取它,然后查找ASCGlowFilter
类。(如果您想在iOS上使用该代码,您需要将NSAffineTransform
部分改为使用cAffinetransform
。我还将centerX
和centerY
属性替换为inputCenter
类型的CIVector
参数,以便Sprite工具包可以自动将效果集中在精灵。)
我说的是“实时”发光吗?是的!这是“真正消耗CPU时间”的缩写。请注意,在屏幕截图中,即使只有一艘宇宙飞船,它也不再固定在每秒60帧的速度上——并且在iOS模拟器上使用OpenGL ES renderer软件,它以幻灯片的速度运行。如果你在Mac上,你可能有多余的硅。。。但如果你想在游戏中做到这一点,请记住以下几点:
- 可能有一些方法可以提高过滤器本身的性能。使用不同的CI过滤器,您可能会看到一些改进(核心图像中有几个模糊过滤器,其中一些肯定比高斯更快)。还请注意,模糊效果往往是碎片着色器绑定的,因此图像越小,光晕半径越小越好 <> LI>如果你想在场景中有多个发光,考虑把所有发光的精灵都放在同一个效果节点上,让它们都变成一个图像,然后应用一次过滤器。
- 如果要发光的精灵变化不大(例如,如果我们的宇宙飞船没有旋转),则在“效果”节点上设置
应该光栅化
为
是
。(实际上,在这种情况下,通过旋转效果节点而不是其中的精灵,您可能会得到一些改进。)
- 你真的需要实时发光吗?与游戏中的许多漂亮的图形效果一样,如果你伪造它,你会获得更好的性能。在您喜爱的图形编辑器中制作一个模糊、蓝色的宇宙飞船,并将其作为另一个精灵放置在场景中
- @rickster的答案很好。由于我的代表性很低,我显然不允许将此代码添加到他的评论中。我希望这不会违反礼仪规则。我不想以任何方式利用他的代表
下面是他在回答中描述的代码:
标题:
// ENHGlowFilter.h
#import <CoreImage/CoreImage.h>
@interface ENHGlowFilter : CIFilter
@property (strong, nonatomic) UIColor *glowColor;
@property (strong, nonatomic) CIImage *inputImage;
@property (strong, nonatomic) NSNumber *inputRadius;
@property (strong, nonatomic) CIVector *inputCenter;
@end
//Based on ASCGLowFilter from Apple
使用中:
@implementation ENHMyScene //SKScene subclass
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
[self setAnchorPoint:(CGPoint){0.5, 0.5}];
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
SKEffectNode *effectNode = [[SKEffectNode alloc] init];
ENHGlowFilter *glowFilter = [[ENHGlowFilter alloc] init];
[glowFilter setGlowColor:[[UIColor redColor] colorWithAlphaComponent:0.5]];
[effectNode setShouldRasterize:YES];
[effectNode setFilter:glowFilter];
[self addChild:effectNode];
_effectNode = effectNode;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.position = location;
[self.effectNode addChild:sprite];
}
}
我尝试了一些方法,但还没有找到解决方案-无法使EffectNode“笔划”图像。如何使用SKShapeNode获得效果?你的意思是创建一个与SKspriteNode轮廓相匹配的形状,然后使其发光并将其置于SKspriteNode后面?精灵不是正方形的,有没有办法创建一个与精灵匹配的形状模型?物理引擎能为collison做到这一点吗?正如rickster提到的,这基本上是伪造的,但在这个过程中节省了大量的性能。您将创建精灵的路径,并在
SKShapeNode
中的精灵后面使用。我会用一个固定的关节或类似的东西连接它,然后关闭它的物理功能,让它基本上跟随精灵-让精灵处理物理/碰撞。我想问的是,是否有一种方法可以创建一个SKSpriteNode的SKShapeNode路径。最好有一种方法来创建一个遵循SKSpriteNode轮廓的SKShapeNode路径。不,没有自动的方法。有一些外部工具可以渲染到
@implementation ENHMyScene //SKScene subclass
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
[self setAnchorPoint:(CGPoint){0.5, 0.5}];
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
SKEffectNode *effectNode = [[SKEffectNode alloc] init];
ENHGlowFilter *glowFilter = [[ENHGlowFilter alloc] init];
[glowFilter setGlowColor:[[UIColor redColor] colorWithAlphaComponent:0.5]];
[effectNode setShouldRasterize:YES];
[effectNode setFilter:glowFilter];
[self addChild:effectNode];
_effectNode = effectNode;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.position = location;
[self.effectNode addChild:sprite];
}
}