web-dev-qa-db-ja.com

iOS 7 SpriteKit Particleを使用したゲームではないiOSアプリにパーティクルエフェクトを追加する方法は?

アプリに雨の粒子効果を追加する必要があります。このアイデアを実際に実行する方法を見つけるのに苦労しています。

このCALayerアプローチチュートリアルに従ってみました: Link しかし、Xcode 5で利用可能な新しいiOS 7 SpriteKit Particle Emitterを考えると、これが最良のアプローチかどうかはわかりません。

既に.sksファイルを作成しており、それは私の階層にありますが、ストーリーボード/プロジェクトに追加することはできません。

とはいえ、SpriteKitパーティクル(sks)をビューに正確に追加するにはどうすればよいですか?私はゲーム開発者ではないので、SpriteKitフレームワークのシーンやレイヤーなどにまったく精通していません。これを理解できるように、可能な限り詳細とサンプルコードが必要です

更新:私は仲間からの回答で提供された指示に従っていますSOメンバー:AyatollahAndy、以下の彼の回答をご覧ください。SKSceneを私のviewタッチイベントが受信されると、アプリがクラッシュします。 enter image description here

ありがとう

34
vzm

SKSceneUIViewを作成して、SKEmitterNode粒子効果を追加します。

これを行う1つの方法:

1.ストーリーボードで(または必要に応じてプログラムで)既存のビューの上にビューオブジェクトを追加し、必要に応じてサイズを変更します。
2。新しいビューのクラスをSKViewに変更します
3。View Controller .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が機能するはずです。

50
AndyOS

2018年

これは、最新のXcodeで非常に簡単になりました。

1. Xcodeで、クリックして新規を作成します

「SpriteKitパーティクルファイル」

単一の.sksファイル。

(Donot「SceneKit Particle System File」を選択します。「SpriteKit Particle File」を選択します。)

.sksファイル。右側の多くのコントロールに注意してください

enter image description here

パーティクルは実際に移動します。これは生きているプレビューです。パーティクルでできることなら何でもできます。パフォーマンスが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パーティクルファイルの使用例:

終了する火花のburstが欲しいとします。

最大値を50に設定...

enter image description here

ヒント-エフェクトが「フィニッシュ」する(つまり、ループではない)場合、終了時にSKSceneを単純に削除できるようです。このような:

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

    delay(1.5) { sk.removeFromSuperview() }

最後の1行のコードはすべてをクリーンアップするようです。


ところで、パーティクルシステムの素晴らしいアイデアが必要な場合は、Unityの「アセットストア」をクリックしてください。さまざまなパーティクルアーティストパーティクルシステムを売買します。彼らの仕事は素晴らしいアイデアを与えてくれます。

enter image description here

右側のリストで「粒子」をクリックするだけです。ビデオを見る。 ( 革新的な例 。)


注意! Appleは、ストーリーボードで非常に簡単にSKViewを作成し、.sksシーン。しかしながら ..

enter image description here

...まだ機能しません!したがって、上記のコードフラグメントが必要です。

30
Fattie

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パーティクルエディタを使用できないことを意味します...

7
MoFlo

実際、SpriteKitなしでパーティクルを追加する方法があります-CoreAnimationのCAEmitterCells。

これにより、UIViewにパーティクルを簡単に追加できます。パラメーターをいじってコードを簡単に入手したい場合は、このアプリを入手してください( Particle X )。

また、SpriteKitもサポートしているため、外出先で遊んだり、パーティクルをデザインしたり、すぐにコードを取得したい場合は、このアプリがソリューションです。

追伸あなたがそれに気付いていないなら、私はアプリの開発者です-アプリやゲームを設計するときに自分でそれを使用するようにしました。 :)

4
GeneCode

まったく異なるアプローチを試してみてください。私の相棒は私にこのクールな道を教えてくれました。 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]
    }
}

楽しい。

2
Fattie