Search code examples
iosobjective-cuiviewsprite-kitskemitternode

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


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 : Link but I am not quite sure if this is the best approach, considering the new iOS 7 SpriteKit Particle Emitter available in Xcode 5.

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

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

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 SKScene in my view the app crashes when any touch event is received. I get the following: enter image description here

Thanks


Solution

  • Create a SKScene in your UIView to add a SKEmitterNode particle effect.

    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:

    @property IBOutlet SKView *skView;
    

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

    #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.

    #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:

    #import "MyScene.h"
    

    and add code to viewDidLoad to initialise the 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 SKScene within your main UIView.