1
00:00:00,506 --> 00:00:09,546
[ Silence ]


2
00:00:10,046 --> 00:00:10,636
>> Good afternoon.


3
00:00:11,406 --> 00:00:13,646
Welcome to Designing
Games with Sprite Kit.


4
00:00:14,306 --> 00:00:15,426
My name is Norman Wang.


5
00:00:15,916 --> 00:00:18,096
I'm with the game
technology team at Apple.


6
00:00:18,126 --> 00:00:24,226
So today, I'll be very-- I'm
very excited to share with some


7
00:00:24,226 --> 00:00:27,346
of the very exciting features
and tools for the runtime,


8
00:00:28,276 --> 00:00:30,106
allow you to maximize
the performance,


9
00:00:30,176 --> 00:00:32,546
as well as minimize
the iteration time


10
00:00:32,956 --> 00:00:35,966
to build your game.


11
00:00:36,196 --> 00:00:38,726
So, for those of you who have
missed the earlier session,


12
00:00:38,726 --> 00:00:42,126
introduction to Sprite
Kit, here's a quick recap.


13
00:00:42,126 --> 00:00:45,376
So, Sprite Kit is a high
performance 2D rendering engine


14
00:00:45,606 --> 00:00:48,656
that is available in OS
X Mavericks and iOS 7.


15
00:00:49,586 --> 00:00:51,406
It has built-in physics support


16
00:00:51,716 --> 00:00:54,426
that features all the 2D
physics need for your game.


17
00:00:55,676 --> 00:00:57,646
It is the-- since the platform--


18
00:00:58,646 --> 00:01:03,266
the framework is available
on both iOS 7 and Mac OS X,


19
00:01:03,416 --> 00:01:06,936
they allow you to build once and
deploy it to multiple devices


20
00:01:06,936 --> 00:01:09,746
that include the iOS running
device and the Mac OS hardware.


21
00:01:09,746 --> 00:01:13,656
Not only Sprite Kit comes
with a super fast runtime,


22
00:01:13,876 --> 00:01:16,286
but we also provide a
lot of tools to allow you


23
00:01:16,286 --> 00:01:18,616
to integrate directly into
your games or pipeline.


24
00:01:19,006 --> 00:01:20,396
So, we're covering
some of that today.


25
00:01:21,636 --> 00:01:24,836
So, in terms of the feature
for rendering the animation,


26
00:01:25,316 --> 00:01:28,546
we have a lot of
features that's provided.


27
00:01:28,546 --> 00:01:32,306
That includes sprites,
shapes, particles,


28
00:01:32,576 --> 00:01:36,316
we also support non-linear
animation, we provide support


29
00:01:36,316 --> 00:01:41,156
for audio, video as well
different visual effects.


30
00:01:41,156 --> 00:01:44,876
So, I hope all of you have
seen the adventure demo so far


31
00:01:45,086 --> 00:01:47,206
and it is a production
quality sample code


32
00:01:47,316 --> 00:01:49,936
that was provided along with the
release of Sprite Kit framework.


33
00:01:50,186 --> 00:01:53,216
They also come with code
explained detailed documentation


34
00:01:53,216 --> 00:01:54,426
on how the game is created.


35
00:01:55,066 --> 00:01:57,666
So, I'll be referring to
various bits and pieces


36
00:01:57,666 --> 00:02:00,576
from the Adventure demo in
this talk to show you how quick


37
00:02:00,576 --> 00:02:03,386
and easy it is to
integrate Sprite Kit directly


38
00:02:03,386 --> 00:02:05,256
into your game.


39
00:02:05,436 --> 00:02:07,896
So, we'll start with looking
at your Adventure art pipeline


40
00:02:08,316 --> 00:02:11,626
to see how the Adventure
Game can do quick iteration


41
00:02:11,626 --> 00:02:14,326
on importing art files
into the runtime.


42
00:02:14,326 --> 00:02:16,326
And then we will
be looking at how


43
00:02:16,326 --> 00:02:19,286
to create various visual
effects for using the Sprite Kit


44
00:02:19,656 --> 00:02:23,406
that include post-processing
and particle system.


45
00:02:23,936 --> 00:02:27,736
I'll have-- we have some
very special guests today


46
00:02:27,736 --> 00:02:29,526
who will be joining us
that will be talking


47
00:02:29,526 --> 00:02:31,866
about how their experience is


48
00:02:32,196 --> 00:02:34,936
when they build the Adventure
Game using Sprite Kit.


49
00:02:34,936 --> 00:02:38,086
And I'll be wrapping up
with how to develop some


50
00:02:38,086 --> 00:02:40,416
of your custom tool that
include level editor,


51
00:02:40,416 --> 00:02:43,036
complex action editor, and some


52
00:02:43,036 --> 00:02:47,446
of the best practices
for using Sprite Kit.


53
00:02:47,626 --> 00:02:50,236
So, the Adventure Game
is a very complex game.


54
00:02:50,576 --> 00:02:52,346
And what really goes
in to the Adventure?


55
00:02:52,936 --> 00:02:57,506
So, Adventure manages a lot
of data that include lots


56
00:02:57,506 --> 00:03:01,366
of artwork files and we have
about 1,700 art files to load.


57
00:03:02,036 --> 00:03:03,806
We have a lot of
sound files to load


58
00:03:03,806 --> 00:03:06,586
for different sound effects,
we have particle effects


59
00:03:06,586 --> 00:03:08,676
and they represent the
tree leaves falling,


60
00:03:09,036 --> 00:03:10,936
smoke and damages.


61
00:03:11,446 --> 00:03:14,236
We have physics that allows
you to interact with the wall


62
00:03:14,236 --> 00:03:18,026
and not ran to objects
as well as AI characters.


63
00:03:19,136 --> 00:03:21,936
We have different-- also
have Collision Mappings.


64
00:03:21,936 --> 00:03:24,786
For example, the entire
Collision Map is data-driven


65
00:03:24,786 --> 00:03:27,976
and design offline and loaded
them dynamically upon game


66
00:03:27,976 --> 00:03:31,096
startup and builds these
dynamic walls inside your level.


67
00:03:32,536 --> 00:03:33,426
So, let's go ahead and look


68
00:03:33,426 --> 00:03:35,016
at the Adventure Game
startup sequence.


69
00:03:35,236 --> 00:03:39,406
How exactly Adventure
is doing upon startup?


70
00:03:40,226 --> 00:03:44,966
So, when the game is load upon
the game application launching


71
00:03:44,966 --> 00:03:48,446
handlers called, we start
loading all the background


72
00:03:48,446 --> 00:03:51,966
assets in parallel because
we need all these assets


73
00:03:51,966 --> 00:03:55,416
to construct our world before
we start issuing the first draw


74
00:03:55,416 --> 00:03:58,046
call will perform all the
asset loading in the background


75
00:03:58,296 --> 00:04:00,356
and get them loaded
as fast they can.


76
00:04:01,546 --> 00:04:04,236
Once we have these assets
in memory, we will go ahead


77
00:04:04,236 --> 00:04:06,556
and create an instance
of a SKScene.


78
00:04:07,676 --> 00:04:12,156
Once we have the scene, we'll
start placing enemies, spawners,


79
00:04:12,156 --> 00:04:16,116
as well as the Boss into
different places in the world.


80
00:04:16,116 --> 00:04:21,966
After that, we'll be parsing and
reading an offline Collision Map


81
00:04:22,466 --> 00:04:26,096
that will indicate and build
the physics world where exactly


82
00:04:26,096 --> 00:04:28,346
at the world-- lost
in your world.


83
00:04:29,146 --> 00:04:31,676
Finally, the scene
is constructed


84
00:04:31,676 --> 00:04:35,366
and we'll use presentScene
method to present


85
00:04:35,576 --> 00:04:38,336
that to a SKscene which part
of your [inaudible] file.


86
00:04:39,056 --> 00:04:40,506
And also, we also register


87
00:04:40,656 --> 00:04:42,596
for the game controller
notifications


88
00:04:42,676 --> 00:04:44,186
for adding game controller
support.


89
00:04:44,696 --> 00:04:48,406
So, in the first session,
we actually looked at some


90
00:04:48,406 --> 00:04:53,266
of the game update loop
of what a typical game


91
00:04:53,266 --> 00:04:55,616
about loop using Sprite Kit.


92
00:04:56,296 --> 00:04:59,516
But now we're going
to talk a little bit


93
00:04:59,516 --> 00:05:00,586
into the Adventure Game.


94
00:05:01,226 --> 00:05:02,906
So, the Adventure
Game actually tab


95
00:05:02,906 --> 00:05:06,646
into this update
loop at two places.


96
00:05:06,776 --> 00:05:09,806
Number one, when
the frame starts,


97
00:05:10,436 --> 00:05:11,846
update method get called.


98
00:05:12,496 --> 00:05:15,286
Here, what we do is we
update all the input


99
00:05:15,546 --> 00:05:19,126
that includes controllers,
touches, mouse and keyboard.


100
00:05:19,126 --> 00:05:21,846
So, once we have this
input, we translate them


101
00:05:21,916 --> 00:05:23,896
into delta movement
for the main character.


102
00:05:24,166 --> 00:05:26,966
So now, our hero knows and
either walk from A to B.


103
00:05:28,266 --> 00:05:32,036
So, once that's happening, we
also update AI, AI will say,


104
00:05:32,036 --> 00:05:34,436
"OK, maybe we should provide--


105
00:05:34,816 --> 00:05:36,996
perform some recasting
to see whether the player


106
00:05:36,996 --> 00:05:38,446
or the hero is visible or not.


107
00:05:38,736 --> 00:05:41,396
If it is, let's translate
that into a Delta movement."


108
00:05:41,906 --> 00:05:43,416
So, once you have this movement,


109
00:05:44,566 --> 00:05:47,616
we'll start issuing
animation playback frame.


110
00:05:48,306 --> 00:05:51,386
So, I know if I move from A
to B, I don't skate from A


111
00:05:51,386 --> 00:05:55,466
to B, I walk from A to B.


112
00:05:55,726 --> 00:05:58,016
So, once that's done,
we'll go to--


113
00:05:58,016 --> 00:06:01,046
we wait until we finish
simulating all the physics.


114
00:06:02,236 --> 00:06:05,146
So, if I'm walking from A to
B, there happen to be a wall


115
00:06:05,146 --> 00:06:07,536
in between, physics will kick in


116
00:06:07,536 --> 00:06:10,116
and stop me right in
front of the wall.


117
00:06:10,736 --> 00:06:13,116
So, this is a really
safe place for you


118
00:06:13,116 --> 00:06:16,856
to assume all the objects final
positions are finalized before


119
00:06:16,856 --> 00:06:17,256
the frame.


120
00:06:17,696 --> 00:06:20,446
So, at this time, we know
the character positions


121
00:06:20,446 --> 00:06:21,116
are finalized.


122
00:06:21,556 --> 00:06:24,896
We'll update the camera, so the
camera will follow the player


123
00:06:24,896 --> 00:06:26,886
and also reveal different
parts of the world.


124
00:06:28,016 --> 00:06:29,736
We also update the tree parallax


125
00:06:29,736 --> 00:06:31,186
because the camera
has been moved,


126
00:06:32,186 --> 00:06:35,616
and the fallen leaves have to
be following with the tree.


127
00:06:36,036 --> 00:06:43,466
Due to that complexity of
this game, it presents us


128
00:06:43,536 --> 00:06:44,596
with a lot of challenges.


129
00:06:45,676 --> 00:06:48,666
Number one, the construction


130
00:06:48,666 --> 00:06:51,906
of the scene cannot happen
unless all the assets are loaded


131
00:06:52,236 --> 00:06:56,436
including 1,700 art files
and we have huge amount


132
00:06:56,436 --> 00:06:58,486
of data dependencies
in each category.


133
00:06:58,486 --> 00:07:00,496
If you just look at
the background tiles,


134
00:07:01,046 --> 00:07:05,856
the level itself is a 4K x
4K tile map that gets divided


135
00:07:05,906 --> 00:07:10,846
into 128 by 128 grid,
sorry, 32 by 32 grid


136
00:07:10,846 --> 00:07:15,786
and each tile is
128 by 128 size.


137
00:07:15,936 --> 00:07:17,816
We also have a lot
of animation frames.


138
00:07:17,936 --> 00:07:19,266
For example, if we
look at animes,


139
00:07:19,266 --> 00:07:22,036
anime have idle animation,
have a tack animation,


140
00:07:22,586 --> 00:07:24,766
also have walking animation,
and death animation.


141
00:07:25,166 --> 00:07:27,086
So, we have different
animation frame categories


142
00:07:27,086 --> 00:07:28,706
for every single
character in the game.


143
00:07:29,256 --> 00:07:31,226
We also have a lot
of particle effects.


144
00:07:31,296 --> 00:07:33,326
For example, falling
trees, smoke,


145
00:07:34,346 --> 00:07:36,696
and also Collision
Mapping need to be loaded.


146
00:07:37,146 --> 00:07:38,846
So, how do we address
all of these


147
00:07:39,636 --> 00:07:41,686
by using the tools
provided by Sprite Kit?


148
00:07:42,686 --> 00:07:46,066
We're going to go into looking
at some of the art pipeline


149
00:07:46,556 --> 00:07:49,886
for the Adventure Game.


150
00:07:50,046 --> 00:07:53,436
So, diving a little bit
into the Adventure textures,


151
00:07:54,066 --> 00:07:58,156
again we have 1660 texture files


