WWDC2013 Session 502

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Thank you everyone.
My name is Jacques
Gasselin de Richebourg
and I manage the Game
[inaudible] team here at Apple.
I am extremely excited to tell
you about this feature today
and this is the Introduction
to Sprite Kit.
But before we get in to the
nitty-gritty details of it,
I'll like to look at where we
are and I think we all know
that games are incredibly
successful in our platform.
Just this morning I had
a look on the App Store.
I looked at the US
Top 100 paid icon apps
and 60 out of 100 are games.
And that's a pretty
good indicator
that we're on to something.
Now, a lot of these
games are truly iconic.
We have games like Angry Birds,
Cut the Rope, Doodle Jump,
Where is My Water, Tiny Wings,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm sure you're all
aware of these games.
And many of them are 2D.
We look to this and we realize
that developers have
a lot in common needs.
2D game developers need a lot of
beautiful graphics, really fast.
They need particle systems,
they need visual effects,
and they need physics
and animation
to really give you a great
game play experience.
So, we thought about
this and really,
to make a really
efficient 2D game engine,
you need to build it from the
ground up where the focus is
on speed and efficiency
and that's what we did.
So Sprite Kit, there's the heavy
lifting for you so you can focus
on making games instead
of game engines.
All right, let's
get to the features.
Sprite Kit, enhancing
2D games development.
It has features that you would
expect from the Sprite engine
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
like Sprites animating
of course,
tinted, particle effects.
It has geometric
primitives that you might use
for debugging or even shipping.
You can do rectangles,
circles, pads.
You can do arbitrary pads.
So you can do subpads
inside them,
you can even have them
self-intersecting,
and this is all rendered on
the GPU extremely efficiently.
You also have animations
and physics.
And what we did here
is we went above
and beyond what you
really need for every game.
We really want to make sure
that you could do whatever
your imagination had in mind.
So, animations and physics
are tied together so closely
that you can animate
an object that is
under the influence of physics.
That should be quite special
if you've ever tried to do
in 2D game with physics.
We've also gone above
and beyond when it comes
to system integration of
current media frameworks.
Core audio, core image and even
foundation are all super easy
to integrate into your game.
So you can have video sprites,
you can apply core image effects
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to your whole scene
or individual sprites
and you can also play sounds
as part of your animations.
We want to make it
even easier for you.
So, Sprite Kit is tightly
integrated into Xcode.
We have a particle
editor that you can edit
and create particles
with as you develop
and we also have a very special
tool that you will notice
or probably not look
at too often.
And this is an Automatic
Texture Atlas generator.
What it does is it analyzes
the files that you have in one
of your source image folders.
And if you say, I would
like this to be in Atlas,
we will go through it, pack
it as efficiently as we can,
but here's the real magic.
If you started out using single
images and referencing them
in code that way, when
you move to an Atlas,
you won't have to
change the code.
We figure it out for you.
Okay, so let's get into it.
So today, we have the
agenda of introducing
of Sprite Kit of course to you.
We'll go through
the known types.
We will show you the
different effects and actions
that you can apply and
we'll also show you physics.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In the second session,
we're going to focus
on designing games
using Sprite Kit.
We have a legendary game
they offer here and we talk
to you a little bit about
experimenting with Sprite Kit
and the take-home demo that you
hopefully have all downloaded
on the iOS 7 WWDC sample code
site called Adventure was
actually designed and
developed very quickly
about this gentleman.
And I'm very excited
to have him here.
Wilson talked about managing the
art pipeline, creating, editing,
and using the art that
your artist has created.
And then we'll have a bit
more of an in-depth look
at the Xcode Support Sprite Kit.
Okay? Now I'm going to show
you a demo of Adventure,
in case you haven't seen it.
So here we have Adventure,
it's a multiplayer
controlling 2D game, topdown.
I'm going to select
the archer in this case
and we're going to
start playing.
So this works with Game
Controllers, works on iOS
and OS X and you can use the
keyboard and mouse to go around.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, we have an archer here who's
animating using frame-based
animation on Sprites.
We have particle systems that
are affecting the leaves here.
You see the leaves
are falling down.
We're doing some really
funky actions to fade
up the trees as you
go under them.
And you'll notice there's
even a parallax effect applied
to this giving it
more of a depth feel.
As you walk around and fire
arrows at the problems,
these are all done
using particle systems.
Not always are the flames
but particle systems too.
Okay. Now I want you all to
have a look at that yourselves,
download it, play with it,
modify it, it's yours to have.
So, thank you for your time.
I'm going to hand you over
now to our principal engineer
on Sprite Kit, Tim Oriol,
and he's going to take you
through all the details.
Thank you so much for your
time and I hope you enjoy it.
>> Thank you, Jacques.
So what I'd like to do now
is give you a tour of the API
and show you what Sprite Kit
has to offer for your games.
So I'm going to start
with the basics.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's three basic parts to any
Sprite Kit game and not consists
of your scenes, your animations
and actions, and physics.
So scenes is the visual
layout of your game,
all of your game
objects, your heroes,
your bad guys, stuff like that.
And actions in Sprite Kit allow
you to perform basic animations
on these game objects
like Rotate,
Scale, Movement, Tinting.
And then the third component
is our built-in physics engine
which you can use
with animations,
or instead of animations
to bring life
and excitement to your game.
So let's take a closer look
at what we mean by scenes.
So in Sprite Kit, your
scene is composed of a tree
of multiple elements
which we call nodes.
So these are all nodes.
You know what, some of them
represent visual content
such as shapes or images like
our background image or trees
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or the character
sprite for our hero.
And other nodes are merely used
as organizational
elements or for grouping.
For example, we have one to
represent our background layer
so this gives us a single
point where we could move
and translate that one node
and have it affect
all of our children.
So, not every node in your scene
necessarily represents explicit
visual content.
And once you have
your scene built,
you can then apply actions
and physics to any node
within your scene and that's
how you put together the parts
of Sprite Kit.
But of course we also have
to get this into your app.
And to do that, you're
going to want
to add an SKView to your app.
SKView is on both platforms,
so we subclass NSView on OS X
and the UIView on iOS.
So you drop that in and then
you simply tell the view
to present your scene.
So once you've done that,
the basic Sprite Kit
game loop kicks in.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so this is the sequence
of events that's going
to happen every frame once
your scene is in the view.
And it will start off by calling
the update method on your scene.
And, so this is where you're
going to be doing the majority
of your game logic, this
is maybe where I'd choose
to spawn additional enemies.
Maybe I'm going to update the
high score or I'm going to check
and see if my character has
completed all the necessary
requirements to advance
to the next level.
This is your basic
area to do game logic.
After you've done all that,
Sprite Kit will then evaluate
any actions attached to nodes
in your scene for
the current frame.
After all these actions
have been evaluated,
Sprite Kit will let you know
that it's done doing that
and give you a chance to react
to the result of those actions.
So, at this point, this is after
the actions have been applied
so the position of
all the elements
in your game will be
exactly where they are
when they're rendered
for this frame.
So if I have a game where maybe
I've got some fireballs lying
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
across the screen and I'm doing
that with some movement actions
that I set up, this will be a
great place to check and see
if the-- one of those fireballs
is completely off screen
and we can go ahead
and clean that up
and remove it from our scene.
After that, Sprite Kit will
then simulate any physics
that you may have set up on
some of the nodes in your scene.
And it'll give you an
additional callback after that
to let you know that the
physics have been simulated.
This is where you can
clean up the results
of the physics simulation or
react to different effects
that may have been
done by physics.
This is also your final
callback and your last chance
to change state in the node
before Sprite Kit goes off
and renders that to the view.
You should note that after
the actions have been applied,
any new action that
you've added to your scene
in the following two
callbacks will not be evaluated
into the next frame
because they've already been
taken place.
So, I'm going to give you
a complete tour of the API
and we're going to go
through a lot of the headers.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But first, I want to
give you a demo of part
of the Xcode template that
we have available for you
in the developer seed.
And I really just wanted to
show you how much you can do
with very little code and
really how approachable
and readable this API is.
And even without seeing the
API before, you should be able
to follow along with
exactly what's going on even
if you've never been
in the game before.
So here, I've got
my zib [phonetic],
I just got a big SKView
that I've put in here.
And then in application
didFinishLaunching,
I'm creating a new instance
of my scene which is the size
of the view and just telling
my view to present that scene.
So, let's take a look at
that subclass myScene.
So, when the scene is
created where it looks
like we're setting a
background color to what looks
like a dark gray
on our scene here.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And then we've implemented the
mouseDown handler and looks
like we're getting the
location of the touch--
excuse me, the mouseEvent
in our scene space.
And then we're going to create
a Sprite using this selector
SpriteNode with image
named "Spaceship",
I wonder what that is.
And then I have-- I'm just
going to add that to myScene
and then I'll set the
position of the Sprite equal
to the location of
that mouseEvent.
Then I'm creating
something called an Action,
looks like it's doing a rotation
by Pi for a duration of one.
And I'm telling my Sprite to
repeat that action forever.
So, this is-- we got about
28 lines of code here.
So if I go ahead and run this,
hopefully we'll get what
we'd expect to happen.
[ Pause ]
That's what I expect to happen.
So we have our gray screen
here, that's what we set
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for our background color.
And if I try clicking
in the scene,
we've already got a Sprite
in our game and animating
with just 28 lines of code.
And then [inaudible].
[ Applause ]
And of course we can go crazy
and do that multiple times
because we've implemented
as a mouseHandler.
So, we just want to make it
really easy to get started
and get you right into
making the actual game.
[ Pause ]
OK, so let's take a look at
the different types of nodes
that we have available
in the SpriteKit.
So, these are all the
nodes that we have.
They all inherit from
the base class of SKNode
and then we have
specialized subclasses
to do various things
for you in your game.
We have nodes for texts, we have
nodes of course for sprites,
we have nodes for doing shapes
and particle systems,
a lot of good stuff.
And we're going to take a
look at each of these now.
We'll start with the
base class, SKNode.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
SKNode has no inherent size
because it has no
inherent content.
So this is one of the nodes
that you would use as one
of those organizational
elements within your scene.
It has all of the basic
transform properties
that you would want.
You can do position,
rotation, scale on both axis,
you can apply alpha to the node
which will also be multiplied
down through to its children, so
you can fade out an entire tree.
You can also disable the
rendering of an entire node tree
by setting the hidden
flag on any of your nodes.
The next stop is SpriteNode.
This is the MVP of
the framework.
This is the one they're going
to be using all the
time in your game.
This is going to be 80 percent
of the nodes in your scene.
SpriteNode absolutely
does have an explicit size
because it actually
provides content.
It can do one of two things.
It can be a solid color
or it can also present a
texture like our Spaceship.
So, let's talk about
textures for a minute.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Textures are how SpriteKit
represents bitmap--
reusable bitmap data
inside the framework.
And they're automatically
managed by the framework,
so you don't have to
worry too much about them.
And we provided a number of
different ways that you can use
to get your content into
a SpriteKit texture.
The most common one of course
is the image name to one
that we've seen a few times.
You got image in your bundle,
this works exactly like UIImage
or NSImage and we'll
go find that
and load it up into the texture.
You can also supply data using
CGImageRef, UIImage, NSImage
or even your own buffer
of RGBA bitmap data.
You can also even create
an additional texture
from a subregion
of an existing one.
So if I only wanted to show
that part of the Spaceship
as another node, I can just
create a new texture using
that subregion and it's actually
really cheap, SpriteKit's going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to take care all the
work behind the scenes.
We're not actually creating
an extra texture for that.
So, here's some basic
that you might use
to put a Sprite into your game.
You can see, we create a
SpriteNode and then I'm going
to create a texture using
my hero image then I'll set
that texture on my sprite and
then I want to set the size
of my sprite to match the size
of that image file that I used.
This seems like something
that people are going
to be doing all the time.
So, we didn't want
you to have to go
through all those four steps.
One of the basic principles
in SpriteKit is we wanted
to make things super
simple to do.
And we have a convenience method
that you can do this
all in one line.
We'll go fetch the
image from your bundle,
set that on the Sprite
and automatically set
up its size to match the image.
So, I've been telling the whole
truth before, it doesn't have
to be just a color or a texture.
SpriteNodes can also do a
blend of the two together.
So, if you have both a
color and a texture set
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on your SpriteNode, you
can control the mixing
of the this two through
a third property
called colorBlendFactor.
So, this will allow you to tint
the texture using that color
that you've set on the
node, where 0 is no tinting
and we get the full texture.
And 1.0 is fully tinted and
the textures then only used
for alpha and luminance
information.
And it's really cool that the
alpha doesn't get overwritten
as well which means that I
can use these game elements
at different parts in my game.
For example, I can tint my
hero red when it gets hit
by an enemy projectile.
I can also have background
elements like this crystal here.
Maybe I wanted to look cool
in icy-blue in my ice world
and I'm going to use it later on
in my fire world and I'm going
to have it be glowy red.
It just allows you a lot more
freedom, so you're not tied
to a generating explicit
images for every type of effect
that you want to
do in your game.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, we want to take
a look at the effect
of all the different properties
that we have on SpriteNode,
many of them inherited from
SKNode that we just talked about
and how they would affect
how the Sprite will look.
So, the first two lines
here just gets our Sprite
on a screen, so that's
exactly what we would expect.
And then we can play
around with the alpha,
maybe fade it out a little bit.
We can modify the scale and
the texture will be stretched.
And then we can also
do a rotation
or we can set the color as well.
You notice when you do set
the color, it's not going
to have an immediate effect
until you also set
the colorBlendFactor
because it will default to 0
when you've created a
Sprite using an image.
And that's what we'd get if
we set the colorblend factor
to 1 using green as our color.
Next up, emitters.
How can you have
a 2D game engine
without having particle systems?
So, SpriteKit of course shift
to the fully featured
2D particle system.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We support all of the basic
functionality that you know
and love from particle
systems like startValue
for all the different properties
we have to configure as well
as variants about
those values and speed
over time once the
particles are emitted.
But we also support advance
features like keyframe sequences
for certain values on particles.
For example, I can set
up a keyframe sequence
that ties the lifetime of
the particle to color values.
And we can get a really cool
effect like the fire here
where the particles
actually pass
through numerous different color
values over their lifetime.
We have-- there's a number of
different things, of course,
you can set on your
particle systems.
Of course, you can set the
texture that's going to be used
to render those particles,
scale, and rotation.
You can set the emission
angle that they're going
to be launched out at.
You can set variants
around that emission angle,
so you can create a cone,
the speed at which they're
launched out, blend modes.
There're just really so
many things you can surround
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and just tweak these
things for hours.
Which is of course why we
didn't want you to do an encode
and we have the editor
built right in to Xcode.
This allows you to use data
driven particle effects,
it allows you to empower
your artist and allow them
to iterate independently
from development in the code,
and it'll greatly
reduce iteration time
for tweaking these
tiny visual effects
and lets you get exactly
the affects you want.
The editor in Xcode is built
off of a Sprite Kit view itself,
so you're getting real
life content there.
You're going to know
exactly what it's going
to look like in your game.
So, next I want to talk a
little bit about video in games.
So, up until now what I've
seen in terms of video
in games is people have put
video above their game view.
Some people have even made
transparent game using put video
behind it.
Or if you wanted
to do anything else
that was pretty much
roll your own in OpenGL.
But in Sprite Kit, video is
truly a first class sprite.
So, what does this mean?
This means of course we have
an easy one line convenience
function for you to get video
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from a file directly
into your game.
You can create a VideoNode using
a video file in your bundle,
and this supports playback
and pausing of that video.
If you want more
advanced controls,
we also support using AV
foundations, AVPlayer,
as a means to create
a video node
which will allow you
advanced playback controls
like playback speed,
asynchronous loading,
even queuing up multiple videos.
So you can really
do a lot with this.
And it opens up like
a whole new world
of possibilities
for video in games.
So, I can now place it
anywhere in my node tree.
I can have spaceships lying
behind and in front of my video.
I can run actions no my
videos since this is a node.
I can rotate.
I can scale it, fade it.
I can even use video
as my level background.
If I wanted to be really
creative, I could enable physics
on my video and have them
floating around my scene.
Anything you can
do with the Sprite,
you can now do with video.
Next, ShapeNodes.
ShapeNodes are a great way to
display dynamic geometric shapes
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
within your game, we've
made it really easy
and we're using CGPath
as the container for you
to supply shapes to Sprite Kit
so you can use all the
great core graphics,
convenience functions to create
ellipsis, rectangles, circles.
You can have complex shapes
like this animating
doughnut above here.
We support stroking and
feeling the path as well.
We even allow you to do a glow
effect like the yellow line
in the bottom here,
sort of fringes out,
create a cool laser
light effect.
We also have LabelNodes.
So, for most of the UI in your
game, you're going to want
to use UIKit or AppKit
for buttons
and editable texts
and stuff like that.
But sometimes you really
want text in your app.
I mean directly in your game.
I want to apply those same
Sprite Kit actions to my text.
I want them to be between
nodes within my scene and to do
that Sprite Kit allows
you to use LabelNodes
to have single line text
in your game as a sprite.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And we support all the system
fonts in either platform
and any custom fonts
that you may have added
to your apps bundle.
We also support, since it's
a node, all of the SKActions
which means I can animate,
rotate my text using the exact
same actions that I've built
to animate my game characters.
EffectNode, this
one is really cool.
So, what EffectNodes do
is they will render all
of their children into
an offscreen image
when we're generating
the frame and then
that image will then
be presented
into the final frame buffer.
So, this allows you to do
some really cool effects
like group opacity
and group blend modes
by having the children
of the EffectNode render
into that offscreen image
using their own opacity
and blend modes and then
the resulting image is then
presented into the frame buffer
using the EffectNodes' opacity
and blend mode.
And we've also-- since we
already have this offscreen
image, we thought it'd be
really cool to allow you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to apply our vast library
of core image filters
on both platforms.
We got a lot of great new
ones in iOS for iOS 7 now too
to that image before
we render it.
So you can take the output
of an EffectNode and send it
through a blur filter
or a pinch filter
and you can do this anywhere in
your game scene or I can do it
on the entire game
scene like we have here.
You can also cache the
output of that filter
if you're not going
to be animating it.
So if I want to apply a
really nice Gaussian blur
to my game world and then put a
Pause menu above that and I know
that my game is not going to
be animated during that time,
I can tell my EffectNode
that it should rasterize
and then we only
incurred the cost of doing
that full screen Gaussian blur
once and then it will be reused
from the cache every time
the frame is rendered
so you can still animate your
menus and your icons on top
of that and not have to worry
about having the filter
applied every frame.
We also support a form
of superfast masking
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in Sprite Kit using
the CropNode.
So, what a CropNode will do
is it will mask out a portion
of its children's content.
And the way you supply that
mask is not via an image
but via a node.
So any node that's not
currently in your scene.
So that means I can use an
image by using a SpriteNode,
I can use a shape if
I use a ShapeNode.
I can even have children
in that node.
So, it doesn't have
to be just one node.
I can have an entire tree
that makes up this mask.
And since those masks are nodes,
of course we can
animate them as well.
So we can have dynamic
masking on the fly in our app
and we can animate both the
objects that are being masked--
masked as well as
the mask itself.
So we can have a
spaceship flying
around with a particle system
massive exhaust trail being used
in real time to mask, let's
say a video node in our scene.
Now, let's talk a
little bit more
about those actions
and animations.
So, when we went to design the
action system for Sprite Kit,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we want it to be super simple,
we want it to be really
readable, we wanted it
to not be confusing at all.
So, we only have one
class where you need to go
to find these actions and
every action, that's SKAction,
and every action can be created
using a single line convenience
method just like all of the
other nodes that we offer.
We wanted them to be
extremely readable.
We wanted the actions to be
reusable so you didn't have
to build them again for
every Sprite you wanted
to run them on.
We want them to be chainable
so you can sequence
them really easily.
We wanted actions to
directly affect your nodes.
We wanted you to know that
if you inspect a value
on your node before
it gets rendered,
that's the exact value that's
going to be rendered at.
And we really wanted
to be almost
like a scripting
language for Sprite Kit.
So of course we've had-- we
have all the basic actions,
movements, scaling,
translate, fade-in, fade-out,
and how do I run
those on my nodes?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I just tell my SpriteNode
or any node
in my scene to run that action.
I'll say runAction, pass it in.
Like I said, they're copied
on ads so you can go ahead
and reuse this action later
on or if you're not going
to reuse it, you can even
create the action inline
like the second sample
here without the need
for making that explicit object.
They're automatically removed
on completion so you don't have
to worry about managing
the actions
that are currently
playing on a node.
We also support repeating
an action.
So, if you've already built a
rotate action and you're going
to be applying it to different
nodes but maybe some are going
to rotate longer than others,
you can repeat an action
by using as input
to the repeat action
in already existing action and
this will work on any action.
And you can specify a
repeat count for that.
Or if you wanted
to keep animating
until that Sprite is
removed from the scene,
you can do that as well
using repeat forever.
So, I mentioned the actions,
they'll run immediately
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
when you put them on the node
and they directly
affect the node.
So the way that I would
sequence my actions is
of course by using a sequence.
We have a sequence
constructor that takes an array
of existing actions and we'll
play them back in order,
run the first one to completion,
then the second, then the third.
I don't know if all of you know
about the NSArray literal syntax
in Objective-C but it's awesome
and I highly recommend using it
in Sprite Kit, it's fantastic
for building up your sequences
with very little code.
We also have groups.
So, groups will allow you to
use the same basic paradigm
by passing in an array
of existing actions,
and this time we'll
run them in parallel.
So, on a group, the duration
of a group is the
longest of its components.
So, if the longest action in my
group is two, the group will run
until the duration of
its longest component,
whereas the sequence
duration is the sum
of all of its components.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, groups and sequences
are themselves actions.
So this means that we can
use groups as sequences
as building blocks for
other groups and sequences.
So, we can have a group
that is part of a sequence.
If I wanted a spaceship to fly
in from the side of the scene
and then I wanted to rotate
and scale up at the same time,
and then I'm going
to fade it out,
I can do that by first creating
a group that performs the rotate
in scale together and then I'll
use that as a second element
in my sequence like here and we
can get the exact desired effect
by running that on my node.
So, if actions run immediately,
what do I do about timing?
We don't want you to have
to set up timers or worry
about counting ticks yourselves
so we've created another action
which pretty much does nothing.
It's a waitForDuration action.
I don't recommend just
running this on a node,
it's going to do
absolutely nothing
but where it's really useful
is using it as a component
of the sequences that
we just mentioned.
So if I want to kick off in
animation one second from now,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'll create a sequence,
do a wait for one second
first followed by the action
that I want to perform and
tell my Sprite to run that.
Those are you basic actions
in terms of translation
and transformation as well
as timing and grouping.
We also have a number
of specialty actions
that do specific tasks
within your game.
One that we definitely
need to have
of course is
animateWithTextures.
So this will allow you to
specify an array of textures
that you want to use on your
node and the timePerFrame
that you want those
textures to be displayed.
And this is how we've done
all the character animations
in the Adventure sample.
We also found that people like
to follow paths a lot in games.
So we built in a
followPath action as well.
And you can specify the path
using a CGPath and a duration
for the sprite to
follow that path.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And by default we'll
do what most--
what we expect most people to
want to happen is for the Sprite
to automatically
orient to the past.
So you don't have to worry
about which way it's facing
at every point along the path.
It will also treat
that path as an offset
from its current position so
it doesn't immediately jump
when you start following
the path
and we have an expanded form
of that action if you want
to configure any of
those two options.
If I have a platform
that's moving around
and I always want it to
stay vertical you can do
that as well, just use
the extended forms.
Removing a sprite from parent.
So a lot of times in
my game, I go through,
I find all the bad guys that
were hit and then I want
to run some sort
of death animation
on them, fade them out.
But then I still have
this SpriteNode hanging
out in my game and a lot of
times we find people have
to build up these arrays of
Sprites that are to be removed
in the future and
then periodically go
and clean them out.
It sounds like a
pain in the butt.
So, what we did is we made
removeFromParent in action.
And you can use this as
part of your sequences.
So, if I already
built up a sequence
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that has my fadeout animation
for any of these characters
and they need to be removed,
I can just insert or remove
from parent at the end of
the sequence, I never have
to worry about it again.
We also found that people want
to play sound in their game.
They wanted to really easy
to play sound in their game
and for short sound
effects I want
to time those with my actions.
If I have a [inaudible]
that's casting a spell
and I have an action
for that and I want
to fire a sound effect
directly timed with that action,
we don't want you setting up a
timer and hope that it lines up.
We've actually built
in a way for you
to play short sound
effects right
in an SKAction using the same
one line convenience method
that we do for everything else
directly from a sound file
in your bundle right
into your game.
And so, this allows you a really
simple use of sounds of course
if you want to do longer
playback or you want
to have complex control over the
volume or asynchronous loading
of these assets then
we recommend checking
out our AVFoundation framework
for more fine grain
control of the sounds.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But this is a fantastic
way if you just want
to kick off a sound effect
every time you play an action
in your game.
We also have runBlock.
People want callbacks
in their games.
Sometimes you have logic in
your game that isn't really tied
to an action on one
of your sprites.
Well, now it can be.
So, now you can insert
a runBlock into any
of your sequences that
you use in your game
and will automatically execute
that exactly at the point
in the sequence when
it gets there.
In which we really tried
to provide a vast variety
of different actions that you
can use but we're not going
to think of absolutely
everything
that people want to do.
So we've created a way for you
to make your own custom actions.
You can do a custom action,
specify a duration for that
as well as a block that
will be executed every frame
when this animation
is evaluated.
And we're going to give
you a reference to the node
that it's currently being
evaluated on as well
as the elapse time that
the action has already run.
So you can use this
to do any sort
of things you want
to the Sprite.
You can even animate things
that aren't even in your game.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If I wanted to automatically
swirl around the emission point
for one of my particle systems
I could do it like this.
I can get some really
cool effects.
And those are just a
few of the actions.
We've got a ton more
for you to look at.
We don't have to time
to go through them all
but I'm sure we'll have a lot
of fun playing with these.
As you mentioned before,
actions are only half the story.
We also have a built-in
physics engine right inside the
framework that you can
use as an alternative
or complementary means
to animate your nodes.
So, usually when you do physics
in the game, you have all
of your game and display
objects in your game engine
and you manipulate
and animate those
and then you have your
physics engine over here
and I'm simulating those
bodies and then I'll have
to do some sort of
synchronization between the two
to get the effects of
the physics in your game.
We didn't want you to have
to do that in Sprite Kit
so we built it right in.
So, all you have to do is create
a physicsBody that represents
that node and simply
set it on the node.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's one property you set
on the node immediately physics
starts acting on that node.
So, it's built right
into the framework.
It's not all on or all off.
You can set it on only
one node in your game,
you don't have to
be a physics game.
It's-- If you really want to
use your own physics framework,
you can do that too, tie it into
Sprite Kit however you want.
If you're not using our physics
engine you pay absolutely no
cost for it.
We have a variety of
shapes that you can use
to represent physics
objects in your game.
Of course we have
circles, rectangles,
we also have hallow rectangles,
even custom polygons or paths
that you can use in your game
and all using our signature
one line convenience method
to create those objects.
So once you've created a physics
object, like I said before,
you just set the physicsBody
properly on your sprite.
So if I wanted to create
a circle with a radius 50,
I'll do that in one line
and I'll set that property
on my SpriteNode and then
physics will immediately start
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
running on there.
So, in the second sample
down here I'm creating these
golf ball nodes that I'm going
to add into my scene and
then I'm making a physicsBody
that matches the
size of that texture.
It's a circle and then I add it
to the scene and we get this.
So, they're currently falling
off the bottom of the scene,
maybe that's not what
we expected to happen
but some games might want that
behavior, so we didn't want
to restrict you to
just the scene.
It's really, really simple to
set it up a bounding volume
if you do want to have that
attached to your scene.
We can use that hallow
rectangle using the edge loop
with rect constructor and I can
just ask my scene for its size,
for its frame and
use that as the input
to create a physicsBody
representing the boundaries
of my scene.
And since the scene
itself is a node,
I can just set the physicsBody
on the scene because that seems
that like an appropriate area
to represent the boundary
and now this time when I
add the nodes to my scene,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you'll see they're
being constrained
by the bounding volume.
[ Applause ]
And so, we also allow
more fine-tuned control
of how these bodies interact
on every scene in Sprite Kit.
You'll find a physicsWorld
property
and here you'll have
access to a number
of functionalities including
doing hit test within rectangles
to see what bodies are in there.
You can do ray casts from
any points if you want to use
that to drive your AI
or pathfinding system.
You can also add
joints between nodes.
You can set up springs
or sliding
or glue different
bodies together.
You can do all of that as well.
You can also change gravity.
Things always don't--
always have to fall down,
that's how it is by
default but I can just
as easily flip the
gravity and make all
of my sprites fallout as well.
And that's physicsWorld.
And you can also sign up
to receive notifications
when any two bodies are
colliding 'cause we've already
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
had to figure this out to
calculate the collisions.
We're offering this as a way
for you to be easily notified
and perform collision
test within your games
if you set up physics bodies.
So, I can implement the
contactDelegate protocol and set
that property on my physicsWorld
and I'll be called back
on these two methods anytime
two bodies begin contacting
or cease to be in contact.
And what do I get back there?
So, I get back each body that
participate in that contact
as well as the point of first
contact where they connected
and the magnitude of
the collision impulse
that was applied at that point,
so I can know how
hard they were hit.
So if I wanted to know anytime
that my hero character collided
with another physicsBody
in my scene,
I could implement
the delegate protocol
and I'd simply check
whether the bodies
in this contact was
associated with my heroSprite
and then I can go up and do
something cool with that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
By default, you'll be
notified of every collision
between any two bodies
in your game and a lot
of times this is way
too much information
and we don't really
need to use all of that.
So we allow our advance users to
filter out different collisions
within your game and only get
back exactly the information
you're interested in.
So, in this game here, I've got
a couple of cooperative players
and I've got some bad guys
and some cooled power ups
that they can collect
in the game.
And I'm going to divide this
up into some logical groups.
So this logical group will help
us set up the three BitMask
that we have available
on every physicsBody.
The first one, is
the categoryBitMask
and this will allow you
to specify which groups,
which logical groups
this body belongs
to using a bit for each group.
So, I can belong to more
than one groups, no groups,
no groups, all groups.
The second BitMask will
allow me to determine
which other groups I'm going
to actually collide with.
So, if I don't collide
with anyone,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the physics bodies will
simply past through each other
or I can only have
my nodes collide
with certain other nodes.
And independently from
that, importantly,
the third one allows
you to specify
which contacts I will
be notified about.
So, I don't have to always
be notified if I want them
to collide and I could
have nodes completely pass
through each other and
still get the notification
when they intersect.
So how are we going
to set this up?
First I'm going to define my
three logical groups, GOOD GUYS,
BAD GUYS and POWER UPS.
And what I'm interested
in having happened is I
want the players to collide
with the enemies and I want them
to be able to walk through them
if they're blocking the way.
And I also want the enemies
to collide with each other
so they don't clump up and we
don't get killed in immediately
when we walk into the
big group of them.
I don't want the
players to collide
with each other 'cause it's
sort of a cooperative game,
I should let them pass
through each other.
So, I don't want that to happen.
But what I also interested
in is I want
to be notified anytime one
of the enemies touches one
of the heroes so that
I can apply damage,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
change the life counters,
stuff like that.
I also want to be notified when
one of my heroes collects one
of the POWER UPS so that I
can go and remove that POWER
UP from the game and apply
some really cool effects
and abilities to my heroes.
So, here's how we set that up.
We have our three
categories and we're going
to set the categoryBit on our
player to be the GOOD GUYS
and I'm going to set
his collisionBitMask
to be just BAD GUYS.
I only want him to
collide with the baddies.
And then the contactBitMask of
course will be both BAD GUYS
and POWER UPS 'cause I
need to know when any
of those two contacts occurs.
The same holds true for Player
2 and then for all of the--
all of the goblins in my scene
I want to set their category
to BAD GUYS and they're going to
collide with both of each other
as well as our hero characters.
Let's also do that for the
collision mask and I'll--
I'm also interested in being
notified whenever they intersect
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with the hero characters.
So that's some advanced
functionality that we offer
in the physics engine.
They're really customized
exactly what interactions you
want to occur.
So, there's a number
of other features
that we have available
in the Sprite Kit.
I'm not going to go
in depth with them
but I want a list a couple
of them and call them out.
We have transitions between
multiple scenes in your game.
We support rotations and
doorway openings and fade
through a color as
well as cross fade.
We've got a lot of
really cool stuff there.
You can reverse any action
that you've constructed
including a sequence
of multiple actions.
We also have some really
nice debugging stats
that you can overlay
on you SpriteKitView
that will let you know how
many dropped calls are being
executed, how many nodes
are currently in your scene.
We also support, instead of
applying filters at runtime,
when we render their frame,
you can also apply a CIFilter
to any texture in your game
by taking an existing texture
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and running it through a
filter to create a new one.
We have automatic
texture atlas generation
and we have some
really great new pieces
of developer documentation
available to you.
We have a complete sample of
Adventure available for you
and a complete Code Explained
guide that really walks
through the development
process for that game
and shows you how the game
is constructed and organized.
We also have a fantastic
programming guide.
You should be able to read
this and get up and running
within a day making
some really great games.
Any additional questions,
please contact Allan Schaffer.
We had a controller session
yesterday, if you missed
that that's a really great
new feature that you can add
to you Sprite Kit games as well.
Check out the video for that.
We have an additional Sprite
Kit session right after lunch,
so come back and join
us again for that one.
We're going to be talking a
little bit more about Adventure
and some of the Xcode
tools that we have.
Thank you.
[ Applause ]
[ Silence ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000