38

我需要在我的应用程序中添加雨粒子效果,我一直很难找到实际执行这个想法的方法。

我尝试遵循这个 CALayer 方法教程:链接 ,但考虑到 Xcode 5 中可用的新 iOS 7 SpriteKit 粒子发射器,我不太确定这是否是最佳方法。

我已经创建了.sks文件并且它在我的层次结构中,但我仍然无法将它添加到我的故事板/项目中。

话虽如此,我究竟如何将 SpriteKit 粒子(sks)添加到我的视图中?由于我不是游戏开发人员,所以我对 SpriteKit 框架中的场景、分层等完全不熟悉。我需要尽可能多的详细信息和示例代码,以便我可以解决这个问题

更新:我已按照 SO 成员的回答中提供的方向进行操作:AyatollahAndy,请在下面查看他的回答。尽管我能够在收到任何触摸事件时SKScene在我的应用程序崩溃中显示。view我得到以下信息:在此处输入图像描述

谢谢

4

7 回答 7

50

SKScene在你的创建一个UIView添加SKEmitterNode粒子效果。

这样做的一种方法:

1.在情节提要中(或以编程方式,如果您愿意)在现有视图之上添加一个视图对象,并根据您的需要调整它的大小。
2.将新视图的类更改为SKView
3.在您的视图控制器.h 文件中为SKView

@property IBOutlet SKView *skView;

4.将SKView情节提要上的链接到 skView 属性。
5.创建一个新类,子类化SKScene。MyScene.h 看起来像:

#import <SpriteKit/SpriteKit.h>
@interface MyScene : SKScene
@end

下面的 MyScene.m 包含在任何时间和任何地方触摸 SKView 时创建粒子效果的代码。

#import "MyScene.h"

@implementation MyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
        SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
        myLabel.text = @"Hello, World!";
        myLabel.fontSize = 30;
        myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
                                   CGRectGetMidY(self.frame));

        [self addChild:myLabel];
    }
    return self;
}

//particle explosion - uses MyParticle.sks
- (SKEmitterNode *) newExplosion: (float)posX : (float) posy
{
    SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"MyParticle" ofType:@"sks"]];
    emitter.position = CGPointMake(posX,posy);
    emitter.name = @"explosion";
    emitter.targetNode = self.scene;
    emitter.numParticlesToEmit = 1000;
    emitter.zPosition=2.0;
    return emitter;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];
        //add effect at touch location
        [self addChild:[self newExplosion:location.x : location.y]];
    }
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end

6.在您的主视图控制器中,包括您的场景类:

#import "MyScene.h"

并将代码添加到 viewDidLoad 以初始化 SKView:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the SKView
    SKView * skView = _skView;
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;

    // Create and configure the scene.
    SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [skView presentScene:scene];
}

然后你应该SKScene在你的 main中有一个工作UIView

于 2013-11-04T15:47:02.660 回答
43

在现代 Xcode 中:

现在这很容易。

1.在Xcode中,点击新建

“SpriteKit 粒子文件”

这将是一个.sks文件。

注意:不要选择“ SceneKit粒子系统文件”。选择“SpriteKit 粒子文件”。)

单击.sks文件一次。注意右边的许多控件。

在此处输入图像描述

粒子实际上会移动,这是一个活生生的预览。任何可以用粒子完成的事情,你都可以做到。这就像在游戏引擎中使用粒子,只是性能要好 180 亿倍。

2.拥有任何普通的UIView,随心所欲:

@IBOutlet weak var teste: UIView! // totally ordinary UIView

3.只需使用以下代码链接:

下面的代码将把你的新粒子系统放在里面,普通的 UIView “teste”:

import SpriteKit ...


let sk: SKView = SKView()
sk.frame = teste.bounds
sk.backgroundColor = .clear
teste.addSubview(sk)

let scene: SKScene = SKScene(size: teste.bounds.size)
scene.scaleMode = .aspectFit
scene.backgroundColor = .clear

let en = SKEmitterNode(fileNamed: "SimpleSpark.sks")
en?.position = sk.center

scene.addChild(en!)
sk.presentScene(scene)

将此添加到您想要的任何内容中。

如果您想要一个闪闪发光的按钮,请将其添加到按钮中。

如果您希望整个屏幕呈现彩虹,请将其添加到全屏视图。

就这么容易。


如何使用 SpriteKit 粒子文件控件的示例:

假设你想要一阵火花,然后就结束了。

将最大值设置为 50...

在此处输入图像描述

提示 - 如果您的效果“完成”(即,它不是循环),似乎您可以简单地摆脱SKScenewhen finished。像这样:

    ...
    scene.addChild(en!)
    sk.presentScene(scene)
    
    delay(1.5) { sk.removeFromSuperview() }