152
00:07:58,156 --> 00:08:01,176
and the game actually used
Texture Atlas for all of them.


153
00:08:01,456 --> 00:08:03,766
Character animations are
divided into several atlas.


154
00:08:03,766 --> 00:08:06,066
For example, walking
animation, 42 frames,


155
00:08:06,356 --> 00:08:08,166
that goes into a
single Texture Atlas.


156
00:08:08,916 --> 00:08:11,496
We have the environment,
1024 tiles,


157
00:08:11,606 --> 00:08:16,036
that's a 4K by 4K grid divided
into a single Texture Atlas,


158
00:08:16,276 --> 00:08:17,926
we'll put that I mean
to a Texture Atlas.


159
00:08:18,786 --> 00:08:21,476
The environments like trees,
caves and projectiles,


160
00:08:21,476 --> 00:08:23,926
all of them go to a single
Texture Atlas as well.


161
00:08:23,926 --> 00:08:29,556
So, this is what it looked like,
bunch of loose files as input


162
00:08:30,806 --> 00:08:33,486
that comes in various
shapes and sizes,


163
00:08:34,736 --> 00:08:36,676
passing through the
Sprite Kit tool


164
00:08:36,676 --> 00:08:40,155
and we generate a Texture
Atlas, as simple as that.


165
00:08:40,666 --> 00:08:41,946
So, speaking about
Texture Atlas,


166
00:08:42,166 --> 00:08:44,226
I want to talk a little
bit more on this topic.


167
00:08:45,396 --> 00:08:48,556
It is not a new thing,
but over the years,


168
00:08:48,556 --> 00:08:52,286
for the game I'm looking
at, that's draw call bound,


169
00:08:52,286 --> 00:08:56,216
not everybody is using Texture
Atlas to batch their draw calls.


170
00:08:56,826 --> 00:08:58,316
It's because there's
always this tank


171
00:08:58,316 --> 00:08:59,836
of work that need to be done.


172
00:09:00,326 --> 00:09:03,706
Traditionally, we have artists
that use Photoshop with bits


173
00:09:03,706 --> 00:09:06,396
and pieces of these textures
inside a bigger texture


174
00:09:06,836 --> 00:09:09,166
and save it and also
manually document it


175
00:09:09,166 --> 00:09:10,506
where each textures are.


176
00:09:10,506 --> 00:09:14,086
And this really makes
the iteration time suck.


177
00:09:14,666 --> 00:09:16,456
OK, so if artist is
not doing the work,


178
00:09:16,726 --> 00:09:18,526
we'll have engineers
do the work, right?


179
00:09:18,816 --> 00:09:21,376
So, the engineer will have to
either run some sort of script


180
00:09:22,006 --> 00:09:25,976
in the bulk-- build process or
use some PayTool to run that


181
00:09:25,976 --> 00:09:28,986
and iteration time is
pretty bad as well.


182
00:09:29,536 --> 00:09:33,796
So, we want to lift all
that work off your shoulder


183
00:09:33,796 --> 00:09:36,176
when we designed
Texture Atlas tool.


184
00:09:36,246 --> 00:09:37,416
So, you can just focus


185
00:09:37,416 --> 00:09:39,556
on putting the beautiful
pixels on the screen.


186
00:09:42,096 --> 00:09:44,216
So now, once you
have Texture Atlas,


187
00:09:45,156 --> 00:09:47,426
there're some major
benefits of having that.


188
00:09:47,666 --> 00:09:50,826
So, number one, it minimizes
the amount of GL render state.


189
00:09:51,996 --> 00:09:54,356
If you issue GL to all calls


190
00:09:54,356 --> 00:09:57,966
that have identical render
state, you can combine them


191
00:09:57,966 --> 00:10:01,366
into a single draw call to
minimize the amount of overhead


192
00:10:01,366 --> 00:10:03,516
for the GL render script change.


193
00:10:04,516 --> 00:10:06,166
It also minimizes the
amount of disk I/O.


194
00:10:07,136 --> 00:10:10,176
Imagine you're loading 10-24
of this background tiles


195
00:10:10,306 --> 00:10:14,846
versus loading a [inaudible]
of-- big texture files.


196
00:10:14,996 --> 00:10:20,056
We also minimize the amount
of memory overhead as well


197
00:10:20,056 --> 00:10:21,916
as avoid memories fragmentation.


198
00:10:22,296 --> 00:10:24,146
I want to talk a little
bit more about this


199
00:10:24,146 --> 00:10:27,606
and this is the Sprite Kit
specific feature where--


200
00:10:27,606 --> 00:10:31,296
if you look at animation frame,
I'm idling here from top down,


201
00:10:31,296 --> 00:10:35,986
I'm about 128 by 128
size, somewhat like that.


202
00:10:36,656 --> 00:10:40,986
And if I'm animating
from standing up pose


203
00:10:40,986 --> 00:10:43,016
to an attack pose,
that's an archer.


204
00:10:43,476 --> 00:10:46,896
So, now my frames stretch
it into say 200 by 100


205
00:10:48,086 --> 00:10:51,946
and if you play these
animation frames side by side,


206
00:10:52,486 --> 00:10:55,686
you notice the feet will
actually pop between frames.


207
00:10:56,336 --> 00:10:59,006
And to fix this, one of
the common methods is


208
00:10:59,036 --> 00:11:02,096
to add transparency borders
to your animation frame


209
00:11:02,096 --> 00:11:04,996
so that you make sure the
back foot is actually locking


210
00:11:04,996 --> 00:11:07,906
down at exact position
between animation frames.


211
00:11:08,226 --> 00:11:12,206
So, when you play this 42
frames at the same location,


212
00:11:12,306 --> 00:11:13,726
animation look silky smooth.


213
00:11:14,706 --> 00:11:16,056
OK, that solved the problem


214
00:11:16,056 --> 00:11:18,756
but you introduce these
transparent borders


215
00:11:18,756 --> 00:11:21,846
and we are paying 4 bytes
per pixel for something


216
00:11:21,846 --> 00:11:24,256
that really doesn't
contribute to the screen output.


217
00:11:25,656 --> 00:11:28,486
So, Sprite Kit is
actually doing trimming


218
00:11:28,486 --> 00:11:30,486
for these transparency
edges before put


219
00:11:30,486 --> 00:11:32,156
into to the final
Texture Atlas for you,


220
00:11:32,156 --> 00:11:33,036
it helps you save memory.


221
00:11:33,586 --> 00:11:35,836
And they require zero
work from your side.


222
00:11:37,086 --> 00:11:41,096
You can also draw unusual shape,
textures, so you don't have


223
00:11:41,096 --> 00:11:43,966
to follow on certain hardware
the power of tool rule


224
00:11:43,966 --> 00:11:46,386
because the texture
can be any size


225
00:11:46,386 --> 00:11:47,486
in putting into a Texture Atlas.


226
00:11:47,486 --> 00:11:49,036
I can't render that
directly on the screen


227
00:11:49,036 --> 00:11:50,886
without having to
worry about that.


228
00:11:51,536 --> 00:11:54,706
So, to create a Texture Atlas
using Sprite Kit tool is


229
00:11:54,706 --> 00:11:55,476
super easy.


230
00:11:55,966 --> 00:11:58,336
It is integrated
directly into Xcode.


231
00:11:58,876 --> 00:12:03,776
It's just a matter of dragging
a folder into your project


232
00:12:03,836 --> 00:12:05,036
and you'll have your
Texture Atlas.


233
00:12:05,136 --> 00:12:08,156
As long as the folder
has extension called


234
00:12:08,306 --> 00:12:10,086
".atlas" we'll go
ahead and process them.


235
00:12:10,086 --> 00:12:12,286
Each folder will turn into
a single Texture Atlas


236
00:12:12,506 --> 00:12:15,106
and you can start referencing
them at runtime right away.


237
00:12:15,726 --> 00:12:16,966
That's it, as simple as that.


238
00:12:17,126 --> 00:12:19,626
So here, we have
a bunch of files


239
00:12:19,926 --> 00:12:21,716
from Finder, drag
them into Xcode.


240
00:12:22,096 --> 00:12:25,506
Call them Environment at
a folderextension.atlas,


241
00:12:25,916 --> 00:12:28,596
press Command B and
you are done.


242
00:12:30,336 --> 00:12:34,406
You can also use the Texture
Atlas generator not just


243
00:12:34,406 --> 00:12:37,656
for 2D Sprite Kit enabled
games, you can also use it


244
00:12:37,656 --> 00:12:39,576
for any OpenGL enabled games


245
00:12:39,966 --> 00:12:43,706
because the Texture format
is OpenGL compatible.


246
00:12:44,066 --> 00:12:46,446
So, if you want to
build [inaudible] game,


247
00:12:46,856 --> 00:12:50,036
I use Texture Atlas say for
[inaudible] you can go ahead


248
00:12:50,036 --> 00:12:55,506
and use that, the output
is atlas C bundle format


249
00:12:55,506 --> 00:12:57,236
which contains a PNG file


250
00:12:57,536 --> 00:13:00,606
which is the Texture Atlas
texture and the plist file.


251
00:13:00,606 --> 00:13:03,226
And plist file, you can
just read it in and iterate


252
00:13:03,226 --> 00:13:04,406
through the NCDictionaries


253
00:13:04,406 --> 00:13:06,226
and it will tell you
all the attribute


254
00:13:06,226 --> 00:13:07,296
of every single texture


255
00:13:07,296 --> 00:13:09,126
that include whether
they are rotated or not.


256
00:13:09,676 --> 00:13:10,976
What's the original size?


257
00:13:10,976 --> 00:13:15,036
Where it is inside the quad of
your Texture Atlas and so on.


258
00:13:16,596 --> 00:13:20,626
But if you are using
Sprite Kit product template,


259
00:13:20,866 --> 00:13:23,326
we automatically turn on
this build setting for you,


260
00:13:23,326 --> 00:13:24,726
so you don't have
to do anything.


261
00:13:25,306 --> 00:13:29,246
But if you are using-- trying to
enable this for your OpenGL game


262
00:13:29,246 --> 00:13:32,366
or some game that's not using
Sprite Kit project template


263
00:13:32,956 --> 00:13:35,116
in build settings, make
sure you turn this fully


264
00:13:35,116 --> 00:13:37,536
on which I'll show you
in one of the demos.


265
00:13:37,536 --> 00:13:42,576
So, what do we do for you when
you use the Texture Atlas?


266
00:13:42,666 --> 00:13:45,366
What really goes on when
you press Command B?


267
00:13:46,336 --> 00:13:49,766
So, we do the very basic
automatic combination


268
00:13:49,836 --> 00:13:50,606
of textures.


269
00:13:51,316 --> 00:13:54,036
We generate hardware
specific Texture Atlas.


270
00:13:54,636 --> 00:13:57,736
So, if you have a folder of
images that contains Mac,


271
00:13:58,586 --> 00:14:02,636
Mac OS 2X, iPhone,
iPhone 2X, iPad, iPad 2X


272
00:14:02,636 --> 00:14:05,136
and the new iPhone
5 resolution format.


273
00:14:05,496 --> 00:14:06,056
Guess what?


274
00:14:06,056 --> 00:14:09,516
We generate a Texture Atlas
for each of those devices.


275
00:14:09,976 --> 00:14:13,256
So, when you load a
Texture Atlas on the iPhone,


276
00:14:13,386 --> 00:14:17,106
you don't have to pay a cost
for loading the similar textures


277
00:14:17,106 --> 00:14:19,586
for the iPad or iPad 2X,
it doesn't really matter.


278
00:14:20,606 --> 00:14:24,786
We don't want you to pull--
pay a memory overhead for that.


279
00:14:24,926 --> 00:14:27,346
We also do a Texture split.


280
00:14:27,846 --> 00:14:30,716
One, the Texture Atlas
greater 2K x 2K resolution.


281
00:14:31,236 --> 00:14:33,916
The reason being is 2K x 2K,


282
00:14:33,916 --> 00:14:36,316
it is the maximum
texture size that's going


283
00:14:36,316 --> 00:14:38,936
to be supported on
all iOS 7 devices.


284
00:14:38,936 --> 00:14:42,056
So, as soon as they go beyond
that range, it will split


285
00:14:42,056 --> 00:14:44,756
into another Texture Atlas file
and it will automatically handle


286
00:14:44,756 --> 00:14:48,916
that and you still get
the single plist file.


287
00:14:49,146 --> 00:14:49,966
So, what else do we do?


288
00:14:49,966 --> 00:14:52,226
When we process each
of the source images,


289
00:14:52,456 --> 00:14:55,636
we do automatically rotation
which will take by 90-degree


290
00:14:55,636 --> 00:14:58,086
and look through the light,
"Hey, this might fit better.


291
00:14:58,086 --> 00:15:01,646
OK, let's rotate it,
leave it and put it in."


292
00:15:01,756 --> 00:15:04,066
We trimmed the transparent
edges, so you don't have


293
00:15:04,066 --> 00:15:06,446
to pay anything that doesn't
have final contribution


294
00:15:06,446 --> 00:15:08,496
to the screen.


295
00:15:08,936 --> 00:15:11,096
But when you request
that texture even


296
00:15:11,096 --> 00:15:13,846
with the same dimension,
that's how it was on the disk?


297
00:15:14,456 --> 00:15:15,266
So, it's magical.


298
00:15:15,746 --> 00:15:19,846
For textures, that's
100 percent opaque.


299
00:15:19,846 --> 00:15:22,686
We're also doing extrude
on each of the edges


