如何向使用 iOS 7 SpriteKit 粒子的非游戏的 iOS 应用程序添加粒子效果?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19620866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:37:09  来源:igfitidea点击:

How to add particle effects to an iOS App that is not a game using iOS 7 SpriteKit Particle?

iosobjective-cuiviewsprite-kitskemitternode

提问by vzm

I need to add a rain particle effect to my app, I have been having a tough time finding ways to actually execute this idea.

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

I tried following this CALayer approach tutorial : Linkbut I am not quite sure if this is the best approach, considering the new iOS 7 SpriteKit Particle Emitter available in Xcode 5.

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

I have already created the .sksfile and it's in my Hierarchy, but I am still unable to add it to my storyboard / project.

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

With that being said, How exactly do I add a SpriteKit Particle (sks) to my view? I am not at all familiar with scenes, layering , etc in the SpriteKit framework as I am not a game developer. I need the most details and sample code possible so that I can figure this out please

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

UPDATE: I have followed the direction provided in an answer by fellow SO member: AyatollahAndy, please see his answer below. Although I was able to display the SKScenein my viewthe app crashes when any touch event is received. I get the following: enter image description here

更新:我已按照 SO 成员 AyatollahAndy 的回答中提供的指示进行操作,请参阅下面的回答。虽然我能够SKScene在我view的应用程序中显示当收到任何触摸事件时崩溃。我得到以下信息:在此处输入图片说明

Thanks

谢谢

回答by AndyOS

Create a SKScenein your UIViewto add a SKEmitterNodeparticle effect.

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

One way of doing this:

这样做的一种方法:

1.In storyboard (or programatically if you prefer) add a View object on top of the existing View and resize it to your needs.
2.Change the class of the new view to SKView
3.In your view controller .h file create a property for the SKView:

1.在故事板中(或以编程方式,如果您愿意)在现有视图之上添加一个视图对象并根据您的需要调整其大小。
2.将新视图的类更改为SKView
3.在您的视图控制器 .h 文件中,为以下内容创建一个属性SKView

@property IBOutlet SKView *skView;

4.Link the SKViewon your storyboard to the skView property.
5.Create a new class, subclassing SKScene. MyScene.h will look like:

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

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

MyScene.m below contains code to create a particle effect whenever and wherever the SKView is touched.

下面的 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.In your main view controller, include your scene class:

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

#import "MyScene.h"

and add code to viewDidLoad to initialise the SKView:

并向 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];
}

You should then have a working SKScenewithin your main UIView.

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

回答by Fattie

2018

2018年

This is now very easy with modern Xcode.

现在使用现代 Xcode 非常容易。

1. In Xcode, click to create a new

1.在Xcode中,点击新建

"SpriteKit Particle File"

“SpriteKit 粒子文件”

it will be a single .sksfile.

它将是一个.sks文件。

(Do notchoose "SceneKit Particle System File". Choose "SpriteKit Particle File".)

(千万不能选“SceneKit粒子系统文件”,选择“SpriteKit粒子文件”。)

Click once on the .sksfile. Notice the many controls on the right.

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

enter image description here

在此处输入图片说明

The particles will actually be moving, it is a living preview. Anything that can be done with particles, you can do it. It is like using particles in a game engine, except performance is 18 billion times better.

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

2. Have any ordinary UIView, anywhere you want:

2.在任何你想要的地方拥有任何普通的UIView:

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

3. Just use the following code to link:

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

The following slab of code will put your new particle system, inside, the ordinary UIView "teste":

下面的代码将把你的新粒子系统放在普通的 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)

Add this to anything you want.

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

If you want a sparkling button, add it to a button.

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

If you want the whole screen to shower rainbows, add it to a full-screen view.

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

It's that easy.

就这么简单。



Example of how to use the SpriteKit Particle File:

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

Say you want a burstof sparks, which ends.

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

Set the max to 50...

将最大值设置为 50...

enter image description here

在此处输入图片说明

Tip - if your effect "finishes" (ie, it is not a loop), it seems you can simply get rid of the SKScenewhen finished. Like this:

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

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

    delay(1.5) { sk.removeFromSuperview() }

That one line of code at the end seems to clean-up everything.

最后的那一行代码似乎清理了所有内容。



BTW if you want fantastic ideas for particle systems, a great idea is click to the Unity "asset store", where various particle artistsbuy and sell particle systems. Their work will give you great ideas.

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

enter image description here

在此处输入图片说明

Just click "particles" in the list on the right; watch the videos. (Innovative examples.)

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



Note! Apple are going to make it so that you can very simply make a SKView in storyboard, and select the .sksscene. However ..

笔记!Apple 将让你可以非常简单地在故事板中制作一个 SKView,然后选择.sks场景。然而 ..

enter image description here

在此处输入图片说明

... it doesn't work yet! So you need the code fragment above.

……还是不行!所以你需要上面的代码片段。

回答by MoFlo

You can add SKView as a subview within your UIKit hierarchy. A function like the following would work, allowing you to create a UIImageView with the effect as a subview, and then you can add this to your main view. Be sure to link against SpriteKit.

您可以将 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;
}

In the end, if all you need is an emitter, it may be easier to create a CAEmitterLayerand add that as a sublayer to your UIView instead. Of course, that means you have to programmatically create the CAEmitterLayerand can't use the cool Xcode particle editor...

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

回答by GeneCode

Actually there is a way to add particles without SpriteKit - CoreAnimation's CAEmitterCells.

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

This way you can add particles in your UIView easily. If you want to play around with the parameters and get the code easily, get this app (Particle X).

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

It also supports SpriteKit so if you want to play around or design particles on the go and immediately get the code for it, this app is the solution.

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

ps. If you havent notice it, I am the developer of the app - made it to use it myself when designing app and games. :)

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

回答by Fattie

Here's approach totally different approach to try. My buddy gave me this cool way to go. Using CAEmitterCell. All in code! Looks like you need a spark.png image.

这里的方法尝试完全不同的方法。我的朋友给了我这条很酷的路。使用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]
    }
}

Enjoy.

享受。

回答by Andrey Gordeev

You cannot use particle effects within UIViewdirectly.

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

SKEmitterNodemust be in a node tree defined with a node scene (SKScene). The scene node runs an animation loop that renders the contents of the node tree for display. UIViewis static, won't work for it.

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

However, you probably able to create a scene inside your UIView, but I've never tried to do that.

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