最后的那一行代码似乎清理了一切。


顺便说一句,如果您想要粒子系统的奇妙想法,一个好主意是单击 Unity“资产商店”,各种粒子艺术家在这里买卖粒子系统。他们的工作会给你很棒的想法。

在此处输入图像描述

只需点击右侧列表中的“粒子”;观看视频。(创新的例子。)


笔记!Apple 将这样做,以便您可以非常简单地在情节提要中制作 SKView,然后选择.sks场景。然而 ..

在此处输入图像描述

......它还没有工作!截至这篇文章的最后一次编辑(2020 年),它仍然被破坏。所以你需要上面的代码片段。

于 2017-03-28T17:10:45.490 回答
7

您可以将 SKView 添加为 UIKit 层次结构中的子视图。像下面这样的函数可以工作,允许你创建一个 UIImageView 效果作为子视图,然后你可以将它添加到你的主视图中。一定要链接到 SpriteKit。

UIImageView *NewEffectUIImageViewWithFrame(CGRect frame)
{
    UIImageView *tempView = [[UIImageView alloc] initWithFrame:frame];

    SKView *skView = [[SKView alloc] initWithFrame:CGRectMake(0.0, 0.0, frame.size.width, frame.size.height)];
    [tempView addSubview:skView];

    SKScene *skScene = [SKScene sceneWithSize:skView.frame.size];
    skScene.scaleMode = SKSceneScaleModeAspectFill;
    skScene.backgroundColor = [UIColor clearColor];

    SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"SparkParticle" ofType:@"sks"]];
    emitter.position = CGPointMake(frame.size.width*0.5,0.0);

    [skScene addChild:emitter];
    [skView presentScene:skScene];

    return tempView;
}

最后,如果您只需要一个发射器,那么创建一个CAEmitterLayer并将其作为子层添加到您的 UIView 可能会更容易。当然,这意味着您必须以编程方式创建CAEmitterLayer并且不能使用酷炫的 Xcode 粒子编辑器...

于 2014-02-10T01:53:45.530 回答
3

实际上有一种方法可以在没有 SpriteKit 的情况下添加粒子 - CoreAnimation 的 CAEmitterCells。

这样您就可以轻松地在 UIView 中添加粒子。如果您想玩转参数并轻松获取代码,请获取此应用程序 ( Particle X )。

它还支持 SpriteKit,所以如果你想在旅途中玩耍或设计粒子并立即获取代码,这个应用程序就是解决方案。

PS。如果您没有注意到,我是该应用程序的开发人员 - 在设计应用程序和游戏时自己使用它。:)

于 2015-08-18T08:04:18.160 回答
3

这是尝试完全不同的方法。我的朋友给了我这个很酷的方法。使用CAEmitterCell. 全部在代码中!看起来你需要一个 spark.png 图像。

extension UIView {
    final public func ignite() {
        let emitter = CAEmitterLayer()
        emitter.frame = self.bounds
        emitter.renderMode = kCAEmitterLayerAdditive
        emitter.emitterPosition = self.center
        self.layer.addSublayer(emitter)

        let cell = CAEmitterCell()
        let bundle = Bundle.init(for: UIColor.self)
        let image = UIImage(named: "spark", in: bundle, compatibleWith: traitCollection)

        cell.contents = image?.cgImage
        cell.birthRate = 1500
        cell.lifetime = 5.0
        cell.color = UIColor(red: 1.0, green: 0.5, blue: 0.1, alpha: 1).cgColor
        cell.alphaSpeed = -0.4
        cell.velocity = 50
        cell.velocityRange = 250
        cell.emissionRange = CGFloat.pi * 2.0

        emitter.emitterCells = [cell]
    }
}

享受。

于 2017-04-03T02:05:47.113 回答
1

出于可见性原因将其放在这里。

关于 a 的用户的答案.clear backgroundColor是正确的,除了您还必须将allowsTransparency属性设置SKView为“真”。

skView.allowsTransparency = true
skView.backgroundColor = .clear  // (not nil)
scene.backgroundColor = .clear

如果您没有设置allowsTransparency为 true,并且您SKView在 a 上进行布局UIImageView,则合成引擎将很合适,并且即使只绘制了一个粒子,也会向您的 GPU 发送红线。(在模拟器中,CPU 会出现峰值。)

于 2020-07-05T07:12:32.047 回答
-1

您不能UIView直接在其中使用粒子效果。

SKEmitterNode必须位于使用节点场景 ( SKScene) 定义的节点树中。场景节点运行一个动画循环,渲染节点树的内容以供显示。UIView是静态的,不会为它工作。

但是,您可能能够在您的内部创建一个场景UIView,但我从未尝试过这样做。

于 2013-11-01T11:17:51.190 回答