300
00:15:22,686 --> 00:15:25,526
by copying those edges
out by one pixel level.


301
00:15:25,866 --> 00:15:29,006
So, if you have a
tile-based game like Adventure


302
00:15:29,196 --> 00:15:31,206
and you move the cameras
around the background,


303
00:15:31,336 --> 00:15:32,726
you will not see flashing edges


304
00:15:32,726 --> 00:15:34,346
between because the
GL is rendering


305
00:15:34,346 --> 00:15:38,526
into the neighboring
Texture tile.


306
00:15:38,696 --> 00:15:44,056
So, here's a quick summary of
how we switched from loose files


307
00:15:44,056 --> 00:15:46,746
in Adventure demo to
use Texture Atlas.


308
00:15:48,576 --> 00:15:54,356
Originally, we go from 1660
file down to 26 Texture Atlases.


309
00:15:55,186 --> 00:15:57,306
So, file iOS significantly
reduced


310
00:15:57,936 --> 00:16:00,276
and also have some
memory savings.


311
00:16:00,276 --> 00:16:03,216
So, if you look at the animation
pixels that we're trimmed,


312
00:16:03,666 --> 00:16:06,376
we are trimming the
transparency pixels for each


313
00:16:06,376 --> 00:16:07,216
of the input Textures.


314
00:16:07,826 --> 00:16:11,536
So the summation of the original
pixel count was 90 megapixels


315
00:16:11,666 --> 00:16:13,476
before we turn in
to Texture Atlas.


316
00:16:14,576 --> 00:16:15,886
And after using Texture Atlas,


317
00:16:16,126 --> 00:16:19,456
the number of pixel count
reduced to 29 megapixels


318
00:16:20,316 --> 00:16:23,576
and that's about 61
megapixels of saving,


319
00:16:23,576 --> 00:16:28,756
each pixel cost 4 bytes and
we'll save about 244 max


320
00:16:29,666 --> 00:16:32,776
for doing what, dragging
a folder into Xcode.


321
00:16:33,146 --> 00:16:34,366
So, now, here's the fun part.


322
00:16:34,676 --> 00:16:36,896
We have a Texture
Atlas, how do we load it?


323
00:16:37,746 --> 00:16:40,406
OK, to load a loose
file from disk,


324
00:16:40,556 --> 00:16:44,066
we have this SKTexture class
called TextureWithImageNamed,


325
00:16:45,156 --> 00:16:50,636
you pass an image and we'll load
from disk to SKTexture instance.


326
00:16:51,896 --> 00:16:53,496
Notice, there's couple
of things that's going


327
00:16:53,496 --> 00:16:54,546
on in the background.


328
00:16:54,546 --> 00:16:56,596
Now, I like to share a little
bit of insight with you.


329
00:16:57,116 --> 00:16:59,406
So, Sprite Kit is maintaining
an internal texture cache.


330
00:17:00,486 --> 00:17:03,766
So, if you create a
spaceship texture instance,


331
00:17:04,136 --> 00:17:06,746
and later on in another
class, you try to say, "Hey,


332
00:17:06,746 --> 00:17:09,685
I want to create SKTexture
with the same spaceship."


333
00:17:10,096 --> 00:17:13,175
And guess what, we keep
track of all the SKTextures,


334
00:17:13,486 --> 00:17:14,626
that's a memory for you,


335
00:17:14,626 --> 00:17:16,346
everything is probably
reference conduit.


336
00:17:16,756 --> 00:17:19,396
All we do is, all right,
reference count plus one,


337
00:17:19,396 --> 00:17:21,646
give you the previous
instance, so you don't have


338
00:17:22,165 --> 00:17:26,326
to pay additional cost for
creating a duplicate texture.


339
00:17:27,536 --> 00:17:30,536
And also, this way, you
don't have to have some sort


340
00:17:30,536 --> 00:17:32,906
of a [inaudible] manager,
middle layer that keeps track


341
00:17:32,906 --> 00:17:35,206
of all these texture
pointers that say,


342
00:17:35,586 --> 00:17:38,136
"OK, this is app delegate.


343
00:17:38,386 --> 00:17:40,816
Hello, I'm here, I'm the
one that's loading all these


344
00:17:40,816 --> 00:17:43,726
textures and now let's
keep array of pointers.


345
00:17:43,726 --> 00:17:46,776
So, if it's [inaudible]
class, here you go."


346
00:17:47,086 --> 00:17:49,266
You don't have to
write any of that.


347
00:17:49,676 --> 00:17:53,126
How do load now a texture from--


348
00:17:53,676 --> 00:17:55,886
a Texture Atlas once you
put them into an atlas.


349
00:17:56,486 --> 00:17:58,196
It's the exact same API.


350
00:17:58,596 --> 00:18:01,536
You just reference its loose
file name, you don't have


351
00:18:01,536 --> 00:18:04,016
to worry about which
Texture Atlas it is in.


352
00:18:04,206 --> 00:18:06,346
You don't have to manually
load a Texture Atlas,


353
00:18:06,676 --> 00:18:09,206
this way is 100 percent
automatic.


354
00:18:10,056 --> 00:18:13,406
My favorite quote from Steve
Jobs is, "It just works."


355
00:18:13,616 --> 00:18:16,156
So here, we have
a Texture Atlas,


356
00:18:16,156 --> 00:18:18,386
inside we have the
same tree that's


357
00:18:18,386 --> 00:18:19,936
on the bottom left corner.


358
00:18:19,936 --> 00:18:24,056
Let's use the same API load, you
get exact same texture image.


359
00:18:24,636 --> 00:18:27,946
And now, I want to
talk a little bit


360
00:18:28,186 --> 00:18:30,216
about loose file
versus Texture Atlas.


361
00:18:30,896 --> 00:18:33,476
We support both and they
are interchangeable.


362
00:18:34,086 --> 00:18:37,776
So, number one, it gave you
the advantage of switching back


363
00:18:37,776 --> 00:18:41,336
and forth between lose texture
files versus Texture Atlas.


364
00:18:41,536 --> 00:18:45,246
You no longer have to recompile
your code or having a, "Hey,


365
00:18:45,246 --> 00:18:47,396
if debug, let's use
texture files.


366
00:18:47,676 --> 00:18:49,576
If released, let's
use Texture Atlas."


367
00:18:49,966 --> 00:18:51,166
No, you don't know--
you don't have


368
00:18:51,166 --> 00:18:53,036
to recompile code
for any of that.


369
00:18:54,216 --> 00:18:56,466
And second, we take loose files,


370
00:18:58,076 --> 00:19:00,406
loose files will have
precedents over Texture Atlas.


371
00:19:00,976 --> 00:19:03,236
So, having environment
Texture Atlas


372
00:19:03,276 --> 00:19:07,196
and inside you have a tree
object in there and you give


373
00:19:07,196 --> 00:19:08,796
that build to an artist.


374
00:19:08,846 --> 00:19:09,856
And the artist will say, "Oh,


375
00:19:09,856 --> 00:19:12,126
I wanted to just make some
minor changes with these trees.


376
00:19:12,126 --> 00:19:13,166
I don't want to preview that."


377
00:19:13,746 --> 00:19:16,576
So, guess what, the artist
can just drop in that tree--


378
00:19:16,576 --> 00:19:19,606
the new tree that he or she
created inside your bundle,


379
00:19:19,606 --> 00:19:22,716
re-launched the game, we found
out there's a loose over tree


380
00:19:22,716 --> 00:19:25,256
and then we'll manually
load that, so you don't have


381
00:19:25,256 --> 00:19:28,346
to again compile, debug build
our special artist version


382
00:19:28,346 --> 00:19:30,606
and you hand it out.


383
00:19:30,876 --> 00:19:36,466
OK, we also provide, for
advance users, the fine control


384
00:19:36,466 --> 00:19:37,486
of over a Texture Atlas.


385
00:19:37,486 --> 00:19:39,276
So, if you do feel the need


386
00:19:39,276 --> 00:19:42,686
of creating a SKTexture
instance, feel free to do so.


387
00:19:43,706 --> 00:19:48,286
We support-- we follow the same
UIKit and AppKit naming commands


388
00:19:48,286 --> 00:19:51,256
and notice here when you specify
your environment, you don't have


389
00:19:51,256 --> 00:19:52,766
to specify extension,
you don't have


390
00:19:52,816 --> 00:19:55,976
to specify I2X-iPhone,
any of that.


391
00:19:57,206 --> 00:19:59,346
So, we'll use SKTexture
Construct--


392
00:19:59,756 --> 00:20:03,636
the Class Initializer initialize
an environment Texture Atlas.


393
00:20:03,956 --> 00:20:06,056
We get number of
names which is array.


394
00:20:06,056 --> 00:20:07,766
We'll go ahead, iterate
through the array


395
00:20:08,046 --> 00:20:11,636
and create a corresponding
SKTexture by calling the SK--


396
00:20:11,736 --> 00:20:12,956
the Texture Named Method.


397
00:20:12,956 --> 00:20:17,156
And now, I want to have
a quick demo of creating


398
00:20:17,156 --> 00:20:21,096
and loading Texture and also
I want to cover the two ways


399
00:20:21,096 --> 00:20:22,136
of loading a Texture


400
00:20:22,136 --> 00:20:24,776
from a Texture Atlas
including the loose file way


401
00:20:24,776 --> 00:20:27,026
and second I want to
cover the automatic--


402
00:20:27,026 --> 00:20:30,866
the manual way of creating
SKTexture Atlas instance


403
00:20:30,866 --> 00:20:32,986
and iterate that.


404
00:20:33,956 --> 00:20:36,976
So, we'll begin by
creating OS X project.


405
00:20:37,516 --> 00:20:45,036
[ Pause ]


406
00:20:45,536 --> 00:20:50,936
Sure, so we need to render
some background in our scene


407
00:20:50,936 --> 00:20:55,676
so we can go ahead
and drag in a--


408
00:20:55,676 --> 00:20:59,176
or borrow some of the
environment art from Adventure.


409
00:21:00,436 --> 00:21:04,326
So Adventure Atlas, drag
that in, drop it in and say,


410
00:21:04,326 --> 00:21:07,906
"I want to copy it over
to the target, finished."


411
00:21:08,426 --> 00:21:10,156
Let's have a look.


412
00:21:10,156 --> 00:21:16,396
So, we have about 12 files here
and they each look different,


413
00:21:18,356 --> 00:21:20,816
so we decided to use
the big tree base


414
00:21:20,816 --> 00:21:22,696
which is the first
picture and let's use


415
00:21:22,696 --> 00:21:24,946
that as our background,
how do we do that?


416
00:21:25,606 --> 00:21:29,576
Let's clean up the
initialization code.


417
00:21:30,516 --> 00:21:36,356
[ Pause ]


418
00:21:36,856 --> 00:21:39,726
All right, so let's create a
Texture, let's load that Texture


419
00:21:39,726 --> 00:21:44,516
by creating Sprite node so we
use the spriteNodeWithImageNamed


420
00:21:44,626 --> 00:21:46,906
by specifying the
loose image name here.


421
00:21:46,906 --> 00:21:48,266
If you look at the
big tree base,


422
00:21:48,266 --> 00:21:51,156
that matter was a big tree base
[inaudible] on the left side,


423
00:21:51,586 --> 00:21:54,286
set up the anchorpoint,
set up the position and as


424
00:21:54,286 --> 00:21:57,336
with the scene, we can
just build and run that.


425
00:21:58,516 --> 00:22:02,676le
[ Pause ]


426
00:21:58,516 --> 00:22:02,676
[ Pause ]


427
00:22:03,176 --> 00:22:03,876
There you go.


428
00:22:03,876 --> 00:22:07,176
So we have one node in the
scene and that's our background.


429
00:22:07,536 --> 00:22:08,756
OK, so this is the simple way


430
00:22:08,756 --> 00:22:11,156
of loading a single
Texture from Texture Atlas.


431
00:22:12,396 --> 00:22:15,316
Cool, so let's look at the
app bundle to see what atlas,


432
00:22:15,316 --> 00:22:16,896
what actually goes into our app.


433
00:22:17,796 --> 00:22:21,246
So, say, show Package Contents,
let's go to the Resource folder


434
00:22:22,296 --> 00:22:24,656
and you notice you
have an Atlas C


435
00:22:25,626 --> 00:22:29,286
which is the compiled
version of the Source folder.


436
00:22:29,826 --> 00:22:34,396
So inside, we have our
Texture Atlas which pull images


437
00:22:34,396 --> 00:22:37,226
in there, have the
corresponding plist files,


438
00:22:37,366 --> 00:22:41,536
you can see aliases, whether the
image is fully opaque or not,


439
00:22:41,536 --> 00:22:44,176
we can perform some
optimization in GL level.


440
00:22:44,556 --> 00:22:45,966
What's the original size?


441
00:22:46,156 --> 00:22:48,746
Where it is located
inside the Texture Atlas,


442
00:22:48,746 --> 00:22:50,566
whether the texture is rotated,


443
00:22:50,686 --> 00:22:52,576
all the attributes that's
needed for the runtime?


444
00:22:54,386 --> 00:22:56,176
Now, let's go ahead and
animate the character.


445
00:22:56,346 --> 00:23:01,726
Let's drag in a Boss-- a packet
animation into our scene.


446
00:23:01,876 --> 00:23:03,986
So make sure to copy
into the folder


447
00:23:03,986 --> 00:23:08,686
so now we still call it atlas
extension and now if we look at,


