WWDC2013 Session 503

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Good afternoon.
Welcome to Designing
Games with Sprite Kit.
My name is Norman Wang.
I'm with the game
technology team at Apple.
So today, I'll be very-- I'm
very excited to share with some
of the very exciting features
and tools for the runtime,
allow you to maximize
the performance,
as well as minimize
the iteration time
to build your game.
So, for those of you who have
missed the earlier session,
introduction to Sprite
Kit, here's a quick recap.
So, Sprite Kit is a high
performance 2D rendering engine
that is available in OS
X Mavericks and iOS 7.
It has built-in physics support
that features all the 2D
physics need for your game.
It is the-- since the platform--
the framework is available
on both iOS 7 and Mac OS X,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
they allow you to build once and
deploy it to multiple devices
that include the iOS running
device and the Mac OS hardware.
Not only Sprite Kit comes
with a super fast runtime,
but we also provide a
lot of tools to allow you
to integrate directly into
your games or pipeline.
So, we're covering
some of that today.
So, in terms of the feature
for rendering the animation,
we have a lot of
features that's provided.
That includes sprites,
shapes, particles,
we also support non-linear
animation, we provide support
for audio, video as well
different visual effects.
So, I hope all of you have
seen the adventure demo so far
and it is a production
quality sample code
that was provided along with the
release of Sprite Kit framework.
They also come with code
explained detailed documentation
on how the game is created.
So, I'll be referring to
various bits and pieces
from the Adventure demo in
this talk to show you how quick
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and easy it is to
integrate Sprite Kit directly
into your game.
So, we'll start with looking
at your Adventure art pipeline
to see how the Adventure
Game can do quick iteration
on importing art files
into the runtime.
And then we will
be looking at how
to create various visual
effects for using the Sprite Kit
that include post-processing
and particle system.
I'll have-- we have some
very special guests today
who will be joining us
that will be talking
about how their experience is
when they build the Adventure
Game using Sprite Kit.
And I'll be wrapping up
with how to develop some
of your custom tool that
include level editor,
complex action editor, and some
of the best practices
for using Sprite Kit.
So, the Adventure Game
is a very complex game.
And what really goes
in to the Adventure?
So, Adventure manages a lot
of data that include lots
of artwork files and we have
about 1,700 art files to load.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have a lot of
sound files to load
for different sound effects,
we have particle effects
and they represent the
tree leaves falling,
smoke and damages.
We have physics that allows
you to interact with the wall
and not ran to objects
as well as AI characters.
We have different-- also
have Collision Mappings.
For example, the entire
Collision Map is data-driven
and design offline and loaded
them dynamically upon game
startup and builds these
dynamic walls inside your level.
So, let's go ahead and look
at the Adventure Game
startup sequence.
How exactly Adventure
is doing upon startup?
So, when the game is load upon
the game application launching
handlers called, we start
loading all the background
assets in parallel because
we need all these assets
to construct our world before
we start issuing the first draw
call will perform all the
asset loading in the background
and get them loaded
as fast they can.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Once we have these assets
in memory, we will go ahead
and create an instance
of a SKScene.
Once we have the scene, we'll
start placing enemies, spawners,
as well as the Boss into
different places in the world.
After that, we'll be parsing and
reading an offline Collision Map
that will indicate and build
the physics world where exactly
at the world-- lost
in your world.
Finally, the scene
is constructed
and we'll use presentScene
method to present
that to a SKscene which part
of your [inaudible] file.
And also, we also register
for the game controller
notifications
for adding game controller
support.
So, in the first session,
we actually looked at some
of the game update loop
of what a typical game
about loop using Sprite Kit.
But now we're going
to talk a little bit
into the Adventure Game.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, the Adventure
Game actually tab
into this update
loop at two places.
Number one, when
the frame starts,
update method get called.
Here, what we do is we
update all the input
that includes controllers,
touches, mouse and keyboard.
So, once we have this
input, we translate them
into delta movement
for the main character.
So now, our hero knows and
either walk from A to B.
So, once that's happening, we
also update AI, AI will say,
"OK, maybe we should provide--
perform some recasting
to see whether the player
or the hero is visible or not.
If it is, let's translate
that into a Delta movement."
So, once you have this movement,
we'll start issuing
animation playback frame.
So, I know if I move from A
to B, I don't skate from A
to B, I walk from A to B.
So, once that's done,
we'll go to--
we wait until we finish
simulating all the physics.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, if I'm walking from A to
B, there happen to be a wall
in between, physics will kick in
and stop me right in
front of the wall.
So, this is a really
safe place for you
to assume all the objects final
positions are finalized before
the frame.
So, at this time, we know
the character positions
are finalized.
We'll update the camera, so the
camera will follow the player
and also reveal different
parts of the world.
We also update the tree parallax
because the camera
has been moved,
and the fallen leaves have to
be following with the tree.
Due to that complexity of
this game, it presents us
with a lot of challenges.
Number one, the construction
of the scene cannot happen
unless all the assets are loaded
including 1,700 art files
and we have huge amount
of data dependencies
in each category.
If you just look at
the background tiles,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the level itself is a 4K x
4K tile map that gets divided
into 128 by 128 grid,
sorry, 32 by 32 grid
and each tile is
128 by 128 size.
We also have a lot
of animation frames.
For example, if we
look at animes,
anime have idle animation,
have a tack animation,
also have walking animation,
and death animation.
So, we have different
animation frame categories
for every single
character in the game.
We also have a lot
of particle effects.
For example, falling
trees, smoke,
and also Collision
Mapping need to be loaded.
So, how do we address
all of these
by using the tools
provided by Sprite Kit?
We're going to go into looking
at some of the art pipeline
for the Adventure Game.
So, diving a little bit
into the Adventure textures,
again we have 1660 texture files
and the game actually used
Texture Atlas for all of them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Character animations are
divided into several atlas.
For example, walking
animation, 42 frames,
that goes into a
single Texture Atlas.
We have the environment,
1024 tiles,
that's a 4K by 4K grid divided
into a single Texture Atlas,
we'll put that I mean
to a Texture Atlas.
The environments like trees,
caves and projectiles,
all of them go to a single
Texture Atlas as well.
So, this is what it looked like,
bunch of loose files as input
that comes in various
shapes and sizes,
passing through the
Sprite Kit tool
and we generate a Texture
Atlas, as simple as that.
So, speaking about
Texture Atlas,
I want to talk a little
bit more on this topic.
It is not a new thing,
but over the years,
for the game I'm looking
at, that's draw call bound,
not everybody is using Texture
Atlas to batch their draw calls.
It's because there's
always this tank
of work that need to be done.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Traditionally, we have artists
that use Photoshop with bits
and pieces of these textures
inside a bigger texture
and save it and also
manually document it
where each textures are.
And this really makes
the iteration time suck.
OK, so if artist is
not doing the work,
we'll have engineers
do the work, right?
So, the engineer will have to
either run some sort of script
in the bulk-- build process or
use some PayTool to run that
and iteration time is
pretty bad as well.
So, we want to lift all
that work off your shoulder
when we designed
Texture Atlas tool.
So, you can just focus
on putting the beautiful
pixels on the screen.
So now, once you
have Texture Atlas,
there're some major
benefits of having that.
So, number one, it minimizes
the amount of GL render state.
If you issue GL to all calls
that have identical render
state, you can combine them
into a single draw call to
minimize the amount of overhead
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for the GL render script change.
It also minimizes the
amount of disk I/O.
Imagine you're loading 10-24
of this background tiles
versus loading a [inaudible]
of-- big texture files.
We also minimize the amount
of memory overhead as well
as avoid memories fragmentation.
I want to talk a little
bit more about this
and this is the Sprite Kit
specific feature where--
if you look at animation frame,
I'm idling here from top down,
I'm about 128 by 128
size, somewhat like that.
And if I'm animating
from standing up pose
to an attack pose,
that's an archer.
So, now my frames stretch
it into say 200 by 100
and if you play these
animation frames side by side,
you notice the feet will
actually pop between frames.
And to fix this, one of
the common methods is
to add transparency borders
to your animation frame
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so that you make sure the
back foot is actually locking
down at exact position
between animation frames.
So, when you play this 42
frames at the same location,
animation look silky smooth.
OK, that solved the problem
but you introduce these
transparent borders
and we are paying 4 bytes
per pixel for something
that really doesn't
contribute to the screen output.
So, Sprite Kit is
actually doing trimming
for these transparency
edges before put
into to the final
Texture Atlas for you,
it helps you save memory.
And they require zero
work from your side.
You can also draw unusual shape,
textures, so you don't have
to follow on certain hardware
the power of tool rule
because the texture
can be any size
in putting into a Texture Atlas.
I can't render that
directly on the screen
without having to
worry about that.
So, to create a Texture Atlas
using Sprite Kit tool is
super easy.
It is integrated
directly into Xcode.
It's just a matter of dragging
a folder into your project
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you'll have your
Texture Atlas.
As long as the folder
has extension called
".atlas" we'll go
ahead and process them.
Each folder will turn into
a single Texture Atlas
and you can start referencing
them at runtime right away.
That's it, as simple as that.
So here, we have
a bunch of files
from Finder, drag
them into Xcode.
Call them Environment at
a folderextension.atlas,
press Command B and
you are done.
You can also use the Texture
Atlas generator not just
for 2D Sprite Kit enabled
games, you can also use it
for any OpenGL enabled games
because the Texture format
is OpenGL compatible.
So, if you want to
build [inaudible] game,
I use Texture Atlas say for
[inaudible] you can go ahead
and use that, the output
is atlas C bundle format
which contains a PNG file
which is the Texture Atlas
texture and the plist file.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And plist file, you can
just read it in and iterate
through the NCDictionaries
and it will tell you
all the attribute
of every single texture
that include whether
they are rotated or not.
What's the original size?
Where it is inside the quad of
your Texture Atlas and so on.
But if you are using
Sprite Kit product template,
we automatically turn on
this build setting for you,
so you don't have
to do anything.
But if you are using-- trying to
enable this for your OpenGL game
or some game that's not using
Sprite Kit project template
in build settings, make
sure you turn this fully
on which I'll show you
in one of the demos.
So, what do we do for you when
you use the Texture Atlas?
What really goes on when
you press Command B?
So, we do the very basic
automatic combination
of textures.
We generate hardware
specific Texture Atlas.
So, if you have a folder of
images that contains Mac,
Mac OS 2X, iPhone,
iPhone 2X, iPad, iPad 2X
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and the new iPhone
5 resolution format.
Guess what?
We generate a Texture Atlas
for each of those devices.
So, when you load a
Texture Atlas on the iPhone,
you don't have to pay a cost
for loading the similar textures
for the iPad or iPad 2X,
it doesn't really matter.
We don't want you to pull--
pay a memory overhead for that.
We also do a Texture split.
One, the Texture Atlas
greater 2K x 2K resolution.
The reason being is 2K x 2K,
it is the maximum
texture size that's going
to be supported on
all iOS 7 devices.
So, as soon as they go beyond
that range, it will split
into another Texture Atlas file
and it will automatically handle
that and you still get
the single plist file.
So, what else do we do?
When we process each
of the source images,
we do automatically rotation
which will take by 90-degree
and look through the light,
"Hey, this might fit better.
OK, let's rotate it,
leave it and put it in."
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We trimmed the transparent
edges, so you don't have
to pay anything that doesn't
have final contribution
to the screen.
But when you request
that texture even
with the same dimension,
that's how it was on the disk?
So, it's magical.
For textures, that's
100 percent opaque.
We're also doing extrude
on each of the edges
by copying those edges
out by one pixel level.
So, if you have a
tile-based game like Adventure
and you move the cameras
around the background,
you will not see flashing edges
between because the
GL is rendering
into the neighboring
Texture tile.
So, here's a quick summary of
how we switched from loose files
in Adventure demo to
use Texture Atlas.
Originally, we go from 1660
file down to 26 Texture Atlases.
So, file iOS significantly
reduced
and also have some
memory savings.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, if you look at the animation
pixels that we're trimmed,
we are trimming the
transparency pixels for each
of the input Textures.
So the summation of the original
pixel count was 90 megapixels
before we turn in
to Texture Atlas.
And after using Texture Atlas,
the number of pixel count
reduced to 29 megapixels
and that's about 61
megapixels of saving,
each pixel cost 4 bytes and
we'll save about 244 max
for doing what, dragging
a folder into Xcode.
So, now, here's the fun part.
We have a Texture
Atlas, how do we load it?
OK, to load a loose
file from disk,
we have this SKTexture class
called TextureWithImageNamed,
you pass an image and we'll load
from disk to SKTexture instance.
Notice, there's couple
of things that's going
on in the background.
Now, I like to share a little
bit of insight with you.
So, Sprite Kit is maintaining
an internal texture cache.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, if you create a
spaceship texture instance,
and later on in another
class, you try to say, "Hey,
I want to create SKTexture
with the same spaceship."
And guess what, we keep
track of all the SKTextures,
that's a memory for you,
everything is probably
reference conduit.
All we do is, all right,
reference count plus one,
give you the previous
instance, so you don't have
to pay additional cost for
creating a duplicate texture.
And also, this way, you
don't have to have some sort
of a [inaudible] manager,
middle layer that keeps track
of all these texture
pointers that say,
"OK, this is app delegate.
Hello, I'm here, I'm the
one that's loading all these
textures and now let's
keep array of pointers.
So, if it's [inaudible]
class, here you go."
You don't have to
write any of that.
How do load now a texture from--
a Texture Atlas once you
put them into an atlas.
It's the exact same API.
You just reference its loose
file name, you don't have
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to worry about which
Texture Atlas it is in.
You don't have to manually
load a Texture Atlas,
this way is 100 percent
automatic.
My favorite quote from Steve
Jobs is, "It just works."
So here, we have
a Texture Atlas,
inside we have the
same tree that's
on the bottom left corner.
Let's use the same API load, you
get exact same texture image.
And now, I want to
talk a little bit
about loose file
versus Texture Atlas.
We support both and they
are interchangeable.
So, number one, it gave you
the advantage of switching back
and forth between lose texture
files versus Texture Atlas.
You no longer have to recompile
your code or having a, "Hey,
if debug, let's use
texture files.
If released, let's
use Texture Atlas."
No, you don't know--
you don't have
to recompile code
for any of that.
And second, we take loose files,
loose files will have
precedents over Texture Atlas.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, having environment
Texture Atlas
and inside you have a tree
object in there and you give
that build to an artist.
And the artist will say, "Oh,
I wanted to just make some
minor changes with these trees.
I don't want to preview that."
So, guess what, the artist
can just drop in that tree--
the new tree that he or she
created inside your bundle,
re-launched the game, we found
out there's a loose over tree
and then we'll manually
load that, so you don't have
to again compile, debug build
our special artist version
and you hand it out.
OK, we also provide, for
advance users, the fine control
of over a Texture Atlas.
So, if you do feel the need
of creating a SKTexture
instance, feel free to do so.
We support-- we follow the same
UIKit and AppKit naming commands
and notice here when you specify
your environment, you don't have
to specify extension,
you don't have
to specify I2X-iPhone,
any of that.
So, we'll use SKTexture
Construct--
the Class Initializer initialize
an environment Texture Atlas.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We get number of
names which is array.
We'll go ahead, iterate
through the array
and create a corresponding
SKTexture by calling the SK--
the Texture Named Method.
And now, I want to have
a quick demo of creating
and loading Texture and also
I want to cover the two ways
of loading a Texture
from a Texture Atlas
including the loose file way
and second I want to
cover the automatic--
the manual way of creating
SKTexture Atlas instance
and iterate that.
So, we'll begin by
creating OS X project.
[ Pause ]
Sure, so we need to render
some background in our scene
so we can go ahead
and drag in a--
or borrow some of the
environment art from Adventure.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So Adventure Atlas, drag
that in, drop it in and say,
"I want to copy it over
to the target, finished."
Let's have a look.
So, we have about 12 files here
and they each look different,
so we decided to use
the big tree base
which is the first
picture and let's use
that as our background,
how do we do that?
Let's clean up the
initialization code.
[ Pause ]
All right, so let's create a
Texture, let's load that Texture
by creating Sprite node so we
use the spriteNodeWithImageNamed
by specifying the
loose image name here.
If you look at the
big tree base,
that matter was a big tree base
[inaudible] on the left side,
set up the anchorpoint,
set up the position and as
with the scene, we can
just build and run that.
[ Pause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There you go.
So we have one node in the
scene and that's our background.
OK, so this is the simple way
of loading a single
Texture from Texture Atlas.
Cool, so let's look at the
app bundle to see what atlas,
what actually goes into our app.
So, say, show Package Contents,
let's go to the Resource folder
and you notice you
have an Atlas C
which is the compiled
version of the Source folder.
So inside, we have our
Texture Atlas which pull images
in there, have the
corresponding plist files,
you can see aliases, whether the
image is fully opaque or not,
we can perform some
optimization in GL level.
What's the original size?
Where it is located
inside the Texture Atlas,
whether the texture is rotated,
all the attributes that's
needed for the runtime?
Now, let's go ahead and
animate the character.
Let's drag in a Boss-- a packet
animation into our scene.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So make sure to copy
into the folder
so now we still call it atlas
extension and now if we look at,
we have about 42
animation frames
of this animation sequence.
So, let's go ahead and add
a character to the scene
and start animating him.
So first, I'd like to add an
instance variable called Boss
and now we have this
animation frames
that we want to load it in.
Let's create NSArray
that contains all
these animation frames.
[ Pause ]
So let's initialize the array,
create a SKTexture Atlas
instance that's Boss--
called Boss Attack which
matches our folder name.
We want to iterate through
this Texture Atlas by look up,
Request Timeout
The server timed out while waiting for the browser's request.
Reference #2.455732b8.1373789568.0
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
However the corresponding
plist file.
[ Pause ]
And now to animate
it, let's go ahead
and add our animation
playback logic
to say the mouse click
handler so what we want
to do is we'd run
action on the Sprite
which is the Boss character.
So, we first defined animation
playback speed, we use SKAction
of anime with texture and
now our Boss should be able
to animate.
All right, every
time we click them--
the button, we'll have
animation sequence.
It's very simple.
So now, I would like to
show you the Build options.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So if you go to Build
settings and just make sure,
because we're using the
Sprite Kit template,
so this option is
automatically enabled.
The next part I want to
cover is visual effects.
Generally speaking, there
are two vague categories
of visual effects.
Number one, post processing
which means that we are
to perform some level
of image processing
on a given render target
which can be [inaudible],
frame buffer or an
input texture.
If you're trying to say
you have a racing game
and playback a motion blur,
usually people grab the
frame buffer, downsize,
followed by app sample
and then you squeeze all
that with radius blur that
has alpha 100 percent in there
so the inside of the
center of the screen
as 100 percent you focus
and slowly blurred out
and you [inaudible] that
on the final screen.
So, totally support that
with-- via Core Image Filters.
We can't show a quick demo and
we also support particle systems
that usually people found a very
large number of small particles
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on the screen and
similarly it's a lifetime
and we can use SKEmitterNode
for that.
So in terms of using
post processing
with Core Image Filters, it can
be applied to any SKEffectNode
so the effect will apply to all
the children, all the children
on this app node will
get flatten first
and the effect will be
applied on this app tree
so you can specify any
filter on the filter property
by creating a new CIFilter.
So here, we created a Gaussian
blur which is quick and simple.
And you can also apply Core
Image Filters with any textures.
So the Texture has a
selector that call Texture
by applying CIFilters, here
we apply same Gaussian blur
to the [inaudible] input texture
and then you get
a result texture
as having that effect on there.
So, we'll have a quick demo
of Sprite Kit running
with CIFilters.
So here, we have a trees
demo from [inaudible] DC 2012
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which was created using
a development version
of Sprite Kit and CIFilter.
So here, we're rendering trees
with three different layers.
We can go ahead and add, you
know, Gaussian blurs to blur all
to show some depths, I know as
well as add some random effects
so that it will show
the creepy feeling.
We can add some particles and
use the old green filters on top
and on the very top,
we can add a distortion
of the [inaudible] environment
by applying the distortion
effect on the wall, on the bulk.
[Applause] So, quick and easy.
You don't have to write any of
the specialized shaders and all
of this is available
on both OS X and iOS.
Now, I want to dive in a little
bit deeper for particles.
So the particle system is being
heavily used for Adventure.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So the leaves, the
damages, the flashes
and the spawning effects are
all done with particle effects.
And the Adventure Game
actually didn't create those
particles manually.
It uses one of the tools
that I will provide as part
of the Sprite Kit Framework.
I iterate these particles
and generate SKS file
and at the runtime, we
deserialized the SKS file
into SKEmitterNode and
add it to the scene.
All the property are already
set and it's good to go.
In the particle editor, we
provide about eight templates
and this is just one of
the templates you can use
to get you started to
whatever the quick effect
that you are looking for.
In terms of SKEmitterNode, we
want to provide a flexibility
for you to get to the exact
look and feel that you want
for your game in order to
generate a particular look
of the particle system therefore
we provided a lot of properties.
But the [inaudible] property is
very time consuming therefore we
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
build a particle
editor inside Xcode.
You can use it to edit any of
the attribute of SKEmitterNode
and also is a good
design pattern
because they separate the
design of the data away
from the engineering
of the code.
And it's also one of
the best ways to learn
about SKEmitter attributes,
because it live editor you
can just drag an attribute
to see the change lively
because we integrate a SKView
inside Xcode.
Here is a quick look of what
the particle editor look
like inside of Xcode.
As you can see, we open SKS file
which a particle
file inside Adventure
and then we can quickly make
a modification to birth rate
and we see the effect
right away.
For particles, we also
provide keyframe sequences.
You can use it to apply some
of the properties of
the SKEmitterNode.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Here, we are applying the
keyframe sequence to the color.
So, it gives you
100 percent control
of what a color sequence look
like from the birth point
of a particle till its death.
So here, when the
particle was spawned,
it have a little bit brown color
and then later on at 25 percent
of age, we go to a
white followed by a red
and when it's-- at the
end of its life cycle,
we turn to a slightly
blue color.
You can also use keyframe
sequences on other properties.
For example, apply
it to a scale.
You can construct this in code.
To-- Here, we have
a quick example
of showing you how we can
use a keyframe sequence
to apply to a scale.
So here, we specify different
timelines and once it was spawn,
it have a scale of 0.2, at the
quarter of the list is timeline,
we change to a scale
to 0.7 and any values
in between will be
interpolating that
and you can just set directly
on a scale of sequence
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and it will be affecting the
scale throughout its lifetime.
You can also add
actions to particles.
Each particle, as soon as they
are spawned by the emitter,
can ask you some of
the complex behaviors.
So if you have really, really
complex behavior that you want--
you're going after
for SKEmitterNode,
we have action property.
Here is a quick example.
This is actually
a particle system.
Each of the particles is
playing back 42 frames
of animation sequence
on a certain speed.
Just to show you some of
the basic functionality
of how powerful particle
actions can give you.
And now, once we tune
the particle system
to the exact look and
feel of what we want,
how do we load that at runtime?
So what we do is we use
NSKeyedUnarchiver and just say,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we want to unarchive BossDamage,
the SKS file and that's it.
It's a one line and
at this point,
you have your SKEmitterNode
instance ready to go,
ready to be added to the
scene, and ready to animate.
Before we jump into the
demo, I want to do some--
give some of the
quick recommendations
for using particle system
like any particle system,
overhauling is not a good thing.
So let's-- one of the good
recommendations I would give
out is to keep the birth
down and we'll recommend
to iterate your particle files
inside using the Xcode editor
to allow you to see the changes
live, perform iteration quickly
with no [inaudible],
command S, command R
and you see the change
live right away.
When particle emitters are not
visible, I'll recommend you
to remove that and Spencer
later on will help--
will come on the stage
and show you how--
sometimes a few particles can
just achieve the very same look
that you're looking after.
So with this, I will
start a quick demo
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of using a particle system.
Let's go ahead and create
a Sprite Kit project,
let's call it demo particles.
So in here, we already
have the scene.
Let's go ahead and create a
particle file from resource.
As you can see, there are
eight different types that's
being provided.
So let's just maybe go crazy
with starting with spark.
Make sure it is in our target.
Let's create-- and this
is what it look like.
Cool. So how about
that's load that in game?
Here I want to tab it, so that
every time when a mouse click,
let's generate SKEmitterNode
and add that to the scene.
Use NSKeyed--
[ Pause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
-- Unarchive with file,
that's where we're looking for
and then we're going to
NSBundle, getting the mainBundle
and then we're going to get
pathForResource of our--
my particle file with
file extension, sks.
Then-- well, we have some error,
we'll go ahead and fix that.
I set the position
to be the location.
We'll add that to the scene.
[ Pause ]
This is what the error is.
[ Pause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
All right, so every
time I click the mouse,
what's the particle count now?
6,500, let's do at
60 frames per second.
So, OK, so that's easy to load,
one liner, setting the position,
adding it, and let's go
ahead and make some changes
to the particle, let's
see how easy it is.
So, I want to create a
similar damage look as soon
as I get hit in the [inaudible].
So, let's go ahead and make
some changes to these particles.
Number one, the birth rate
is a little bit too high,
I don't really need 2,000
so let's go with say, 400,
that looks a little bit
better and the lifetime,
I want to make it slightly
shorter, so let's go with that
and add a little bit
variance for your lifetime.
OK, so that's a little
bit better.
And how about we-- now the Y
value is a little bit flat,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
let's go ahead and stretch
that by a little bit,
so that will be 50.
I think the angle is
a little bit limited,
so let's go ahead
and do all angles.
Speed is a little bit too
high right now and we say,
let's change it to 200,
and let's not do variance,
and obviously if this is
a top down looking games,
so we don't really need a
gravity here, so let's go ahead
and set that to be 0, and
we can change the scale,
say go from 0.4 and we want to
do an increment on the scale
in a positive direction
and wallah.
So, if we decided to go
ahead and change some
of the damaged colors, we can
change slightly like that.
And how about if we make--
if we decide to that this damage
is only one time, I get hit,
I spawned 200 particles and
the particle will finish.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, let's-- we can set
that by setting the maximum
attribute here.
We go 200, so let's run that.
So, every time I get
hit, get the particle
and particle goes away.
[ Applause ]
Next, I like to invite Graeme
Devine and Spencer Lindsay,
will be talking to us about
building the Adventure Game.
>> Thank you Norman.
Hello, I'm Graeme Devine.
>> I'm Spencer Lindsay.
>> Today, we're going
to be talking to you
about building Adventure.
So, what happens with
the do to build it?
[laughs] So, we know
a little bit about it.
We're going to talk about some
of the technical challenges
that we faced in actually
making the demo and some
of the art challenges
that's being able to--
that we have to do unless
you're making the demo too.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, let's take a quick
look at the demo again,
just one last time so that you
can-- so you've seen it lots.
We talked about how the
game has [inaudible] you got
to talk about.
So, the parallax effect that--
as the guy walks around,
we have leaves on our trees
and the-- that the, you know,
that look so nice and parallax
and so forth that looks awesome.
The guy is bumping into the wall
and he sees a colliding well
and he's sliding across this,
you know, the walls nicely,
beautiful leaves falling from
the trees and looking, you know,
nice and thready as
they fall to the ground
and Sprites are animazing
like that's a real characters
and we're going to talk about
how we actually made that too.
Let's talk about the parallax.
Parallax is an old effect that's
a, you know, that we've used
in games in many, many years.
It's actually really easy to do.
If you're looking at the
formula then writing it down,
you can stop doing that now
'cause you don't use formulas.
The sub class SKNode from
more or less everything that,
you know, that we have in the
game, the characters, the,
you know, that the parallax
nodes, anything that's
in the game is really
a sub class of SKNode,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
it's a good way of doing it.
But, you can see here that the
parallax has three layers as,
you know, kind of a root layer
with the tree at the beginning
and as it goes up, the
parallax slides away
from that [inaudible] 3D effect.
When we think about cameras
in 3D games is I think
of the camera 3D game, what's
a camera in the 2D game mean?
And for our [inaudible], it's
the center of the screen.
It's always kind of that
the center of the screen,
everything moves so fast,
the parallax moves away
from that and, you
know, movement.
What's driving the
movement on that camera?
It's actually-- in this
case, our characters
as the [inaudible] screen
that pushing, you know,
the pushing the world
around and with
that changes the
actual camera position.
So lesson number one is
always, in games, fake it all.
[laughs] You make it a
game, make it look good.
That's the most important thing.
So, it's a good [inaudible]
fake 3D.
Fake 3D is actually
was easy to do.
We have our little root
object which is the roots
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the actual ParallaxNode
and as our object moves
from the center of the
screen from minus one
to plus one the X and Y axes.
That object is part
of the ParallaxNode,
kind of miscue away from that
object, away from the center
to give the effect of parallax.
Possibly, the code that
we wrote actually do that.
So, ParallaxSprite, you
know, from an SKNode,
[inaudible] much a little set up
in there, then the actual code
to actually setup, we're like
good old days so we just want
to load three PNG files and
we want those three PNG files
to be part of our ParallaxSprite
and we have a voodoo number
that is really the
heights of a tree, 150.
That doesn't mean anything.
It's just the [laughs],
you know,
the effect where
I see [inaudible]
and we want the Sprite
to fade off an alpha
as that character approaches
the tree, we ought to be able
to see the character underneath
the trees and so we're going
to talk about how we
[inaudible] to did that too.
So, if we look at the SKNode
and how it's actually set up,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can see that the SKNode is,
you know, at the bottom there,
there's ParallaxSprite, we
got these three children,
these three PNG files on top
of that, you know, the RootNode
and then on top of that,
[inaudible] leaves
that come out.
And if run through how things
were actually done in the Xcode,
the two lines of code work out
the opposite X and opposite Y.
That's, you know, that kind of
show which sides are off on,
you know, from that zero to
one that we showed you before
and we work out that
for X and the Y.
Then we walk through our
children and we multiply
that with voodoo number, really
it's just a voodoo number,
they're OK to have voodoo
number, it's a game.
And we set that to the
position on the node
and that actually produces
that parallax effect
as the Sprite moves around
because the children moving away
from the center of
the screen multiplied
by that number chooses a
very nice parallax effect.
Very, very easy.
So, we also have the character--
the trees fade as the
character approaches that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So how do we do that?
So the Adventure
character, the--
there's a ton of them
in the game 'cause
it's multiply the game.
We work out which Adventure
character is closest
to this tree, look
how far away that is,
and then if it's too far
away, it's, you know,
we set it to being completely
fake, so these are going
to be completely fake,
but if it's close enough,
we do a nice little
square fall off on--
as the character approaches it,
so that's the tree
fades away nicely.
And we make it stay
around a little bit,
so that's what with
the 0.1 and 0.9.
The Collision Mapping
is kind of interesting.
You can see here
[inaudible] collision volumes.
We [inaudible] many
of them in the game.
I think there's like 20 of
them for the entire level.
We actually ended up
using the physics system.
But we then definitely start
out using the physics system.
To begin with, we did
this the wrong way.
It's OK to do things
the wrong way.
We load, it's already great
big PNG file and we load
that in the 2D array
if my guy is standing
on black, he can move around.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
My guy is standing
on red, he stops.
Simple, that's the way-- that
seem the obvious way to do it.
It turned out to be too much
code, so that will be a lot
of code and just him seem
more and more and more to try
and fix the, you know,
fix the problems.
It works terribly.
The guy will get stuck on
the wall and he won't be able
to move out and he
won't slide along
like [inaudible]
slide along, you know,
it was just not a good
choice and he-- wrong.
But it sure seems
obvious, you know,
[inaudible] write the code, I'm
not going to use Sprite Kit.
I'm going to roll this on my own
and it's going to be awesome.
No, no, I'm not that also.
[laughter] So it turns out the
right way was actually pretty
darn easy.
It was to use the physics
system built into--
in the Sprite Kit
and as it turned
out to be zero lines of code.
But let me qualify that
'cause there's no such thing
as zero lines of code.
There is a little bit of set up
and that's full lines of code.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So we have a rectangle
which is one of those red
or blue rectangles
for the actual walls.
We add that to the physics
party and we say, "Hey,
this is physics party
on the Sprite."
We say, "It's not
been moving around,
that wall is going
to stay still."
It's going to be called the wall
and we add it into the world.
And boom, that is it, we
had done, that guy collides
with the wall, he
goes along nicely.
It is all done for
you from then on out
and we didn't have
to do anything.
It was like happy day.
[Inaudible] Spencer
at the second lesson.
>> We're going to talk
about the art pipeline.
We have-- there's a
lot of stuff to talk
about in the pipe
line-- art pipeline.
But, I'm going to
go through three.
The first one is plan your art.
Make sure that you know
what your art is going
to be before it goes in, because
our resources cost money and one
of the things that Graeme and I
do is that Graeme will make art.
Graeme will do the program
or art which is, you know,
that's awesome, because, you
know, Graeme will give me a PNG
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that is the right
size, the right bit up,
the right orientation
or whatever.
And I can take that as a
communication tool and then use
that as, you know, as a template
for us to put the real art in.
So, another one is limit
the size of your resources,
limit the number
of your resources,
make sure that you're not
using system resources crazy
because a lot of artist wanted
to put a ton of polygons
or [inaudible] or, you know,
particles into a system.
And then you, you know, you
bug the system, it runs slow
and you're fighting with
the programmer over assets.
And if you can get the
coolest looking effect
with the smallest number of
resources, that's a total win.
We have kind of a contest
in the lab or, you know,
we try to get the
neatest looking thing
out of the smallest
number of system resources.
And then also build
only what you need.
So, if you're going to build
the coastline and you see part
of the ocean, don't build
the whole ocean, you know,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
just get what you need
especially in 3D games
but in 2D games this
also applies.
So you make sure that, you
know, what's going to go
on the screen, if it's only
going to show up at 256 pixels
in screen size, make
it 256 pixels.
Don't make it 4K, you know,
make your assets as big
as they're going to be.
So, this is kind of a napkin
sketch, one of the critters
and this was our first, you
know, our first presentation
of the client and they came
back and they said, "You know,
I like the eyes but let's
get some bigger eyes.
Let's get some, you know,
some huge googly eyes,"
and we put those in and they
were, "Whoa, that's a lot
of eyes, let's trim the eyes."
[laughter] So then we came back
and we had built this thing
in Maya by this point.
We have the big googly
eyes in Maya.
And we did a tap
down Render and all
of our animations were basically
on alpha, tap down Renders
in Maya, frame by frame out as
sequential PNGs to a folder.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so this was our-- our fix,
was we made it big green warts
instead of big red eyeballs.
And then-- so this was our
final little dude, you know,
this is kind of our--
after iterating back and
forth, got to the critter.
And then made these
spreadsheets out of--
what are we calling it again?
>> Atlas files.
>> Atlas files, sorry,
artist, programmer.
[laughter] And they were
super easy to build.
I mean, I-- we would build a
sequential list of PNG files,
throw them into a folder,
put them into Xcode and bang,
we had this little guy getting
hit by an arrow or whatever.
Then the programmers
were able to take that,
assign it to a spread,
assigned to a character position
and you know, and
trigger it when needed.
So another thing that we
did was this particle system
that you guys have
been hearing about.
This was kind of-- this is
that wind that I was talking
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about where we have-- it's a
really tiny amount of resources.
We used 25 particles twice and
so 50 particles total for all
of those leads all
over the world.
And you can see here, we use
two little tiny particles,
two little tiny textures
and started them off
at 100 percent scale
down to zero.
Zero percent opacity up to a
hundred and it ended up looking
like a bunch of leaves
kind of floating
down on the forest floor,
it really worked out well.
>> Oh, back to me.
Lesson number three,
agree on stuff.
You know, we're a small team
and we had a very tight
deadline for this.
So day to day agreeing on what
we're actually doing is kind
of important.
So, let's take a look at
our internal pipeline.
Communications, [inaudible]
in the same office,
so it actually worked
out pretty darn well.
I can just yell at him that, you
know, and-- we never yell, yes,
yes on doing stuff, but
communication is very important.
And it applies to things
like naming schemes.
You don't think that these
things, I just want to make game
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and pull the structure.
Even the coordinate
system that you use
in the game 'cause we use
all these tools, we use Maya,
we use Photoshop, we
use Xcode and each one
of these has a different
coordinate system
and you'd really have to agree
on what the number one means.
And bigger things,
like orientation.
Orientation is a
[inaudible] games.
Agree on which direction is up
and write it on the white board
and do not end up with a
hacked file for the one is off
by 90 degrees, it has
plus 90 [inaudible]
because that will come and
haunt and you will shift
and all the guy will become
like this, and you wonder why
and it's a plus 90,
you have an [inaudible]
that you forgot to change.
Sorry, that might have happened.
[Laughter]
>> Like I said before,
programmer art is great
and there's probably like
three artists in this audience.
But go home and talk to
your artist and tell them
to let you do art, because
the art that you provide
to us is an invaluable
tool of communication.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It allows us to iterate back and
forth with you when you give us
that artwork, you know
that it works in code.
For example, I mean
the next one here,
this is a Graeme's art this
worked perfectly for Graeme
because he has a
vector, you know, that--
which way is this thing going
and he's also got
these three different--
this represent those
three parallax layers.
So, he was able to go in, send
box, play around with like,
you know, all of his numbers
and get all of the layers
to work correctly with the
camera and then he gave it
to me, and then we built
this stuff in Photoshop
and made it all pretty
and stuff and so--
then it actually
look like a tree.
And so, so yeah, programmer art
is awesome, I love programmer.
>> The folder structure of the
game is also really important.
You have to remember, you know,
Xcode does a lot of the work
for you and puts things nicely
into groups and so forth,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
resources, but that is not
necessarily representing
on the hard drive, they won't
use all these tools, Photoshop,
Maya, you know, these
sound tools.
They're supposed to put
things into separate folders
that you will agree on,
separate your game data
from your level data from
your game data as localization
and so forth, but, you know,
[inaudible] different folders.
It sounds simple but that
folder is where you live,
so it's really important.
>> And I-- finally, this
is another great way
to communicate back and forth.
Our rule that we've kind of
like been going back and forth
on for the past like 25 years
of game development is a
meaningful name, just something
that means something that,
you know, that makes sense,
so that if you get an artist
or a programmer who comes
into the project halfway that
they are not trying to figure
out what, you know,
file 73 is, you know.
And then we use underscores,
no spaces,
and then we pad our revision
by four because you never know
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
when you're going to have 9,999
versions of that file especially
when you're-- and seriously,
especially when you're
doing animation.
You're going to have a ton
of files in animations.
And then the file type at
the end is really important.
We go into finder for everybody
on the project and we turn on--
we expose the file
type at the end.
This seems simple but it's--
it really, really helps
when you're trying
to quickly identify
whether it's a PSD,
a PNG, a TXT, or whatever.
So, you know, agree on a
file naming convention,
you can use that if you want
to, but use one that works
for you but, you know, this is
also a great communication tool.
>> Lesson number four, have fun.
You're in the freaking
game industry.
[laughs] If you're not having
fun making the game then you're
going to make a rotten game
unless one of the big things
that we differentiate
ourselves on is that Spencer
and I are in the game industry.
I don't work in the game
industry, I never worked
in my life and that's what
we do every single day.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, let's go over
our lessons again.
Just because it's a 2D
Sprite engine doesn't mean
that you make 2D games, we
touched the tip of the iceberg
with what we can
do with Sprite Kit.
We could have made it complex
3D game with [inaudible]
and it would have been awesome.
>> Physics is much more useful
than for just drawing
birds epics
and programmer art is beautiful.
I-- really, use your
placeholders with pride
and give them to your artist
so that they can understand
what to do correctly.
And as far as the less is
more, we've been talking
about that a lot, see how
you can get them the fastest
running, least, you know,
quickest booting game
that you possibly can and
make it look super amazing
because if you can get
a really cool effect
or really great looking game out
of just hardly any resource used
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
at all, you know, well first off
you're amazing and second thing,
all you have to worry about
is awesome game design.
So, thank you very much.
>> Thank you Graeme,
and Spencer.
So, lastly I want to
talk about how to build,
not only use Sprite Kit as
part of your game runtime,
but build awesome game tools
to improve it in a recent time.
What if we decide to take
Adventure to the next level?
What if we want multiple level
support, currently is one level.
What if we want to add
save and load game support
so that the user doesn't have
to spend [inaudible]
30 minutes just playing
and finishing the game.
And what if we want to build
this more sophisticated
and reusable actions for
every single different effects
for your characters?
So, Sprite Kit, every single
SKNodes support NSCoding
and NSCopying, so what
that means every single node
can be serialize and deserialize
to the disk or to the iCloud
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
over the network,
however you want.
So, we can implement essentially
a save/load game logic using one
line of code.
So, let's look at the
serialization API.
It's quick and easy.
All you have to do is use
NSKeyedArchiver parsing any
SKNode, you get NSData blob and
from them on, you can do write
to disk, send it to the cloud
or that the serialization
is just the reverse.
Getting NSData blob, past
to the NSKeyedUnarchiver
and therefore you have the
corresponding SKNode instance.
So to build Adventure, in this
case, Adventure level editor,
we create a level editor in
Mac OS X using Sprite Kit.
If you're able to add an
overview, overlay view on top,
you can place your
level tiles on top
and also use the overlay view
to receive any of the user input
as well as the mouse
manipulations.
So if user drag and drop
some tiles on there,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can make it the
direct manipulation
to the underlying SKNode.
And once everything is properly
placed, you can serialize now
to the scene and
essentially just load
that at runtime therefore
you have your game level
and you don't have to use change
some integer, recompile, and,
oh, I'm off by 50 pixels, you
don't have to any of that.
Custom Actions also
serialize well too.
Imagine we're building
a golf game.
So here, I want to simulate, OK,
when the golf club hit the ball,
what's going to happen?
What if I-- the first thing I
want to do is apply some sort
of an impulse to
make the ball fly.
And second, I want to play some
task effects that play that,
wait for all the
particles to finish,
and it will remove
that from the scene.
And in the meantime when in
parallel when the ball hit--
when the club hit the ball,
you will hear sound effects
and maybe way with
the ball is airborne
and then we'll play a task
trail for beginners to learn
from their mistakes, "Hey,
this how far I'm hitting
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this is the projectile
for that."
And if I want to build
all of these, this logic,
I want to use it in game
for every single time
when the club hit
the ball, I'll have--
we can build this in code by
having a sequence fall away bat
of groups, it's about
20 lines of codes.
But if you want to tune
that, the easiest way is
to use serialization API
for SKActions as well.
So, SKActions itself is
serializable as well.
When-- As soon as it's being
assigned to any SKNote,
it will be kicking off
from the beginning.
It's-- As soon as you assign
the action to the SK node,
it copies on write and
when actions are completed,
it will be finished.
And the last section I
want to quickly touch base
about the best practices
of using Sprite Kit.
Number one, we will recommend
you to use UIKit and AppKit
if you need a complex
layout for your text.
So, we do provide a SKLabelNode
for a one line that UI allow you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to animate that before any
complex constraints as well
as with the height adjustment
where Holly [phonetic] recommend
to use AppKit or UIKit.
So, just like any other
GL view, as soon as OS X,
if you enable layer-backed,
you automatically get
all these benefits.
And one thing I like to point
out is in OS X, I'm sorry,
Xcode 5, we provide a major
update to Interface Builder.
So if you want to design
your UI with the pipe--
breaking at the part
into different flows.
For example here,
how main screen goes
to character selection
screen followed by going
to weapon selection,
you can totally design
that using Storyboard
inside Xcode.
And now, how do we improve
your iteration time?
So, we want to integrate
Sprite Kit inside your code--
with your game code
so you can use
that to build your level
editor, if you do action editor,
you can use the particle
editor to edit your particles
at the Sprite Kit building
Texture Atlas generator
is great.
You just drag a folder in
and you have, therefore,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you have your Texture Atlas.
In terms of performance tips,
we provide a building stat
to show you how many
draw calls as well
as how many SKNotes are
being rendered on screen
as you can see from
one of my examples.
We'd like to keep
the node count low
for node that's no
longer visible.
You can remove that,
but Sprite Kit does cull
out invisible node, but
there's the additional
if statement that we go through.
But if you know ahead of
time, the object is going
to be no longer visible,
feel free to remove that.
CIFilters are expensive if you
apply them to a full screen.
So, we do provide a
property called [inaudible]
so that this we-- the
result will be cached
into a frame buffer
so that will be reused
for the following frames.
Also, we like to talk
about organizing your games
into different scenes.
Once if you treat scenes as
the fundamental building block
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for your games, you can
plan ahead, OK, how do I--
do transitions from
scene A to scene B,
from UIView into the game
view, from Game to Pause menu,
you can do all these transitions
and make your flow
much, much easier.
So and-- that's the
end of the session.
For any questions or feedback,
please contact our
evangelist, Allan Schaffer.
I'd like to point
out for those of you
who have missed the
introduction to Sprite Kit,
there's online videos that's
going to be available tomorrow,
and have a great WWDC 2013.
[Applause]