J'ai besoin d'ajouter un effet de particules de pluie à mon application, j'ai eu du mal à trouver des moyens d'exécuter cette idée.
J'ai essayé de suivre ce didacticiel sur l'approche CALayer: Link mais je ne sais pas si c'est la meilleure approche, compte tenu du nouvel émetteur de particules SpriteKit iOS 7 disponible dans Xcode 5.
J'ai déjà créé le .sks
fichier et il est dans ma hiérarchie, mais je ne parviens toujours pas à l'ajouter à mon storyboard/projet.
Cela étant dit, Comment ajouter exactement une particule SpriteKit (sks) à ma vue? Je ne connais pas du tout les scènes, les superpositions, etc. dans le framework SpriteKit car je ne suis pas développeur de jeux. J'ai besoin du plus de détails et d'un exemple de code possible pour pouvoir le comprendre s'il vous plaît
MISE À JOUR: J'ai suivi la direction fournie dans une réponse par un collègue SO membre: AyatollahAndy, veuillez voir sa réponse ci-dessous. Bien que j'ai pu afficher le SKScene
dans mon view
l'application se bloque lorsqu'un événement tactile est reçu. J'obtiens ce qui suit:
Merci
Créez un SKScene
dans votre UIView
pour ajouter un effet de particule SKEmitterNode
.
Une façon de procéder:
1.Dans le storyboard (ou par programme si vous préférez), ajoutez un objet View au-dessus de la vue existante et redimensionnez-le selon vos besoins.
2.Changez la classe de la nouvelle vue en SKView
3.Dans votre fichier .h de contrôleur de vue, créez une propriété pour le SKView
:
@property IBOutlet SKView *skView;
4.Liez le SKView
de votre storyboard à la propriété skView.
5.Créez une nouvelle classe, sous-classe SKScene
. MyScene.h ressemblera à:
#import <SpriteKit/SpriteKit.h>
@interface MyScene : SKScene
@end
MyScene.m ci-dessous contient du code pour créer un effet de particules quand et où le SKView est touché.
#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.Dans votre contrôleur de vue principal, incluez votre classe de scène:
#import "MyScene.h"
et ajoutez du code à viewDidLoad pour initialiser le 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];
}
Vous devriez alors avoir un SKScene
fonctionnel dans votre UIView
principal.
C'est maintenant très facile avec Xcode moderne.
ce sera un seul .sks
fichier.
(Ne pas choisissez "Fichier système de particules SceneKit". Choisissez "Fichier particules SpriteKit".)
Cliquez une fois sur le .sks
fichier. Remarquez les nombreux contrôles à droite .
Les particules vont effectivement se déplacer, c'est un aperçu vivant. Tout ce qui peut être fait avec des particules, vous pouvez le faire. C'est comme utiliser des particules dans un moteur de jeu, sauf que les performances sont 18 milliards de fois meilleures.
@IBOutlet weak var teste: UIView! // totally ordinary UIView
La dalle de code suivante mettra votre nouveau système de particules à l'intérieur du "teste" UIView ordinaire:
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)
Ajoutez-le à tout ce que vous voulez.
Si vous voulez un bouton scintillant, ajoutez-le à un bouton.
Si vous souhaitez que l'écran entier couvre les arcs-en-ciel, ajoutez-le à une vue plein écran.
C'est si facile.
Disons que vous voulez une rafale d'étincelles, qui se termine.
Réglez le maximum à 50 ...
Astuce - si votre effet "se termine" (c'est-à-dire qu'il ne s'agit pas d'une boucle), il semble que vous pouvez simplement vous débarrasser de SKScene
une fois terminé. Comme ça:
...
scene.addChild(en!)
sk.presentScene(scene)
delay(1.5) { sk.removeFromSuperview() }
Cette ligne de code à la fin semble tout nettoyer.
BTW si vous voulez des idées fantastiques pour les systèmes de particules, une bonne idée est de cliquer sur le "magasin de ressources" Unity, où divers artistes de particules acheter et vendre des systèmes de particules. Leur travail vous donnera de bonnes idées.
Cliquez simplement sur "particules" dans la liste de droite; regardez les vidéos. ( Exemples innovants .)
Remarque! Apple va faire en sorte que vous puissiez très simplement faire un SKView dans le storyboard, et sélectionner le .sks
scène. Pourtant ..
... ça ne marche pas encore! Vous avez donc besoin du fragment de code ci-dessus.
Vous pouvez ajouter SKView en tant que sous-vue dans votre hiérarchie UIKit. Une fonction comme la suivante fonctionnerait, vous permettant de créer un UIImageView avec l'effet en tant que sous-vue, puis vous pouvez l'ajouter à votre vue principale. Assurez-vous de créer un lien contre 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;
}
En fin de compte, si tout ce dont vous avez besoin est un émetteur, il peut être plus facile de créer un CAEmitterLayer
et de l'ajouter en tant que sous-couche à votre UIView. Bien sûr, cela signifie que vous devez créer par programme le CAEmitterLayer
et ne pouvez pas utiliser l'éditeur de particules Xcode cool ...
En fait, il existe un moyen d'ajouter des particules sans SpriteKit - CAEmitterCells de CoreAnimation.
De cette façon, vous pouvez facilement ajouter des particules dans votre UIView. Si vous voulez jouer avec les paramètres et obtenir le code facilement, téléchargez cette application ( Particle X ).
Il prend également en charge SpriteKit, donc si vous voulez jouer ou concevoir des particules en déplacement et obtenir immédiatement le code correspondant, cette application est la solution.
ps. Si vous ne l'avez pas remarqué, je suis le développeur de l'application - je l'ai fait pour l'utiliser moi-même lors de la conception d'applications et de jeux. :)
Voici une approche totalement différente à essayer. Mon copain m'a donné cette façon cool de faire. Utilisation de CAEmitterCell
. Tout en code! Il semble que vous ayez besoin d'une image 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]
}
}
Prendre plaisir.