448
00:23:08,686 --> 00:23:10,906
we have about 42
animation frames


449
00:23:11,126 --> 00:23:12,736
of this animation sequence.


450
00:23:14,996 --> 00:23:17,666
So, let's go ahead and add
a character to the scene


451
00:23:17,666 --> 00:23:18,776
and start animating him.


452
00:23:19,336 --> 00:23:24,896
So first, I'd like to add an
instance variable called Boss


453
00:23:25,026 --> 00:23:27,186
and now we have this
animation frames


454
00:23:27,186 --> 00:23:28,416
that we want to load it in.


455
00:23:28,416 --> 00:23:29,126
Let's create NSArray


456
00:23:29,126 --> 00:23:30,976
that contains all
these animation frames.


457
00:23:31,516 --> 00:23:44,496
[ Pause ]


458
00:23:44,996 --> 00:23:47,456
So let's initialize the array,


459
00:23:47,456 --> 00:23:51,026
create a SKTexture Atlas
instance that's Boss--


460
00:23:51,116 --> 00:23:56,396
called Boss Attack which
matches our folder name.


461
00:23:57,946 --> 00:24:02,366
We want to iterate through
this Texture Atlas by look up,


462
00:24:02,366 --> 00:24:03,576
how many names are there,


463
00:24:04,296 --> 00:24:08,136
create a corresponding
SKTexture instance


464
00:24:09,816 --> 00:24:15,366
by using the Texture Named
Selector, here you can see--


465
00:24:16,516 --> 00:24:22,056
[ Pause ]


466
00:24:22,556 --> 00:24:26,966
And now we want to add a
Sprite node called Boss


467
00:24:27,196 --> 00:24:29,696
and then we set this position
to be the middle of the screen


468
00:24:29,696 --> 00:24:33,386
and let's go ahead
and add that in.


469
00:24:33,386 --> 00:24:35,806
And we can build
that and have a look.


470
00:24:37,836 --> 00:24:38,496
There you go.


471
00:24:38,606 --> 00:24:39,506
So now we have two nodes.


472
00:24:41,046 --> 00:24:43,456
One is the tree, one is
the Boss, so let's go ahead


473
00:24:43,456 --> 00:24:49,246
and look at the Bundle.


474
00:24:49,246 --> 00:24:51,466
And notice now, we have
two compiled Texture Atlas


475
00:24:51,556 --> 00:24:55,356
and for the Boss,
42 animations packed


476
00:24:55,356 --> 00:24:56,606
into a single Texture Atlas.


477
00:25:00,336 --> 00:25:02,826
However the corresponding
plist file.


478
00:25:03,516 --> 00:25:11,916
[ Pause ]


479
00:25:12,416 --> 00:25:15,266
And now to animate
it, let's go ahead


480
00:25:15,266 --> 00:25:17,356
and add our animation
playback logic


481
00:25:17,356 --> 00:25:21,496
to say the mouse click
handler so what we want


482
00:25:21,496 --> 00:25:24,686
to do is we'd run
action on the Sprite


483
00:25:24,986 --> 00:25:26,386
which is the Boss character.


484
00:25:26,666 --> 00:25:31,526
So, we first defined animation
playback speed, we use SKAction


485
00:25:31,526 --> 00:25:37,706
of anime with texture and
now our Boss should be able


486
00:25:37,706 --> 00:25:38,646
to animate.


487
00:25:43,356 --> 00:25:45,096
All right, every
time we click them--


488
00:25:45,566 --> 00:25:48,306
the button, we'll have
animation sequence.


489
00:25:52,386 --> 00:25:53,926
It's very simple.


490
00:25:59,156 --> 00:26:01,606
So now, I would like to
show you the Build options.


491
00:26:01,976 --> 00:26:04,576
So if you go to Build
settings and just make sure,


492
00:26:04,776 --> 00:26:06,506
because we're using the
Sprite Kit template,


493
00:26:06,926 --> 00:26:09,286
so this option is
automatically enabled.


494
00:26:10,596 --> 00:26:13,146
The next part I want to
cover is visual effects.


495
00:26:14,636 --> 00:26:16,636
Generally speaking, there
are two vague categories


496
00:26:16,636 --> 00:26:17,396
of visual effects.


497
00:26:17,576 --> 00:26:20,186
Number one, post processing
which means that we are


498
00:26:20,186 --> 00:26:22,186
to perform some level
of image processing


499
00:26:22,186 --> 00:26:25,686
on a given render target
which can be [inaudible],


500
00:26:25,746 --> 00:26:27,796
frame buffer or an
input texture.


501
00:26:28,396 --> 00:26:30,446
If you're trying to say
you have a racing game


502
00:26:30,446 --> 00:26:32,186
and playback a motion blur,


503
00:26:32,216 --> 00:26:34,936
usually people grab the
frame buffer, downsize,


504
00:26:35,016 --> 00:26:38,166
followed by app sample
and then you squeeze all


505
00:26:38,166 --> 00:26:43,886
that with radius blur that
has alpha 100 percent in there


506
00:26:43,886 --> 00:26:45,566
so the inside of the
center of the screen


507
00:26:45,566 --> 00:26:47,826
as 100 percent you focus
and slowly blurred out


508
00:26:47,826 --> 00:26:49,316
and you [inaudible] that
on the final screen.


509
00:26:49,766 --> 00:26:53,116
So, totally support that
with-- via Core Image Filters.


510
00:26:53,176 --> 00:26:57,296
We can't show a quick demo and
we also support particle systems


511
00:26:58,056 --> 00:27:00,776
that usually people found a very
large number of small particles


512
00:27:00,776 --> 00:27:03,356
on the screen and
similarly it's a lifetime


513
00:27:03,736 --> 00:27:06,386
and we can use SKEmitterNode
for that.


514
00:27:07,876 --> 00:27:10,436
So in terms of using
post processing


515
00:27:10,436 --> 00:27:14,646
with Core Image Filters, it can
be applied to any SKEffectNode


516
00:27:15,066 --> 00:27:19,766
so the effect will apply to all
the children, all the children


517
00:27:19,946 --> 00:27:21,756
on this app node will
get flatten first


518
00:27:21,836 --> 00:27:24,076
and the effect will be
applied on this app tree


519
00:27:24,736 --> 00:27:29,486
so you can specify any
filter on the filter property


520
00:27:29,916 --> 00:27:31,186
by creating a new CIFilter.


521
00:27:31,336 --> 00:27:34,486
So here, we created a Gaussian
blur which is quick and simple.


522
00:27:35,006 --> 00:27:40,496
And you can also apply Core
Image Filters with any textures.


523
00:27:40,746 --> 00:27:43,866
So the Texture has a
selector that call Texture


524
00:27:43,966 --> 00:27:47,086
by applying CIFilters, here
we apply same Gaussian blur


525
00:27:47,426 --> 00:27:48,506
to the [inaudible] input texture


526
00:27:48,506 --> 00:27:49,826
and then you get
a result texture


527
00:27:49,826 --> 00:27:51,456
as having that effect on there.


528
00:27:52,536 --> 00:27:53,826
So, we'll have a quick demo


529
00:27:54,226 --> 00:27:58,166
of Sprite Kit running
with CIFilters.


530
00:27:59,486 --> 00:28:02,516
So here, we have a trees
demo from [inaudible] DC 2012


531
00:28:02,516 --> 00:28:04,676
which was created using
a development version


532
00:28:04,926 --> 00:28:08,006
of Sprite Kit and CIFilter.


533
00:28:08,396 --> 00:28:11,256
So here, we're rendering trees
with three different layers.


534
00:28:11,376 --> 00:28:15,156
We can go ahead and add, you
know, Gaussian blurs to blur all


535
00:28:15,156 --> 00:28:19,276
to show some depths, I know as
well as add some random effects


536
00:28:19,756 --> 00:28:23,136
so that it will show
the creepy feeling.


537
00:28:23,136 --> 00:28:27,436
We can add some particles and
use the old green filters on top


538
00:28:27,746 --> 00:28:31,226
and on the very top,
we can add a distortion


539
00:28:31,226 --> 00:28:32,486
of the [inaudible] environment


540
00:28:33,026 --> 00:28:41,506
by applying the distortion
effect on the wall, on the bulk.


541
00:28:44,476 --> 00:28:45,546
[Applause] So, quick and easy.


542
00:28:45,846 --> 00:28:49,356
You don't have to write any of
the specialized shaders and all


543
00:28:49,356 --> 00:28:51,796
of this is available
on both OS X and iOS.


544
00:28:51,796 --> 00:28:56,846
Now, I want to dive in a little
bit deeper for particles.


545
00:28:57,156 --> 00:29:02,096
So the particle system is being
heavily used for Adventure.


546
00:29:02,676 --> 00:29:05,416
So the leaves, the
damages, the flashes


547
00:29:05,616 --> 00:29:08,776
and the spawning effects are
all done with particle effects.


548
00:29:09,476 --> 00:29:12,466
And the Adventure Game
actually didn't create those


549
00:29:12,496 --> 00:29:13,316
particles manually.


550
00:29:13,646 --> 00:29:15,926
It uses one of the tools
that I will provide as part


551
00:29:15,926 --> 00:29:17,136
of the Sprite Kit Framework.


552
00:29:17,586 --> 00:29:22,886
I iterate these particles
and generate SKS file


553
00:29:22,886 --> 00:29:26,226
and at the runtime, we
deserialized the SKS file


554
00:29:26,226 --> 00:29:28,516
into SKEmitterNode and
add it to the scene.


555
00:29:28,646 --> 00:29:31,946
All the property are already
set and it's good to go.


556
00:29:32,186 --> 00:29:35,396
In the particle editor, we
provide about eight templates


557
00:29:35,596 --> 00:29:37,636
and this is just one of
the templates you can use


558
00:29:37,666 --> 00:29:39,926
to get you started to
whatever the quick effect


559
00:29:40,326 --> 00:29:41,166
that you are looking for.


560
00:29:42,176 --> 00:29:47,456
In terms of SKEmitterNode, we
want to provide a flexibility


561
00:29:47,456 --> 00:29:50,646
for you to get to the exact
look and feel that you want


562
00:29:50,646 --> 00:29:53,446
for your game in order to
generate a particular look


563
00:29:53,446 --> 00:29:58,206
of the particle system therefore
we provided a lot of properties.


564
00:29:59,676 --> 00:30:03,776
But the [inaudible] property is
very time consuming therefore we


565
00:30:03,776 --> 00:30:05,896
build a particle
editor inside Xcode.


566
00:30:06,886 --> 00:30:11,536
You can use it to edit any of
the attribute of SKEmitterNode


567
00:30:11,576 --> 00:30:13,806
and also is a good
design pattern


568
00:30:13,806 --> 00:30:16,656
because they separate the
design of the data away


569
00:30:16,656 --> 00:30:18,096
from the engineering
of the code.


570
00:30:18,946 --> 00:30:21,146
And it's also one of
the best ways to learn


571
00:30:21,146 --> 00:30:22,486
about SKEmitter attributes,


572
00:30:22,486 --> 00:30:25,636
because it live editor you
can just drag an attribute


573
00:30:25,636 --> 00:30:28,616
to see the change lively
because we integrate a SKView


574
00:30:28,616 --> 00:30:29,556
inside Xcode.


575
00:30:31,576 --> 00:30:35,456
Here is a quick look of what
the particle editor look


576
00:30:35,456 --> 00:30:37,066
like inside of Xcode.


577
00:30:37,066 --> 00:30:38,496
As you can see, we open SKS file


578
00:30:38,546 --> 00:30:41,246
which a particle
file inside Adventure


579
00:30:41,946 --> 00:30:45,476
and then we can quickly make
a modification to birth rate


580
00:30:45,916 --> 00:30:48,296
and we see the effect
right away.


581
00:30:52,156 --> 00:30:54,666
For particles, we also
provide keyframe sequences.


582
00:30:54,936 --> 00:30:56,896
You can use it to apply some


583
00:30:56,896 --> 00:30:59,846
of the properties of
the SKEmitterNode.


584
00:31:00,426 --> 00:31:03,416
Here, we are applying the
keyframe sequence to the color.


585
00:31:04,146 --> 00:31:06,536
So, it gives you
100 percent control


586
00:31:06,536 --> 00:31:09,296
of what a color sequence look
like from the birth point


587
00:31:10,656 --> 00:31:12,426
of a particle till its death.


588
00:31:13,636 --> 00:31:16,316
So here, when the
particle was spawned,


589
00:31:16,316 --> 00:31:19,966
it have a little bit brown color
and then later on at 25 percent


590
00:31:19,966 --> 00:31:22,646
of age, we go to a
white followed by a red


591
00:31:23,096 --> 00:31:25,486
and when it's-- at the
end of its life cycle,


592
00:31:25,486 --> 00:31:27,796
we turn to a slightly
blue color.


593
00:31:28,336 --> 00:31:32,616
You can also use keyframe
sequences on other properties.


594
00:31:32,906 --> 00:31:34,596
For example, apply
it to a scale.


595
00:31:34,966 --> 00:31:36,366
You can construct this in code.


596
00:31:37,426 --> 00:31:39,326
To-- Here, we have
a quick example


597
00:31:39,326 --> 00:31:42,356
of showing you how we can
use a keyframe sequence


598
00:31:42,356 --> 00:31:43,536
to apply to a scale.


599
00:31:43,536 --> 00:31:47,346
So here, we specify different
timelines and once it was spawn,


