Developing 2D Games With Sprite Kit

Preview:

Citation preview

These are confidential sessions—please refrain from streaming, blogging, or taking pictures

These are confidential sessions—please refrain from streaming, blogging, or taking pictures

Developing 2D Games with Sprite Kit

Allan Schaffer Game Technologies Evangelist aschaffer@apple.com

Enhancing 2D game developmentSprite Kit

Sprites, Shapes and Particles Animations and Physics Audio, Video, Visual Effects

Enhancing 2D game developmentSprite Kit

Sprites, Shapes and Particles Animations and Physics Audio, Video, Visual Effects

Enhancing 2D game developmentSprite Kit

Agenda

• Sprites and particles • Textures and atlases • Scene transitions • Drawing order • Animation

Sprites and Particles

Scene Graph

Foreground

SKScene

Hero

HUD

Background

Nodes

Life Counter

HP Bar

Tree

Background Image

Tree

Displaying Sprite Kit Content

Application UIView / NSView

SKView

!

[skView presentScene:myScene];

Scrolling Background

Tree

Background Image

HUD

Foreground

Hero

Life Counter

SKScene

The Sprite Kit Game Loop

-update:

SKScene evaluates actions

Each Frame

The Sprite Kit Game Loop

-update:

SKScene evaluates actions-didEvaluateActions

Each FrameSKView renders the scene

-didSimulatePhysics

SKScene simulates physics

Node Classes

SKSpriteNode

SKCropNodeSKLabelNode

SKScene

SKEmitterNode

SKShapeNode

SKNode

SKEffectNode

The base classSKNode

• Used for grouping in node tree @property SKNode* parent; @property NSArray* children;

• Used for positioning itself and children @property CGPoint position; // relative to parent @property CGFloat zRotation; // radians @property CGFloat xScale, yScale; // scaling

• Can control visibility @property CGFloat alpha;@property BOOL hidden;

• Can run actions • Can be a physics body

SKNode

Main rendering node typeSKSpriteNode

• Draws a 2D image ■ Can be a color ■ Can be a texture image ■ Has an explicit size

SKSpriteNode

Simple creationSKSpriteNode

SKSpriteNode *ship = [SKSpriteNode spriteNodeWithImageNamed:@”ship.png”]; ship.position = CGPointMake(40.0,30.0); [scene addChild:ship]; !

• Creates a sprite matching the image size • Centers sprite on image center (0.5, 0.5) • Positions sprite at (40, 30) relative to its parent • Follows UIImage -imageNamed: behavior

Particles!SKEmitterNode

• Full featured 2D particle system • Standard startValue and speed • Advanced keyframe sequence controls

Particle attributes

• Texture • Scale • Rotation • Emission angle • Emission speed • Blend modes • Birth rate • Particle count • Lifetime • Position

• Z position • Speed • Size • Angle • Acceleration • Rotation speed • Scale speed • Color • Blend factor • Alpha

SKEmitterNode

Xcode particle editorSKEmitterNode

• Easy-to-use particle editor ■ Integrated directly into Xcode 5

• Edit SKEmitterNode attributes visually ■ Separates design from programming

• Creates an archived SKEmitterNode ■ Use NSKeyedUnarchiver to unarchive

DemoCreating and loading particles

Node classesSprite Kit Nodes

Class Description

SKNode Parent class of all nodes

SKScene Root of the scene graph

SKSpriteNode Renders a textured sprite

SKEmitterNode Generates and renders particles

SKLabelNode Renders a text string

SKVideoNode Plays video content

SKShapeNode Renders a shape based on a Core Graphics path

SKEffectNode Applies a Core Image filter to its children

SKCropNode Crops its children using a mask

Textures and Atlases

Sprite Kit bitmap dataSKTexture

• Fundamental Sprite Kit bitmap object • Very flexible [SKTexture textureWithImageNamed:@"ship.png"]; [SKTexture textureWithCGImage:myCGImageRef]; [SKTexture textureWithData:rgbaNSData size:CGSizeMake(100, 100)]; [SKTexture textureWithImage:myUIImage]; [SKTexture textureWithRect:CGRectMake(100, 100, 80, 80) inTexture:tex1];

