Sprite Kit

Sprite Kit is Game Engine base on OpenGL ES.

Project Template

In XCode5, “Project” -> “Application” -> “Game Sprite Kit”.
“Sprite kit” template is created.

ViewController

Just 2 things to do.

  • Get SKView
  • Create Scene class and add it to SKView
- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    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];
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

SKSceneScaleMode
Scale mode

Scale Mode Description
SKSceneScaleModeFill
SKSceneScaleModeAspectFill
SKSceneScaleModeAspectFit
SKSceneScaleModeResizeFill

Scene

MyScene.h

This class is class which extends SKScene

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

MyScene.m

#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;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];
        
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        
        sprite.position = location;
        
        SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
        
        [sprite runAction:[SKAction repeatActionForever:action]];
        
        if ([sprite containsPoint:location]) {
            // Collision
        }
        
        
        [self addChild:sprite];
    }
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}
@end

Axis

Same as OpenGL, left bottom is 0,0

SKNode

Node which is provided Sprite Kit

Name Description
SKSpriteNode Sprite(Image)
SKLabelNode Label, Text
SKEmitterNode Particle
SKShapeNode Path
SKCropNode Crop(Mask)
SKEffectNode Apply Core Image Filter
SKVideoNode Video

We make a group of SKNode using addChild

SKSpriteNode

Display Image

NodeScene.h

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

NodeScene.m

@implementation NodeScene

- (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];
 
        // Square Sprite Node
        SKSpriteNode * spriteColor = [SKSpriteNode node];
        spriteColor.size = CGSizeMake(100, 50);
        spriteColor.color = [UIColor orangeColor];
        
        // Image Sprite Node
        SKTexture * flappy = [SKTexture textureWithImageNamed:@"flappy.png"];
        SKSpriteNode * flappySprite = [SKSpriteNode spriteNodeWithTexture:flappy];
        
        // Image Part Sprite
        SKTexture *textureFlappyPart = [SKTexture textureWithRect:
                                     CGRectMake(0.2, 0.2, 0.5, 0.5) inTexture:flappy];
        SKSpriteNode * spriteFlappyPart = [SKSpriteNode spriteNodeWithTexture:textureFlappyPart];
        
        // Position
        spriteColor.position = CGPointMake(CGRectGetMidX(self.frame) - 200, CGRectGetMidY(self.frame));
        spriteFlappyPart.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
        flappySprite.position = CGPointMake(CGRectGetMidX(self.frame) + 200, CGRectGetMidY(self.frame));
        
        [self addChild:spriteColor];
        [self addChild:flappySprite];
        [self addChild:spriteFlappyPart];
    }
    return self;
}
@end

SKLabelNode

Text

TextNodeScene.h

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

TextNodeScene.m

#import "TextNodeScene.h"
@implementation TextNodeScene
- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]){
        
        SKLabelNode *label = [SKLabelNode labelNodeWithFontNamed:[UIFont systemFontOfSize:0].fontName];
        
        label.text = @"Hello Sprite Kit!";
        
        label.fontSize = 12;  // Font size
        label.fontColor = [UIColor whiteColor];
        label.position = CGPointMake(100, 50);
        label.verticalAlignmentMode = SKLabelVerticalAlignmentModeBottom;    // Bottom
        label.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;  // Left
        // Not for multiline, Long -> UILabel UITextView
        [self addChild:label];
    }
    return self;
}
@end

SKEmitterNode

Particle file(.sks)
“File” -> “Resource” -> “Scene Kit Particle File”

ParticleScene.h

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

ParticleScene.m

#import "ParticleScene.h"

@implementation ParticleScene

- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]){
        
        // MyParticle.sks
        NSString *particlePath = [[NSBundle mainBundle] pathForResource:@"MyParticle" ofType:@"sks"];
        
        // Create SKEmitterNode object
        SKEmitterNode *sparcle = [NSKeyedUnarchiver unarchiveObjectWithFile:particlePath];
        
        // Set position of particle
        sparcle.position = CGPointMake(0, 0);
        
        // Start particle
        [self addChild:sparcle];
        
    }
    return self;
}
@end

SKShapeNode

Shape with bezier path.

SKShapeNode.m

#import "ShapeScene.h"

@implementation ShapeScene

- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]){
        
        UIBezierPath *path = [self createBezierPath];
        
        SKShapeNode * line = [SKShapeNode node];
        line.path = path.CGPath;
        line.lineWidth = 2;     // width
        line.strokeColor = [UIColor lightGrayColor];    // Line color
        line.fillColor = [SKColor blueColor];           // Fill color
        line.antialiased = NO;                          // Antialiasing
        line.glowWidth = 5.0;                           // Glow effect area
        
        [self addChild:line];
    }
    return self;
}

- (UIBezierPath *)createBezierPath {
    UIBezierPath *aPath = [UIBezierPath bezierPath];
    
    [aPath moveToPoint:CGPointMake(100.0, 0.0)];
    [aPath addLineToPoint:CGPointMake(200.0, 40.0)];
    [aPath addLineToPoint:CGPointMake(160, 140)];
    [aPath addLineToPoint:CGPointMake(40.0, 140)];
    [aPath addLineToPoint:CGPointMake(0.0, 40.0)];
    [aPath closePath];
    return aPath;
}
@end

SKCropNode

CropScene.m


@implementation CropScene

- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]){
        
        SKSpriteNode *ship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        
        SKSpriteNode *picture = [SKSpriteNode spriteNodeWithImageNamed:@"background"];
        
        ship.xScale = ship.yScale = 0.75;
        
        // Create crop
        SKCropNode *crop = [SKCropNode node];
        crop.maskNode = ship;
        [crop addChild:picture];
        crop.position = CGPointMake(160, 200);
        
        [self addChild:crop];
    }
    return self;
}

@end

SKEffectNode

EffectScene.m

@implementation EffectScene

- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]){
        
        // Square Sprite Node
        SKSpriteNode * spriteColor = [SKSpriteNode node];
        spriteColor.size = CGSizeMake(100, 50);
        spriteColor.color = [UIColor orangeColor];
        spriteColor.position = CGPointMake(160, 200);
        
        NSArray *targets = @[spriteColor];
        [self addChild:[self blurredNode:targets]];
    }
    return self;
}

- (SKNode *)blurredNode:(NSArray *)targets {
    
    SKEffectNode *node = [[SKEffectNode alloc] init];
    
    node.filter = [self blurFilter:10.0f];
    node.blendMode = SKBlendModeAlpha;
    
    for ( SKNode *target in targets ) {
        [node addChild:target];
    }
    
    return node;
}

- (CIFilter *)blurFilter:(float)radius {
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setDefaults];
    [filter setValue:@(radius) forKey:@"inputRadius"];
    return filter;
}
@end