600
00:31:47,346 --> 00:31:51,516
it have a scale of 0.2, at the
quarter of the list is timeline,


601
00:31:51,516 --> 00:31:55,886
we change to a scale
to 0.7 and any values


602
00:31:55,886 --> 00:31:57,636
in between will be
interpolating that


603
00:31:57,636 --> 00:32:00,586
and you can just set directly
on a scale of sequence


604
00:32:01,016 --> 00:32:05,766
and it will be affecting the
scale throughout its lifetime.


605
00:32:07,436 --> 00:32:10,376
You can also add
actions to particles.


606
00:32:11,826 --> 00:32:14,116
Each particle, as soon as they
are spawned by the emitter,


607
00:32:14,116 --> 00:32:17,326
can ask you some of
the complex behaviors.


608
00:32:17,626 --> 00:32:21,016
So if you have really, really
complex behavior that you want--


609
00:32:21,016 --> 00:32:23,096
you're going after
for SKEmitterNode,


610
00:32:23,546 --> 00:32:24,876
we have action property.


611
00:32:24,876 --> 00:32:27,726
Here is a quick example.


612
00:32:28,486 --> 00:32:30,866
This is actually
a particle system.


613
00:32:31,626 --> 00:32:34,396
Each of the particles is
playing back 42 frames


614
00:32:34,396 --> 00:32:36,866
of animation sequence
on a certain speed.


615
00:32:37,456 --> 00:32:41,006
Just to show you some of
the basic functionality


616
00:32:41,006 --> 00:32:44,766
of how powerful particle
actions can give you.


617
00:32:46,236 --> 00:32:49,566
And now, once we tune
the particle system


618
00:32:49,566 --> 00:32:51,256
to the exact look and
feel of what we want,


619
00:32:51,256 --> 00:32:53,906
how do we load that at runtime?


620
00:32:54,836 --> 00:33:00,576
So what we do is we use
NSKeyedUnarchiver and just say,


621
00:33:00,576 --> 00:33:04,786
we want to unarchive BossDamage,
the SKS file and that's it.


622
00:33:04,786 --> 00:33:06,756
It's a one line and
at this point,


623
00:33:06,756 --> 00:33:10,016
you have your SKEmitterNode
instance ready to go,


624
00:33:10,016 --> 00:33:14,696
ready to be added to the
scene, and ready to animate.


625
00:33:14,856 --> 00:33:16,876
Before we jump into the
demo, I want to do some--


626
00:33:17,596 --> 00:33:19,166
give some of the
quick recommendations


627
00:33:19,166 --> 00:33:22,036
for using particle system
like any particle system,


628
00:33:22,546 --> 00:33:24,176
overhauling is not a good thing.


629
00:33:24,626 --> 00:33:27,196
So let's-- one of the good
recommendations I would give


630
00:33:27,196 --> 00:33:30,326
out is to keep the birth
down and we'll recommend


631
00:33:30,326 --> 00:33:34,416
to iterate your particle files
inside using the Xcode editor


632
00:33:34,416 --> 00:33:38,226
to allow you to see the changes
live, perform iteration quickly


633
00:33:38,226 --> 00:33:41,066
with no [inaudible],
command S, command R


634
00:33:41,066 --> 00:33:42,986
and you see the change
live right away.


635
00:33:43,506 --> 00:33:46,126
When particle emitters are not
visible, I'll recommend you


636
00:33:46,126 --> 00:33:49,766
to remove that and Spencer
later on will help--


637
00:33:49,766 --> 00:33:51,406
will come on the stage
and show you how--


638
00:33:51,556 --> 00:33:55,306
sometimes a few particles can
just achieve the very same look


639
00:33:55,506 --> 00:33:56,426
that you're looking after.


640
00:33:56,966 --> 00:34:01,516
So with this, I will
start a quick demo


641
00:34:01,516 --> 00:34:02,906
of using a particle system.


642
00:34:03,336 --> 00:34:05,686
Let's go ahead and create
a Sprite Kit project,


643
00:34:05,856 --> 00:34:08,446
let's call it demo particles.


644
00:34:09,186 --> 00:34:15,466
So in here, we already
have the scene.


645
00:34:15,466 --> 00:34:19,626
Let's go ahead and create a
particle file from resource.


646
00:34:20,196 --> 00:34:23,716
As you can see, there are
eight different types that's


647
00:34:23,716 --> 00:34:24,846
being provided.


648
00:34:24,846 --> 00:34:29,666
So let's just maybe go crazy
with starting with spark.


649
00:34:31,376 --> 00:34:33,235
Make sure it is in our target.


650
00:34:33,406 --> 00:34:36,255
Let's create-- and this
is what it look like.


651
00:34:37,476 --> 00:34:41,045
Cool. So how about
that's load that in game?


652
00:34:42,335 --> 00:34:46,795
Here I want to tab it, so that
every time when a mouse click,


653
00:34:47,045 --> 00:34:55,176
let's generate SKEmitterNode
and add that to the scene.


654
00:34:55,396 --> 00:34:56,476
Use NSKeyed--


655
00:34:57,516 --> 00:35:06,336
[ Pause ]


656
00:35:06,836 --> 00:35:11,076
-- Unarchive with file,
that's where we're looking for


657
00:35:11,076 --> 00:35:15,026
and then we're going to
NSBundle, getting the mainBundle


658
00:35:20,956 --> 00:35:26,256
and then we're going to get
pathForResource of our--


659
00:35:28,816 --> 00:35:33,686
my particle file with
file extension, sks.


660
00:35:36,816 --> 00:35:41,316
Then-- well, we have some error,
we'll go ahead and fix that.


661
00:35:42,006 --> 00:35:43,896
I set the position
to be the location.


662
00:35:44,366 --> 00:35:47,826
We'll add that to the scene.


663
00:35:49,516 --> 00:35:54,596
[ Pause ]


664
00:35:55,096 --> 00:35:56,886
This is what the error is.


665
00:35:57,516 --> 00:36:09,296
[ Pause ]


666
00:36:09,796 --> 00:36:12,076
All right, so every
time I click the mouse,


667
00:36:16,656 --> 00:36:18,246
what's the particle count now?


668
00:36:19,636 --> 00:36:22,886
6,500, let's do at
60 frames per second.


669
00:36:23,416 --> 00:36:26,606
So, OK, so that's easy to load,
one liner, setting the position,


670
00:36:26,606 --> 00:36:28,746
adding it, and let's go
ahead and make some changes


671
00:36:28,746 --> 00:36:30,936
to the particle, let's
see how easy it is.


672
00:36:31,346 --> 00:36:34,516
So, I want to create a
similar damage look as soon


673
00:36:34,516 --> 00:36:36,536
as I get hit in the [inaudible].


674
00:36:36,536 --> 00:36:39,906
So, let's go ahead and make
some changes to these particles.


675
00:36:40,006 --> 00:36:42,456
Number one, the birth rate
is a little bit too high,


676
00:36:42,456 --> 00:36:45,886
I don't really need 2,000
so let's go with say, 400,


677
00:36:46,376 --> 00:36:50,116
that looks a little bit
better and the lifetime,


678
00:36:50,186 --> 00:36:53,016
I want to make it slightly
shorter, so let's go with that


679
00:36:53,506 --> 00:36:57,386
and add a little bit
variance for your lifetime.


680
00:36:57,386 --> 00:36:59,606
OK, so that's a little
bit better.


681
00:36:59,926 --> 00:37:04,616
And how about we-- now the Y
value is a little bit flat,


682
00:37:04,866 --> 00:37:05,806
let's go ahead and stretch


683
00:37:05,996 --> 00:37:08,846
that by a little bit,
so that will be 50.


684
00:37:09,206 --> 00:37:11,636
I think the angle is
a little bit limited,


685
00:37:11,636 --> 00:37:14,416
so let's go ahead
and do all angles.


686
00:37:14,926 --> 00:37:19,416
Speed is a little bit too
high right now and we say,


687
00:37:19,476 --> 00:37:23,366
let's change it to 200,
and let's not do variance,


688
00:37:23,856 --> 00:37:26,916
and obviously if this is
a top down looking games,


689
00:37:26,916 --> 00:37:29,396
so we don't really need a
gravity here, so let's go ahead


690
00:37:29,396 --> 00:37:34,336
and set that to be 0, and
we can change the scale,


691
00:37:34,976 --> 00:37:39,356
say go from 0.4 and we want to
do an increment on the scale


692
00:37:40,466 --> 00:37:44,446
in a positive direction
and wallah.


693
00:37:45,356 --> 00:37:47,046
So, if we decided to go
ahead and change some


694
00:37:47,046 --> 00:37:51,236
of the damaged colors, we can
change slightly like that.


695
00:37:51,326 --> 00:37:53,206
And how about if we make--


696
00:37:53,206 --> 00:37:57,356
if we decide to that this damage
is only one time, I get hit,


697
00:37:57,486 --> 00:38:02,366
I spawned 200 particles and
the particle will finish.


698
00:38:02,606 --> 00:38:05,746
So, let's-- we can set
that by setting the maximum


699
00:38:05,746 --> 00:38:06,536
attribute here.


700
00:38:06,536 --> 00:38:12,246
We go 200, so let's run that.


701
00:38:15,016 --> 00:38:19,026
So, every time I get
hit, get the particle


702
00:38:19,026 --> 00:38:20,126
and particle goes away.


703
00:38:21,516 --> 00:38:26,906
[ Applause ]


704
00:38:27,406 --> 00:38:32,336
Next, I like to invite Graeme
Devine and Spencer Lindsay,


705
00:38:32,776 --> 00:38:35,806
will be talking to us about
building the Adventure Game.


706
00:38:36,236 --> 00:38:36,826
>> Thank you Norman.


707
00:38:37,606 --> 00:38:39,826
Hello, I'm Graeme Devine.


708
00:38:40,026 --> 00:38:40,956
>> I'm Spencer Lindsay.


709
00:38:41,316 --> 00:38:42,686
>> Today, we're going
to be talking to you


710
00:38:42,686 --> 00:38:43,806
about building Adventure.


711
00:38:44,596 --> 00:38:48,096
So, what happens with
the do to build it?


712
00:38:48,466 --> 00:38:49,626
[laughs] So, we know
a little bit about it.


713
00:38:50,006 --> 00:38:52,196
We're going to talk about some
of the technical challenges


714
00:38:52,296 --> 00:38:55,426
that we faced in actually
making the demo and some


715
00:38:55,426 --> 00:38:57,506
of the art challenges
that's being able to--


716
00:38:57,506 --> 00:38:59,596
that we have to do unless
you're making the demo too.


717
00:39:00,776 --> 00:39:02,436
So, let's take a quick
look at the demo again,


718
00:39:02,436 --> 00:39:05,286
just one last time so that you
can-- so you've seen it lots.


719
00:39:05,286 --> 00:39:07,686
We talked about how the
game has [inaudible] you got


720
00:39:07,686 --> 00:39:09,036
to talk about.


721
00:39:09,586 --> 00:39:12,856
So, the parallax effect that--
as the guy walks around,


722
00:39:13,166 --> 00:39:16,396
we have leaves on our trees
and the-- that the, you know,


723
00:39:16,396 --> 00:39:19,146
that look so nice and parallax
and so forth that looks awesome.


724
00:39:19,396 --> 00:39:22,526
The guy is bumping into the wall
and he sees a colliding well


725
00:39:22,526 --> 00:39:25,016
and he's sliding across this,
you know, the walls nicely,


726
00:39:25,426 --> 00:39:28,456
beautiful leaves falling from
the trees and looking, you know,


727
00:39:28,456 --> 00:39:30,296
nice and thready as
they fall to the ground


728
00:39:30,686 --> 00:39:33,486
and Sprites are animazing
like that's a real characters


729
00:39:33,486 --> 00:39:35,226
and we're going to talk about
how we actually made that too.


730
00:39:35,976 --> 00:39:37,936
Let's talk about the parallax.


731
00:39:38,646 --> 00:39:41,186
Parallax is an old effect that's
a, you know, that we've used


732
00:39:41,186 --> 00:39:42,636
in games in many, many years.


733
00:39:42,636 --> 00:39:44,836
It's actually really easy to do.


734
00:39:44,876 --> 00:39:47,356
If you're looking at the
formula then writing it down,


735
00:39:47,356 --> 00:39:51,316
you can stop doing that now
'cause you don't use formulas.


736
00:39:51,316 --> 00:39:55,186
The sub class SKNode from
more or less everything that,


737
00:39:55,186 --> 00:39:56,716
you know, that we have in the
game, the characters, the,


738
00:39:56,756 --> 00:39:58,946
you know, that the parallax
nodes, anything that's


739
00:39:58,946 --> 00:40:01,076
in the game is really
a sub class of SKNode,


740
00:40:01,076 --> 00:40:01,966
it's a good way of doing it.


741
00:40:02,516 --> 00:40:05,786
But, you can see here that the
parallax has three layers as,


742
00:40:05,786 --> 00:40:08,096
you know, kind of a root layer
with the tree at the beginning


743
00:40:08,096 --> 00:40:10,296
and as it goes up, the
parallax slides away


744
00:40:10,296 --> 00:40:11,796
from that [inaudible] 3D effect.


745
00:40:11,846 --> 00:40:16,186
When we think about cameras
in 3D games is I think


746
00:40:16,186 --> 00:40:18,826
of the camera 3D game, what's
a camera in the 2D game mean?


747
00:40:19,096 --> 00:40:21,856
And for our [inaudible], it's
the center of the screen.