• Properties for filter mode, mipmap generation, pre-loading • Reference from a texture atlas

Key to performanceTexture Atlases

• Many images combined into a single larger image ■ Saves memory ■ Improves drawing efficiency

big_tree_base.png big_tree_middle.png

big_tree_top.png blobShadow.png

cave_base.png cave_destroyed.png

cave_top.png minionSplort.png

small_tree_base.png small_tree_middle.png

small_tree_top.png warrior_throw_hammer.png

In Sprite KitTexture Atlases

• Xcode generates atlases automatically ■ From individual image files ■ Retina and non-retina if provided

• Packed for maximum efficiency ■ Automatic rotation ■ Transparent edges trimmed ■ Opaque images extruded ■ Up to 2048 x 2048

• Put your files in a “.atlas” folder • Drag the folder into your project • Done

Creating a Texture Atlas

Environment.atlas/ big_tree_base.png

big_tree_middle.png big_tree_top.png blobShadow.png

cave_base.png cave_destroyed.png

cave_top.png minionSplort.png

small_tree_base.png small_tree_middle.png

small_tree_top.png warrior_throw_hammer.png

Loading From a Texture Atlas

• Load a SKTexture from a stand-alone file SKTexture *texture = [SKTexture textureWithImageNamed:@”big_tree_base.png”]; !

• Load a SKTexture from a texture atlas SKTexture *texture = [SKTexture textureWithImageNamed:@”big_tree_base.png”]; !

• It’s the same ■ Sprite Kit manages atlases for you

Deeper into SKScene

A scene of contentSKScene

• Root node of the scene graph • Displayed by a SKView • Inherits from SKEffectNode • Runs per-frame loop -update: -didEvaluateActions -didSimulatePhysics

Scrolling Background

Tree

Background Image

HUD

Foreground

Hero

Life Counter

SKScene

OrganizationSKScene

• Typical to create different scenes for ■ Main menu ■ Game options ■ Gameplay ■ Game over

• Level 1 • Level 2 • Level 3 • ... • Level N

Transition between scenesSKTransition

• Performs a transition between current and new SKScene • Standard transitions

■ Cross fade, fade thru color ■ Doors closing, doors opening ■ Flip vertical, flip horizontal ■ Move in, push in, reveal ■ CIFilter transitions

• Option to pause rendering of either scene

ExampleSKTransition

// New scene slides on top of the old scene. SKTransition *moveIn = [SKTransition moveInWithDirection:SKTransitionDirectionUp duration:2.0]; !

// Allow old scene’s animations to continue during transition moveIn.pausesOutgoingScene = NO; !

// Present the new scene with the transition [myView presentScene:newScene transition:moveIn];

Drawing Order and Performance

Standard behaviorDrawing Order

• Two simple rules ■ A parent draws its content before rendering its children ■ Children are rendered in the order they appear in the child array

Helicopter

Missiles

Body

Primary Rotor

Tail Rotor

zPositionDrawing Order

• Gives the node an explicit height ■ Relative to its parent node

• Nodes drawn in global Z order

Helicopter (z=100)

Body (z=0)

Primary Rotor (z=1)

Tail Rotor (z=1)

Missiles (z=-1)

SKScene ignoresSiblingOrder propertyDrawing Order

• Allows nodes in scene to be drawn in any order ■ Sprite Kit batches scene by state ■ Results in fewer draw calls

• With ignoresSiblingOrder and zPosition ■ Each node’s global Z position is calculated ■ Drawn from lowest Z to highest Z ■ Sprite Kit sorts nodes at equal Z for optimal batching

Key insightDrawing Order

• Compose scene as layers ■ Give objects common Z value per layer ■ Place overlapping objects in different layers

• Set ignoreSiblingOrder

Actions and Animations

Actions Overview

[node runAction: [SKAction rotateByAngle:M_PI duration:1.0] ];

