我需要在我的应用程序中添加雨粒子效果,我一直很难找到实际执行这个想法的方法。
我尝试了这个CALayer方法教程:Link但是我不太确定这是否是最好的方法,考虑到Xcode 5中新的iOS 7 SpriteKit粒子发射器。
我已经创建了.sks
文件并且它在我的层次结构中,但我仍然无法将其添加到我的故事板/项目中。
话虽如此, 我究竟如何在我的视图中添加SpriteKit粒子(sks)?我对SpriteKit框架中的场景,分层等并不熟悉,因为我不是游戏开发人员。 我需要尽可能多的细节和示例代码,以便我能够解决这个问题
更新:
我按照SO成员答案中提供的指示:AyatollahAndy,请参阅下面的答案。虽然我能够在我的SKScene
中显示view
,但在收到任何触摸事件时应用程序崩溃了。我得到以下内容:
由于
答案 0 :(得分:50)
在SKScene
中创建UIView
以添加SKEmitterNode
粒子效果。
这样做的一种方法:
1.在故事板中(或者以编程方式,如果您愿意)在现有视图的顶部添加View对象,并根据需要调整其大小。
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
中使用UIView
。
答案 1 :(得分:28)
现在Xcode非常容易。
它将是一个.sks
文件。
(不选择“SceneKit粒子系统文件”。选择“SpriteKit粒子文件”。)
点击.sks
文件。请注意右侧的许多控件。
粒子实际上会移动,这是一个活生生的预览。任何可以通过粒子完成的事情,你都可以做到。就像在游戏引擎中使用粒子一样,性能要好180亿倍。
@IBOutlet weak var teste: UIView! // totally ordinary UIView
下面的代码将把你的新粒子系统放在普通的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)
将此添加到您想要的任何内容。
如果您想要一个闪亮的按钮,请将其添加到按钮。
如果您希望整个屏幕能够淋浴彩虹,请将其添加到全屏视图中。
就这么简单。
假设你想要一个爆发的火花,结束。
将最大值设置为50 ...
提示 - 如果你的效果“完成”(即,它不是一个循环),看起来你完全可以简单地摆脱SKScene
。像这样:
...
scene.addChild(en!)
sk.presentScene(scene)
delay(1.5) { sk.removeFromSuperview() }
最后一行代码似乎可以清理所有内容。
如果你想要关于粒子系统的奇妙想法,那么一个好主意是点击Unity“资产商店”,其中各种粒子艺术家买卖粒子系统。他们的工作会给你很好的想法。只需点击右侧列表中的“粒子”即可;观看视频。 (Innovative examples。)
请注意! Apple将会制作它,以便您可以非常简单地在故事板中制作SKView,并选择.sks
场景。但是......
......它还没有用!所以你需要上面的代码片段。
答案 2 :(得分:7)
您可以在您的UIKit层次结构中添加SKView作为子视图。如下所示的函数可以使用,允许您创建一个具有子视图效果的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粒子编辑器......
答案 3 :(得分:4)
实际上有一种方法可以在没有SpriteKit的情况下添加粒子--CoreAnimation的CAEmitterCells。
这样您就可以轻松地在UIView中添加粒子。如果您想要使用参数并轻松获取代码,请获取此应用程序(Particle X)。
它还支持SpriteKit,所以如果你想在游戏中玩或设计粒子并立即获得它的代码,这个应用程序就是解决方案。
PS。如果您没有注意到它,我是应用程序的开发者 - 在设计应用程序和游戏时自己使用它。 :)
答案 4 :(得分:2)
这是尝试完全不同的方法。我的伙伴给了我这个很酷的方式。使用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]
}
}
享受。
答案 5 :(得分:1)
出于可见性原因,将其放在此处。
关于.clear
backgroundColor
用户的答案是正确的,除了您还必须将allowsTransparency
的{{1}}属性设置为'true'。
SKView
如果您未将skView.allowsTransparency = true
skView.backgroundColor = .clear // (not nil)
scene.backgroundColor = .clear
设置为true,并且将allowsTransparency
布置在SKView
上方,则合成引擎将适合并发送您的GPU即使只绘制了一个粒子,红线也是如此。 (在模拟器中,CPU将改为峰值。)
答案 6 :(得分:-1)
您无法直接在UIView
内使用粒子效果。
SKEmitterNode
必须位于使用节点场景(SKScene
)定义的节点树中。场景节点运行动画循环,该循环呈现节点树的内容以供显示。 UIView
是静态的,对它不起作用。
但是,您可能在UIView
内创建了一个场景,但我从未尝试过这样做。