748
00:40:22,596 --> 00:40:24,166
It's always kind of that
the center of the screen,


749
00:40:24,166 --> 00:40:26,106
everything moves so fast,
the parallax moves away


750
00:40:26,106 --> 00:40:28,756
from that and, you
know, movement.


751
00:40:28,876 --> 00:40:30,476
What's driving the
movement on that camera?


752
00:40:30,896 --> 00:40:32,556
It's actually-- in this
case, our characters


753
00:40:32,556 --> 00:40:35,356
as the [inaudible] screen
that pushing, you know,


754
00:40:35,356 --> 00:40:36,816
the pushing the world
around and with


755
00:40:36,816 --> 00:40:41,406
that changes the
actual camera position.


756
00:40:42,236 --> 00:40:48,016
So lesson number one is
always, in games, fake it all.


757
00:40:48,466 --> 00:40:52,416
[laughs] You make it a
game, make it look good.


758
00:40:52,416 --> 00:40:54,926
That's the most important thing.


759
00:40:55,876 --> 00:40:57,276
So, it's a good [inaudible]
fake 3D.


760
00:40:57,626 --> 00:40:59,696
Fake 3D is actually
was easy to do.


761
00:40:59,926 --> 00:41:01,856
We have our little root
object which is the roots


762
00:41:01,856 --> 00:41:04,196
of the actual ParallaxNode
and as our object moves


763
00:41:04,196 --> 00:41:06,836
from the center of the
screen from minus one


764
00:41:06,836 --> 00:41:08,506
to plus one the X and Y axes.


765
00:41:08,746 --> 00:41:11,176
That object is part
of the ParallaxNode,


766
00:41:11,636 --> 00:41:14,916
kind of miscue away from that
object, away from the center


767
00:41:14,916 --> 00:41:16,096
to give the effect of parallax.


768
00:41:16,976 --> 00:41:21,206
Possibly, the code that
we wrote actually do that.


769
00:41:21,376 --> 00:41:24,986
So, ParallaxSprite, you
know, from an SKNode,


770
00:41:25,156 --> 00:41:27,776
[inaudible] much a little set up
in there, then the actual code


771
00:41:27,776 --> 00:41:32,476
to actually setup, we're like
good old days so we just want


772
00:41:32,476 --> 00:41:36,126
to load three PNG files and
we want those three PNG files


773
00:41:36,126 --> 00:41:39,136
to be part of our ParallaxSprite
and we have a voodoo number


774
00:41:39,136 --> 00:41:43,156
that is really the
heights of a tree, 150.


775
00:41:43,946 --> 00:41:45,166
That doesn't mean anything.


776
00:41:45,166 --> 00:41:46,946
It's just the [laughs],
you know,


777
00:41:46,946 --> 00:41:48,226
the effect where
I see [inaudible]


778
00:41:48,866 --> 00:41:51,096
and we want the Sprite
to fade off an alpha


779
00:41:51,176 --> 00:41:53,376
as that character approaches
the tree, we ought to be able


780
00:41:53,376 --> 00:41:55,636
to see the character underneath
the trees and so we're going


781
00:41:55,636 --> 00:41:58,516
to talk about how we
[inaudible] to did that too.


782
00:41:58,736 --> 00:42:01,386
So, if we look at the SKNode
and how it's actually set up,


783
00:42:01,386 --> 00:42:04,006
you can see that the SKNode is,
you know, at the bottom there,


784
00:42:04,006 --> 00:42:06,126
there's ParallaxSprite, we
got these three children,


785
00:42:06,596 --> 00:42:10,006
these three PNG files on top
of that, you know, the RootNode


786
00:42:10,006 --> 00:42:11,406
and then on top of that,


787
00:42:11,436 --> 00:42:12,176
[inaudible] leaves
that come out.


788
00:42:12,936 --> 00:42:16,206
And if run through how things
were actually done in the Xcode,


789
00:42:17,606 --> 00:42:20,096
the two lines of code work out
the opposite X and opposite Y.


790
00:42:20,146 --> 00:42:24,166
That's, you know, that kind of
show which sides are off on,


791
00:42:24,536 --> 00:42:27,086
you know, from that zero to
one that we showed you before


792
00:42:27,686 --> 00:42:29,156
and we work out that
for X and the Y.


793
00:42:29,766 --> 00:42:33,526
Then we walk through our
children and we multiply


794
00:42:33,526 --> 00:42:36,736
that with voodoo number, really
it's just a voodoo number,


795
00:42:37,146 --> 00:42:38,956
they're OK to have voodoo
number, it's a game.


796
00:42:39,486 --> 00:42:42,086
And we set that to the
position on the node


797
00:42:42,086 --> 00:42:45,306
and that actually produces
that parallax effect


798
00:42:45,886 --> 00:42:48,716
as the Sprite moves around
because the children moving away


799
00:42:48,716 --> 00:42:50,306
from the center of
the screen multiplied


800
00:42:50,306 --> 00:42:53,376
by that number chooses a
very nice parallax effect.


801
00:42:53,766 --> 00:42:54,456
Very, very easy.


802
00:42:55,026 --> 00:42:59,196
So, we also have the character--


803
00:42:59,196 --> 00:43:01,696
the trees fade as the
character approaches that.


804
00:43:01,696 --> 00:43:02,466
So how do we do that?


805
00:43:02,936 --> 00:43:04,096
So the Adventure
character, the--


806
00:43:04,096 --> 00:43:05,216
there's a ton of them


807
00:43:05,216 --> 00:43:06,716
in the game 'cause
it's multiply the game.


808
00:43:06,966 --> 00:43:08,676
We work out which Adventure
character is closest


809
00:43:08,676 --> 00:43:10,696
to this tree, look
how far away that is,


810
00:43:11,336 --> 00:43:14,736
and then if it's too far
away, it's, you know,


811
00:43:14,736 --> 00:43:17,036
we set it to being completely
fake, so these are going


812
00:43:17,036 --> 00:43:18,786
to be completely fake,
but if it's close enough,


813
00:43:19,016 --> 00:43:21,876
we do a nice little
square fall off on--


814
00:43:21,876 --> 00:43:23,406
as the character approaches it,


815
00:43:23,406 --> 00:43:25,256
so that's the tree
fades away nicely.


816
00:43:25,496 --> 00:43:27,336
And we make it stay
around a little bit,


817
00:43:27,336 --> 00:43:29,276
so that's what with
the 0.1 and 0.9.


818
00:43:29,696 --> 00:43:32,986
The Collision Mapping
is kind of interesting.


819
00:43:32,986 --> 00:43:34,546
You can see here
[inaudible] collision volumes.


820
00:43:34,916 --> 00:43:37,136
We [inaudible] many
of them in the game.


821
00:43:37,136 --> 00:43:39,866
I think there's like 20 of
them for the entire level.


822
00:43:39,926 --> 00:43:42,276
We actually ended up
using the physics system.


823
00:43:43,056 --> 00:43:46,106
But we then definitely start
out using the physics system.


824
00:43:46,636 --> 00:43:49,236
To begin with, we did
this the wrong way.


825
00:43:50,116 --> 00:43:51,396
It's OK to do things
the wrong way.


826
00:43:52,486 --> 00:43:56,266
We load, it's already great
big PNG file and we load


827
00:43:56,266 --> 00:43:58,846
that in the 2D array
if my guy is standing


828
00:43:58,846 --> 00:44:00,646
on black, he can move around.


829
00:44:00,926 --> 00:44:03,106
My guy is standing
on red, he stops.


830
00:44:03,736 --> 00:44:07,166
Simple, that's the way-- that
seem the obvious way to do it.


831
00:44:07,166 --> 00:44:10,066
It turned out to be too much
code, so that will be a lot


832
00:44:10,066 --> 00:44:12,626
of code and just him seem
more and more and more to try


833
00:44:12,626 --> 00:44:14,106
and fix the, you know,
fix the problems.


834
00:44:14,436 --> 00:44:15,996
It works terribly.


835
00:44:16,406 --> 00:44:18,946
The guy will get stuck on
the wall and he won't be able


836
00:44:18,946 --> 00:44:20,916
to move out and he
won't slide along


837
00:44:20,916 --> 00:44:22,946
like [inaudible]
slide along, you know,


838
00:44:22,946 --> 00:44:25,766
it was just not a good
choice and he-- wrong.


839
00:44:26,436 --> 00:44:30,056
But it sure seems
obvious, you know,


840
00:44:30,096 --> 00:44:31,896
[inaudible] write the code, I'm
not going to use Sprite Kit.


841
00:44:31,896 --> 00:44:34,186
I'm going to roll this on my own
and it's going to be awesome.


842
00:44:34,706 --> 00:44:36,106
No, no, I'm not that also.


843
00:44:36,106 --> 00:44:41,276
[laughter] So it turns out the
right way was actually pretty


844
00:44:41,276 --> 00:44:41,856
darn easy.


845
00:44:42,046 --> 00:44:46,376
It was to use the physics
system built into--


846
00:44:46,376 --> 00:44:48,886
in the Sprite Kit
and as it turned


847
00:44:48,886 --> 00:44:50,996
out to be zero lines of code.


848
00:44:51,956 --> 00:44:55,076
But let me qualify that
'cause there's no such thing


849
00:44:55,076 --> 00:44:56,086
as zero lines of code.


850
00:44:57,416 --> 00:45:03,146
There is a little bit of set up
and that's full lines of code.


851
00:45:03,616 --> 00:45:05,616
So we have a rectangle
which is one of those red


852
00:45:05,616 --> 00:45:09,496
or blue rectangles
for the actual walls.


853
00:45:10,076 --> 00:45:11,746
We add that to the physics
party and we say, "Hey,


854
00:45:11,746 --> 00:45:13,026
this is physics party
on the Sprite."


855
00:45:13,746 --> 00:45:15,416
We say, "It's not
been moving around,


856
00:45:15,636 --> 00:45:16,746
that wall is going
to stay still."


857
00:45:17,526 --> 00:45:20,476
It's going to be called the wall
and we add it into the world.


858
00:45:21,306 --> 00:45:24,156
And boom, that is it, we
had done, that guy collides


859
00:45:24,156 --> 00:45:26,136
with the wall, he
goes along nicely.


860
00:45:26,136 --> 00:45:28,226
It is all done for
you from then on out


861
00:45:28,226 --> 00:45:29,826
and we didn't have
to do anything.


862
00:45:30,846 --> 00:45:32,436
It was like happy day.


863
00:45:32,436 --> 00:45:33,896
[Inaudible] Spencer
at the second lesson.


864
00:45:33,926 --> 00:45:36,346
>> We're going to talk
about the art pipeline.


865
00:45:36,346 --> 00:45:38,796
We have-- there's a
lot of stuff to talk


866
00:45:38,796 --> 00:45:40,636
about in the pipe
line-- art pipeline.


867
00:45:41,086 --> 00:45:43,186
But, I'm going to
go through three.


868
00:45:43,406 --> 00:45:45,046
The first one is plan your art.


869
00:45:45,466 --> 00:45:47,296
Make sure that you know
what your art is going


870
00:45:47,296 --> 00:45:52,186
to be before it goes in, because
our resources cost money and one


871
00:45:52,186 --> 00:45:56,126
of the things that Graeme and I
do is that Graeme will make art.


872
00:45:56,386 --> 00:45:59,936
Graeme will do the program
or art which is, you know,


873
00:45:59,936 --> 00:46:06,196
that's awesome, because, you
know, Graeme will give me a PNG


874
00:46:06,196 --> 00:46:08,446
that is the right
size, the right bit up,


875
00:46:08,716 --> 00:46:10,486
the right orientation
or whatever.


876
00:46:10,736 --> 00:46:14,506
And I can take that as a
communication tool and then use


877
00:46:14,506 --> 00:46:18,776
that as, you know, as a template
for us to put the real art in.


878
00:46:18,776 --> 00:46:22,886
So, another one is limit
the size of your resources,


879
00:46:22,886 --> 00:46:24,746
limit the number
of your resources,


880
00:46:24,746 --> 00:46:27,356
make sure that you're not
using system resources crazy


881
00:46:27,356 --> 00:46:30,186
because a lot of artist wanted
to put a ton of polygons


882
00:46:30,186 --> 00:46:33,596
or [inaudible] or, you know,
particles into a system.


883
00:46:33,986 --> 00:46:38,416
And then you, you know, you
bug the system, it runs slow


884
00:46:38,416 --> 00:46:40,636
and you're fighting with
the programmer over assets.


885
00:46:40,636 --> 00:46:43,146
And if you can get the
coolest looking effect


886
00:46:43,146 --> 00:46:46,426
with the smallest number of
resources, that's a total win.


887
00:46:46,426 --> 00:46:49,096
We have kind of a contest
in the lab or, you know,


888
00:46:49,096 --> 00:46:50,616
we try to get the
neatest looking thing


889
00:46:50,616 --> 00:46:52,526
out of the smallest
number of system resources.


890
00:46:52,936 --> 00:46:54,916
And then also build
only what you need.


891
00:46:55,136 --> 00:46:58,836
So, if you're going to build
the coastline and you see part


892
00:46:58,836 --> 00:47:01,086
of the ocean, don't build
the whole ocean, you know,


893
00:47:01,086 --> 00:47:03,346
just get what you need
especially in 3D games


894
00:47:03,346 --> 00:47:04,896
but in 2D games this
also applies.


895
00:47:05,326 --> 00:47:07,696
So you make sure that, you
know, what's going to go