• Very simple to use ■ Single action class—SKAction ■ One line creation ■ Chainable, reusable, readable

• Like a scripting language for Sprite Kit ■ Actions directly affect the node it is run on ■ Actions run immediately ■ Removed on completion

Basic SKActions

[SKAction rotateByAngle:M_PI duration:1.0]; !![SKAction moveTo:aCGPoint duration:1.0]; !![SKAction fadeAlphaTo:0.75 duration:1.0]; !![SKAction scaleBy:2.0 duration:1.0]; !![SKAction scaleXBy:1.5 y:0.5 duration:1.0];

SequencesCompound Actions

!

!

[myNode runAction: [SKAction sequence:@[action1, action2, action3]] ];

action1 action2 action3

SKAction Sequence

1.0 sec 2.0 sec 0.5 sec

3.5 sec

GroupsCompound Actions

!

!

[myNode runAction: [SKAction group:@[action1, action2, action3]] ];

action1

action2

action3

SKAction Group

1.0 sec

2.0 sec

0.5 sec

2.0 sec

Sequences of groupsCompound Actions

SKAction *group = [SKAction group:@[scale, rotate]]; !

[myNode runAction: [SKAction sequence:@[move, group, fadeout]] ];

move fadeout

Sequence with a Group

rotate

scale

AnimateSpecialty SKActions

[SKAction animateWithTextures:@[tex0, tex1, tex2] timePerFrame:0.1]; !!!

Follow pathSpecialty SKActions

![SKAction followPath:myPath duration:2.5] ![SKAction followPath:myPath asOffset:YES orientToPath:NO duration:5.0]; !

Remove from parentSpecialty SKActions

/* zero duration */ ![SKAction removeFromParent]; !!!!/* fade out a sprite and then remove it */ !SKAction *fade = [SKAction fadeOutWithDuration:1.0]; SKAction *remove = [SKAction removeFromParent]; ![sprite runAction:[SKAction sequence:@[fade, remove]];

Run blockSpecialty SKActions

/* zero duration, fires once */ ![SKAction runBlock:^{ doSomething(); }] !!!!/* show game over menu after character death animation */ !SKAction *fade = [SKAction fadeOutWithDuration:1.0]; SKAction *remove = [SKAction removeFromParent]; SKAction *showMenu = [SKAction runBlock:^{ [self showGameOverMenu]; }]; ![heroSprite runAction: [SKAction sequence:@[fade, showMenu, remove]] ]; !

Large catalogSKActions

• moveByX: y: duration: • moveTo: duration: • moveToX: duration: • moveToY: duration: • rotateByAngle: duration: • rotateToAngle: duration: • scaleXTo: duration: • scaleYTo: duration: • speedBy: duration: • speedTo: duration: • scaleBy: duration: • scaleXBy: y: duration: • scaleTo: duration: • scaleXTo: y: duration:

• sequence: • group: • setTexture: • runBlock: • runBlock: queue: • removeFromParent • performSelector: onTarget: • resizeByWidth: height: duration: • resizeToWidth: height: duration: • resizeToWidth: duration: • resizeToHeight: duration: • repeatAction: count: • repeatActionForever: • fadeInWithDuration:

• fadeOutWithDuration: • fadeAlphaBy: duration: • fadeAlphaTo: duration: • animateWithTextures: timePerFrame: • animateWithTextures: timePerFrame: resize: • playSoundFileNamed: waitForCompletion: • colorizeWithColor: colorBlendFactor: • colorizeWithColorBlendFactor: duration: • followPath: duration: • followPath: asOffset: orientToPath: • waitForDuration: • waitForDuration: withRange: • runAction: onChildWithName: • customActionWithDuration: actionBlock:

Wrap-Up

• Introduction to Sprite Kit • Sprites and particles • Textures and atlases • Scene transitions • Drawing order • Animation

More Information

Allan Schaffer Game Technologies Evangelist aschaffer@apple.com !

Apple Developer Forums http://devforums.apple.com/ !

Developer Documentation http://developer.apple.com/library/

Recommended