896
00:47:07,696 --> 00:47:11,156
on the screen, if it's only
going to show up at 256 pixels


897
00:47:11,156 --> 00:47:13,726
in screen size, make
it 256 pixels.


898
00:47:13,806 --> 00:47:18,376
Don't make it 4K, you know,
make your assets as big


899
00:47:18,376 --> 00:47:21,216
as they're going to be.


900
00:47:21,566 --> 00:47:24,996
So, this is kind of a napkin
sketch, one of the critters


901
00:47:25,146 --> 00:47:29,006
and this was our first, you
know, our first presentation


902
00:47:29,006 --> 00:47:32,236
of the client and they came
back and they said, "You know,


903
00:47:32,236 --> 00:47:34,106
I like the eyes but let's
get some bigger eyes.


904
00:47:34,106 --> 00:47:36,986
Let's get some, you know,
some huge googly eyes,"


905
00:47:36,986 --> 00:47:39,436
and we put those in and they
were, "Whoa, that's a lot


906
00:47:39,436 --> 00:47:40,786
of eyes, let's trim the eyes."


907
00:47:40,786 --> 00:47:44,496
[laughter] So then we came back
and we had built this thing


908
00:47:44,496 --> 00:47:45,556
in Maya by this point.


909
00:47:45,556 --> 00:47:47,276
We have the big googly
eyes in Maya.


910
00:47:47,696 --> 00:47:50,626
And we did a tap
down Render and all


911
00:47:50,626 --> 00:47:56,436
of our animations were basically
on alpha, tap down Renders


912
00:47:56,436 --> 00:48:00,516
in Maya, frame by frame out as
sequential PNGs to a folder.


913
00:48:01,016 --> 00:48:04,316
And so this was our-- our fix,


914
00:48:04,316 --> 00:48:08,036
was we made it big green warts
instead of big red eyeballs.


915
00:48:08,566 --> 00:48:11,806
And then-- so this was our
final little dude, you know,


916
00:48:11,806 --> 00:48:12,806
this is kind of our--


917
00:48:12,996 --> 00:48:16,556
after iterating back and
forth, got to the critter.


918
00:48:16,786 --> 00:48:19,936
And then made these
spreadsheets out of--


919
00:48:20,296 --> 00:48:22,236
what are we calling it again?


920
00:48:22,236 --> 00:48:22,786
>> Atlas files.


921
00:48:22,886 --> 00:48:28,286
>> Atlas files, sorry,
artist, programmer.


922
00:48:28,726 --> 00:48:31,066
[laughter] And they were
super easy to build.


923
00:48:31,066 --> 00:48:34,876
I mean, I-- we would build a
sequential list of PNG files,


924
00:48:35,236 --> 00:48:38,496
throw them into a folder,
put them into Xcode and bang,


925
00:48:38,496 --> 00:48:42,226
we had this little guy getting
hit by an arrow or whatever.


926
00:48:42,546 --> 00:48:44,836
Then the programmers
were able to take that,


927
00:48:44,836 --> 00:48:47,136
assign it to a spread,
assigned to a character position


928
00:48:47,136 --> 00:48:49,166
and you know, and
trigger it when needed.


929
00:48:49,886 --> 00:48:54,416
So another thing that we
did was this particle system


930
00:48:54,416 --> 00:48:57,536
that you guys have
been hearing about.


931
00:48:57,536 --> 00:49:00,186
This was kind of-- this is
that wind that I was talking


932
00:49:00,186 --> 00:49:03,336
about where we have-- it's a
really tiny amount of resources.


933
00:49:03,336 --> 00:49:09,686
We used 25 particles twice and
so 50 particles total for all


934
00:49:09,686 --> 00:49:10,736
of those leads all
over the world.


935
00:49:10,736 --> 00:49:14,046
And you can see here, we use
two little tiny particles,


936
00:49:14,046 --> 00:49:17,176
two little tiny textures
and started them off


937
00:49:17,176 --> 00:49:19,576
at 100 percent scale
down to zero.


938
00:49:20,066 --> 00:49:24,636
Zero percent opacity up to a
hundred and it ended up looking


939
00:49:24,636 --> 00:49:27,316
like a bunch of leaves
kind of floating


940
00:49:27,316 --> 00:49:29,126
down on the forest floor,
it really worked out well.


941
00:49:29,126 --> 00:49:30,706
>> Oh, back to me.


942
00:49:31,506 --> 00:49:33,826
Lesson number three,
agree on stuff.


943
00:49:34,486 --> 00:49:35,436
You know, we're a small team


944
00:49:35,436 --> 00:49:38,416
and we had a very tight
deadline for this.


945
00:49:38,416 --> 00:49:41,536
So day to day agreeing on what
we're actually doing is kind


946
00:49:41,536 --> 00:49:42,016
of important.


947
00:49:42,016 --> 00:49:44,686
So, let's take a look at
our internal pipeline.


948
00:49:45,216 --> 00:49:47,026
Communications, [inaudible]
in the same office,


949
00:49:47,026 --> 00:49:49,036
so it actually worked
out pretty darn well.


950
00:49:49,036 --> 00:49:53,336
I can just yell at him that, you
know, and-- we never yell, yes,


951
00:49:53,336 --> 00:49:55,356
yes on doing stuff, but
communication is very important.


952
00:49:55,496 --> 00:49:57,386
And it applies to things
like naming schemes.


953
00:49:57,456 --> 00:50:00,166
You don't think that these
things, I just want to make game


954
00:50:00,166 --> 00:50:01,286
and pull the structure.


955
00:50:02,166 --> 00:50:04,076
Even the coordinate
system that you use


956
00:50:04,076 --> 00:50:07,356
in the game 'cause we use
all these tools, we use Maya,


957
00:50:07,356 --> 00:50:09,866
we use Photoshop, we
use Xcode and each one


958
00:50:09,866 --> 00:50:11,116
of these has a different
coordinate system


959
00:50:11,116 --> 00:50:13,746
and you'd really have to agree
on what the number one means.


960
00:50:14,436 --> 00:50:15,966
And bigger things,
like orientation.


961
00:50:16,326 --> 00:50:18,146
Orientation is a
[inaudible] games.


962
00:50:18,376 --> 00:50:22,646
Agree on which direction is up
and write it on the white board


963
00:50:23,256 --> 00:50:26,596
and do not end up with a
hacked file for the one is off


964
00:50:26,646 --> 00:50:28,936
by 90 degrees, it has
plus 90 [inaudible]


965
00:50:29,056 --> 00:50:33,026
because that will come and
haunt and you will shift


966
00:50:33,026 --> 00:50:35,786
and all the guy will become
like this, and you wonder why


967
00:50:35,786 --> 00:50:36,766
and it's a plus 90,
you have an [inaudible]


968
00:50:36,766 --> 00:50:38,276
that you forgot to change.


969
00:50:40,076 --> 00:50:41,836
Sorry, that might have happened.


970
00:50:41,836 --> 00:50:41,903
[Laughter]


971
00:50:41,903 --> 00:50:47,356
>> Like I said before,
programmer art is great


972
00:50:47,536 --> 00:50:51,186
and there's probably like
three artists in this audience.


973
00:50:51,566 --> 00:50:54,336
But go home and talk to
your artist and tell them


974
00:50:54,686 --> 00:50:58,466
to let you do art, because
the art that you provide


975
00:50:58,466 --> 00:51:02,796
to us is an invaluable
tool of communication.


976
00:51:02,796 --> 00:51:07,086
It allows us to iterate back and
forth with you when you give us


977
00:51:07,136 --> 00:51:09,876
that artwork, you know
that it works in code.


978
00:51:10,106 --> 00:51:12,026
For example, I mean
the next one here,


979
00:51:12,026 --> 00:51:18,986
this is a Graeme's art this
worked perfectly for Graeme


980
00:51:18,986 --> 00:51:21,946
because he has a
vector, you know, that--


981
00:51:21,946 --> 00:51:23,046
which way is this thing going


982
00:51:23,306 --> 00:51:25,156
and he's also got
these three different--


983
00:51:25,196 --> 00:51:28,076
this represent those
three parallax layers.


984
00:51:28,456 --> 00:51:32,316
So, he was able to go in, send
box, play around with like,


985
00:51:32,476 --> 00:51:37,196
you know, all of his numbers
and get all of the layers


986
00:51:37,196 --> 00:51:39,386
to work correctly with the
camera and then he gave it


987
00:51:39,386 --> 00:51:42,736
to me, and then we built
this stuff in Photoshop


988
00:51:42,736 --> 00:51:44,276
and made it all pretty
and stuff and so--


989
00:51:44,276 --> 00:51:45,746
then it actually
look like a tree.


990
00:51:46,096 --> 00:51:50,826
And so, so yeah, programmer art
is awesome, I love programmer.


991
00:51:52,686 --> 00:51:55,816
>> The folder structure of the
game is also really important.


992
00:51:55,816 --> 00:51:59,316
You have to remember, you know,
Xcode does a lot of the work


993
00:51:59,316 --> 00:52:01,546
for you and puts things nicely
into groups and so forth,


994
00:52:01,546 --> 00:52:04,156
resources, but that is not
necessarily representing


995
00:52:04,156 --> 00:52:07,136
on the hard drive, they won't
use all these tools, Photoshop,


996
00:52:07,186 --> 00:52:08,686
Maya, you know, these
sound tools.


997
00:52:08,686 --> 00:52:10,736
They're supposed to put
things into separate folders


998
00:52:10,736 --> 00:52:13,476
that you will agree on,
separate your game data


999
00:52:13,476 --> 00:52:16,756
from your level data from
your game data as localization


1000
00:52:16,756 --> 00:52:19,686
and so forth, but, you know,
[inaudible] different folders.


1001
00:52:20,056 --> 00:52:23,056
It sounds simple but that
folder is where you live,


1002
00:52:23,386 --> 00:52:24,336
so it's really important.


1003
00:52:24,806 --> 00:52:28,316
>> And I-- finally, this
is another great way


1004
00:52:28,396 --> 00:52:29,526
to communicate back and forth.


1005
00:52:29,796 --> 00:52:33,326
Our rule that we've kind of
like been going back and forth


1006
00:52:33,326 --> 00:52:34,796
on for the past like 25 years


1007
00:52:34,796 --> 00:52:39,216
of game development is a
meaningful name, just something


1008
00:52:39,216 --> 00:52:41,726
that means something that,
you know, that makes sense,


1009
00:52:41,726 --> 00:52:44,716
so that if you get an artist
or a programmer who comes


1010
00:52:44,716 --> 00:52:47,906
into the project halfway that
they are not trying to figure


1011
00:52:47,906 --> 00:52:52,426
out what, you know,
file 73 is, you know.


1012
00:52:52,986 --> 00:52:55,586
And then we use underscores,
no spaces,


1013
00:52:55,656 --> 00:53:00,186
and then we pad our revision
by four because you never know


1014
00:53:00,186 --> 00:53:04,696
when you're going to have 9,999
versions of that file especially


1015
00:53:04,696 --> 00:53:05,766
when you're-- and seriously,


1016
00:53:05,766 --> 00:53:07,046
especially when you're
doing animation.


1017
00:53:07,406 --> 00:53:12,126
You're going to have a ton
of files in animations.


1018
00:53:12,196 --> 00:53:16,136
And then the file type at
the end is really important.


1019
00:53:16,136 --> 00:53:20,036
We go into finder for everybody
on the project and we turn on--


1020
00:53:20,226 --> 00:53:22,706
we expose the file
type at the end.


1021
00:53:22,706 --> 00:53:24,396
This seems simple but it's--


1022
00:53:24,526 --> 00:53:26,956
it really, really helps
when you're trying


1023
00:53:26,956 --> 00:53:29,056
to quickly identify
whether it's a PSD,


1024
00:53:29,056 --> 00:53:31,436
a PNG, a TXT, or whatever.


1025
00:53:31,436 --> 00:53:34,566
So, you know, agree on a
file naming convention,


1026
00:53:35,076 --> 00:53:37,116
you can use that if you want
to, but use one that works


1027
00:53:37,116 --> 00:53:41,286
for you but, you know, this is
also a great communication tool.


1028
00:53:41,286 --> 00:53:43,416
>> Lesson number four, have fun.


1029
00:53:44,356 --> 00:53:45,786
You're in the freaking
game industry.


1030
00:53:46,046 --> 00:53:50,956
[laughs] If you're not having
fun making the game then you're


1031
00:53:50,956 --> 00:53:53,856
going to make a rotten game
unless one of the big things


1032
00:53:53,856 --> 00:53:55,776
that we differentiate
ourselves on is that Spencer


1033
00:53:55,776 --> 00:53:57,616
and I are in the game industry.


1034
00:53:58,056 --> 00:53:59,896
I don't work in the game
industry, I never worked


1035
00:53:59,896 --> 00:54:04,016
in my life and that's what
we do every single day.


1036
00:54:05,336 --> 00:54:06,456
So, let's go over
our lessons again.


1037
00:54:07,376 --> 00:54:10,046
Just because it's a 2D
Sprite engine doesn't mean


1038
00:54:10,046 --> 00:54:12,806
that you make 2D games, we
touched the tip of the iceberg


1039
00:54:12,806 --> 00:54:14,216
with what we can
do with Sprite Kit.


1040
00:54:14,476 --> 00:54:16,886
We could have made it complex
3D game with [inaudible]


1041
00:54:16,886 --> 00:54:18,266
and it would have been awesome.


1042
00:54:19,176 --> 00:54:20,836
>> Physics is much more useful


1043
00:54:20,836 --> 00:54:23,246
than for just drawing
birds epics


1044
00:54:23,596 --> 00:54:25,786
and programmer art is beautiful.


1045
00:54:26,316 --> 00:54:31,396
I-- really, use your
placeholders with pride


1046
00:54:31,736 --> 00:54:34,496
and give them to your artist


1047
00:54:34,496 --> 00:54:36,726
so that they can understand
what to do correctly.


1048
00:54:36,726 --> 00:54:40,656
And as far as the less is
more, we've been talking


1049
00:54:40,656 --> 00:54:47,076
about that a lot, see how
you can get them the fastest


1050
00:54:47,076 --> 00:54:52,386
running, least, you know,
quickest booting game


1051
00:54:52,656 --> 00:54:55,026
that you possibly can and
make it look super amazing


1052
00:54:55,026 --> 00:54:58,336
because if you can get
a really cool effect


1053
00:54:58,406 --> 00:55:03,336
or really great looking game out
of just hardly any resource used


1054
00:55:03,336 --> 00:55:07,756
at all, you know, well first off
you're amazing and second thing,


1055
00:55:07,756 --> 00:55:09,666
all you have to worry about
is awesome game design.


1056
00:55:10,536 --> 00:55:11,736
So, thank you very much.


1057
00:55:12,246 --> 00:55:14,276
>> Thank you Graeme,
and Spencer.


1058
00:55:15,416 --> 00:55:17,626
So, lastly I want to
talk about how to build,


1059
00:55:18,056 --> 00:55:20,886
not only use Sprite Kit as
part of your game runtime,


1060
00:55:20,936 --> 00:55:24,396
but build awesome game tools
to improve it in a recent time.


1061
00:55:25,046 --> 00:55:28,026
What if we decide to take
Adventure to the next level?


1062
00:55:28,756 --> 00:55:31,636
What if we want multiple level
support, currently is one level.


1063
00:55:32,116 --> 00:55:35,436
What if we want to add
save and load game support


1064
00:55:35,436 --> 00:55:36,396
so that the user doesn't have


1065
00:55:36,396 --> 00:55:39,016
to spend [inaudible]
30 minutes just playing


1066
00:55:39,016 --> 00:55:39,906
and finishing the game.


1067
00:55:40,586 --> 00:55:43,516
And what if we want to build
this more sophisticated


1068
00:55:43,516 --> 00:55:47,176
and reusable actions for
every single different effects


1069
00:55:47,526 --> 00:55:48,216
for your characters?


1070
00:55:49,516 --> 00:55:53,226
So, Sprite Kit, every single
SKNodes support NSCoding


1071
00:55:53,376 --> 00:55:55,406
and NSCopying, so what


1072
00:55:55,406 --> 00:55:58,946
that means every single node
can be serialize and deserialize


1073
00:55:59,046 --> 00:56:00,566
to the disk or to the iCloud


1074
00:56:00,646 --> 00:56:02,356
over the network,
however you want.


1075
00:56:02,356 --> 00:56:08,586
So, we can implement essentially
a save/load game logic using one


1076
00:56:08,586 --> 00:56:09,786
line of code.


1077
00:56:10,336 --> 00:56:12,126
So, let's look at the
serialization API.


1078
00:56:12,726 --> 00:56:13,986
It's quick and easy.


1079
00:56:14,056 --> 00:56:18,116
All you have to do is use
NSKeyedArchiver parsing any


1080
00:56:18,116 --> 00:56:22,996
SKNode, you get NSData blob and
from them on, you can do write


1081
00:56:22,996 --> 00:56:24,436
to disk, send it to the cloud


1082
00:56:25,686 --> 00:56:28,246
or that the serialization
is just the reverse.


1083
00:56:28,426 --> 00:56:32,676
Getting NSData blob, past
to the NSKeyedUnarchiver


1084
00:56:32,676 --> 00:56:35,786
and therefore you have the
corresponding SKNode instance.


1085
00:56:36,326 --> 00:56:41,376
So to build Adventure, in this
case, Adventure level editor,


1086
00:56:41,376 --> 00:56:45,056
we create a level editor in
Mac OS X using Sprite Kit.


1087
00:56:45,056 --> 00:56:51,096
If you're able to add an
overview, overlay view on top,


1088
00:56:51,096 --> 00:56:53,196
you can place your
level tiles on top


1089
00:56:53,196 --> 00:56:57,176
and also use the overlay view
to receive any of the user input


1090
00:56:57,176 --> 00:56:58,986
as well as the mouse
manipulations.


1091
00:56:59,306 --> 00:57:01,536
So if user drag and drop
some tiles on there,


1092
00:57:01,536 --> 00:57:03,766
you can make it the
direct manipulation


1093
00:57:03,766 --> 00:57:05,196
to the underlying SKNode.


1094
00:57:05,476 --> 00:57:08,876
And once everything is properly
placed, you can serialize now


1095
00:57:08,926 --> 00:57:10,486
to the scene and
essentially just load


1096
00:57:10,486 --> 00:57:13,876
that at runtime therefore
you have your game level


1097
00:57:13,876 --> 00:57:17,936
and you don't have to use change
some integer, recompile, and,


1098
00:57:17,936 --> 00:57:20,856
oh, I'm off by 50 pixels, you
don't have to any of that.


1099
00:57:22,186 --> 00:57:24,056
Custom Actions also
serialize well too.


1100
00:57:24,466 --> 00:57:26,066
Imagine we're building
a golf game.


1101
00:57:26,516 --> 00:57:31,846
So here, I want to simulate, OK,
when the golf club hit the ball,


1102
00:57:31,936 --> 00:57:32,576
what's going to happen?


1103
00:57:33,226 --> 00:57:35,866
What if I-- the first thing I
want to do is apply some sort


1104
00:57:35,866 --> 00:57:37,366
of an impulse to
make the ball fly.


1105
00:57:38,316 --> 00:57:41,256
And second, I want to play some
task effects that play that,


1106
00:57:41,566 --> 00:57:43,146
wait for all the
particles to finish,


1107
00:57:43,986 --> 00:57:45,346
and it will remove
that from the scene.


1108
00:57:45,546 --> 00:57:49,166
And in the meantime when in
parallel when the ball hit--


1109
00:57:49,166 --> 00:57:51,496
when the club hit the ball,
you will hear sound effects


1110
00:57:52,056 --> 00:57:55,296
and maybe way with
the ball is airborne


1111
00:57:55,296 --> 00:57:58,116
and then we'll play a task
trail for beginners to learn


1112
00:57:58,116 --> 00:58:00,776
from their mistakes, "Hey,
this how far I'm hitting


1113
00:58:00,776 --> 00:58:02,256
and this is the projectile
for that."


1114
00:58:02,696 --> 00:58:06,386
And if I want to build
all of these, this logic,


1115
00:58:06,386 --> 00:58:09,486
I want to use it in game
for every single time


1116
00:58:09,546 --> 00:58:11,646
when the club hit
the ball, I'll have--


1117
00:58:11,896 --> 00:58:15,416
we can build this in code by
having a sequence fall away bat


1118
00:58:15,416 --> 00:58:19,246
of groups, it's about
20 lines of codes.


1119
00:58:19,396 --> 00:58:23,066
But if you want to tune
that, the easiest way is


1120
00:58:23,066 --> 00:58:26,156
to use serialization API
for SKActions as well.


1121
00:58:26,636 --> 00:58:29,426
So, SKActions itself is
serializable as well.


1122
00:58:29,816 --> 00:58:32,096
When-- As soon as it's being
assigned to any SKNote,


1123
00:58:32,336 --> 00:58:34,856
it will be kicking off
from the beginning.


1124
00:58:35,586 --> 00:58:40,056
It's-- As soon as you assign
the action to the SK node,


1125
00:58:40,056 --> 00:58:44,326
it copies on write and
when actions are completed,


1126
00:58:44,326 --> 00:58:45,116
it will be finished.


1127
00:58:46,126 --> 00:58:48,346
And the last section I
want to quickly touch base


1128
00:58:48,346 --> 00:58:50,816
about the best practices
of using Sprite Kit.


1129
00:58:51,656 --> 00:58:55,476
Number one, we will recommend
you to use UIKit and AppKit


1130
00:58:55,476 --> 00:58:57,696
if you need a complex
layout for your text.


1131
00:58:58,356 --> 00:59:02,826
So, we do provide a SKLabelNode
for a one line that UI allow you


1132
00:59:02,826 --> 00:59:06,656
to animate that before any
complex constraints as well


1133
00:59:06,656 --> 00:59:09,226
as with the height adjustment
where Holly [phonetic] recommend


1134
00:59:09,226 --> 00:59:11,656
to use AppKit or UIKit.


1135
00:59:11,866 --> 00:59:14,736
So, just like any other
GL view, as soon as OS X,


1136
00:59:14,736 --> 00:59:16,026
if you enable layer-backed,


1137
00:59:16,116 --> 00:59:17,906
you automatically get
all these benefits.


1138
00:59:18,566 --> 00:59:21,906
And one thing I like to point
out is in OS X, I'm sorry,


1139
00:59:22,396 --> 00:59:26,356
Xcode 5, we provide a major
update to Interface Builder.


1140
00:59:26,666 --> 00:59:29,686
So if you want to design
your UI with the pipe--


1141
00:59:29,686 --> 00:59:31,536
breaking at the part
into different flows.


1142
00:59:31,536 --> 00:59:33,206
For example here,
how main screen goes


1143
00:59:33,256 --> 00:59:35,476
to character selection
screen followed by going


1144
00:59:35,476 --> 00:59:38,176
to weapon selection,
you can totally design


1145
00:59:38,176 --> 00:59:40,286
that using Storyboard
inside Xcode.


1146
00:59:40,866 --> 00:59:43,936
And now, how do we improve
your iteration time?


1147
00:59:44,646 --> 00:59:48,726
So, we want to integrate
Sprite Kit inside your code--


1148
00:59:48,726 --> 00:59:50,036
with your game code
so you can use


1149
00:59:50,036 --> 00:59:52,406
that to build your level
editor, if you do action editor,


1150
00:59:52,406 --> 00:59:54,906
you can use the particle
editor to edit your particles


1151
00:59:54,906 --> 00:59:57,706
at the Sprite Kit building
Texture Atlas generator


1152
00:59:57,706 --> 00:59:57,976
is great.


1153
00:59:58,406 --> 01:00:01,646
You just drag a folder in
and you have, therefore,


1154
01:00:01,646 --> 01:00:03,236
you have your Texture Atlas.


1155
01:00:04,806 --> 01:00:09,096
In terms of performance tips,
we provide a building stat


1156
01:00:09,146 --> 01:00:10,756
to show you how many
draw calls as well


1157
01:00:10,756 --> 01:00:13,026
as how many SKNotes are
being rendered on screen


1158
01:00:13,026 --> 01:00:14,666
as you can see from
one of my examples.


1159
01:00:15,056 --> 01:00:17,196
We'd like to keep
the node count low


1160
01:00:17,196 --> 01:00:19,296
for node that's no
longer visible.


1161
01:00:19,696 --> 01:00:22,526
You can remove that,
but Sprite Kit does cull


1162
01:00:22,526 --> 01:00:25,896
out invisible node, but
there's the additional


1163
01:00:25,896 --> 01:00:27,606
if statement that we go through.


1164
01:00:27,796 --> 01:00:30,196
But if you know ahead of
time, the object is going


1165
01:00:30,196 --> 01:00:32,536
to be no longer visible,
feel free to remove that.


1166
01:00:33,296 --> 01:00:37,186
CIFilters are expensive if you
apply them to a full screen.


1167
01:00:37,676 --> 01:00:40,856
So, we do provide a
property called [inaudible]


1168
01:00:40,856 --> 01:00:45,226
so that this we-- the
result will be cached


1169
01:00:45,436 --> 01:00:47,926
into a frame buffer
so that will be reused


1170
01:00:47,926 --> 01:00:48,986
for the following frames.


1171
01:00:49,476 --> 01:00:53,776
Also, we like to talk
about organizing your games


1172
01:00:53,846 --> 01:00:54,886
into different scenes.


1173
01:00:55,136 --> 01:01:00,086
Once if you treat scenes as
the fundamental building block


1174
01:01:00,146 --> 01:01:03,256
for your games, you can
plan ahead, OK, how do I--


1175
01:01:03,496 --> 01:01:05,416
do transitions from
scene A to scene B,


1176
01:01:05,416 --> 01:01:09,266
from UIView into the game
view, from Game to Pause menu,


1177
01:01:09,686 --> 01:01:11,056
you can do all these transitions


1178
01:01:11,056 --> 01:01:12,756
and make your flow
much, much easier.


1179
01:01:12,756 --> 01:01:16,226
So and-- that's the
end of the session.


1180
01:01:16,226 --> 01:01:17,566
For any questions or feedback,


1181
01:01:17,666 --> 01:01:20,336
please contact our
evangelist, Allan Schaffer.


1182
01:01:20,336 --> 01:01:22,406
I'd like to point
out for those of you


1183
01:01:22,406 --> 01:01:24,106
who have missed the
introduction to Sprite Kit,


1184
01:01:24,466 --> 01:01:27,416
there's online videos that's
going to be available tomorrow,


1185
01:01:27,416 --> 01:01:29,286
and have a great WWDC 2013.


1186
01:01:29,786 --> 01:01:36,420
[Applause]

