-
Notifications
You must be signed in to change notification settings - Fork 1
/
output.html
2885 lines (2807 loc) · 340 KB
/
output.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<p><embed src="images/cover_no_badge.pdf" /></p>
<h1 id="about-this-book">About this Book</h1>
<p>Thanks a lot for purchasing a copy of <em>Learn 2D iPhone Game Development with SpriteBuilder, Cocos2D and Swift</em>. Over the last one and a half years I’ve enjoyed working with <span>SpriteBuilder</span> and <span>Cocos2D</span> while creating various tutorials for <a href="makeschool.com" class="uri">makeschool.com</a>.</p>
<p>Why did I decide to write this book? While writing tutorials, I discovered my passion for diving into details of the newly designed <span>Cocos2D</span> 3.0 API and making my acquired knowledge available to a wide audience - many readers have reached out to me, pointing to awesome projects that they have built based on our tutorials.</p>
<p>After this initial success I created the first version of the official documentation for <span>SpriteBuilder</span> and <span>Cocos2D</span>: <a href="https://www.makeschool.com/docs/#!/cocos2d/1.2/overview" class="uri">https://www.makeschool.com/docs/#!/cocos2d/1.2/overview</a>. As a developer who has often struggled through adopting new frameworks, I truly believe that good documentation is essential for the success of a product for software developers.</p>
<p>This book fits neatly between the documentation and the tutorials we provide on <a href="makeschool.com" class="uri">makeschool.com</a>. It covers many aspects of the frameworks in depth while providing you with a practical step-by-step guide on building an iPhone game that is available on the App Store.</p>
<p>I hope this book helps you getting started with building amazing games!</p>
<h2 id="who-this-book-is-for">Who This Book Is for</h2>
<p>This book should be ideal for intermediate to advanced developers that have previous experience with any object oriented programming language.</p>
<p>This book does not teach programming in general, or the <em>Swift</em> programming language from scratch! However, I don’t assume you have any previous knowledge in game programming.</p>
<p>Besides that, this book focuses strongly on <span>SpriteBuilder</span>, <span>Cocos2D</span> and 2D game programming concepts.</p>
<p>If you have experience in other programming languages, you will easily be able to pick up Swift as you read through this book. Every once in a while we will also discuss individual language features in more detail.</p>
<p>If you want a formal introduction to the Swift programming language, Apple’s book is the best reference: <a href="https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11" class="uri">https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11</a></p>
<h2 id="what-this-book-covers">What This Book Covers</h2>
<p>This book covers most of the core features of <span>SpriteBuilder</span> and <span>Cocos2D</span>, as well as many concepts of 2D game programming. In many chapters I discuss details about the <em>Swift</em> programming language and also dive into aspects of good code design.</p>
<p>By reading this book you should get a very good idea of the <em>big picture</em> of 2D game development for iOS.</p>
<p>One large topic is not covered in this book: the <span>Cocos2D</span> physics engine. I decided to leave it out, because it is a fairly large topic that is already very well covered through Steffen Itterheim’s <em>Learn SpriteBuilder for iOS Game Development</em> book. We also have an extensive physics based tutorial on the Make School website: <a href="https://www.makeschool.com/tutorials/getting-started-with-spritebuilder/" class="uri">https://www.makeschool.com/tutorials/getting-started-with-spritebuilder/</a>.</p>
<p>I promise, after reading this book you will easily be able to pick up the physics features of <span>SpriteBuilder</span> and <span>Cocos2D</span> through our tutorial or the official documentation.</p>
<p>Here’s a breakdown of the entire book by chapters:</p>
<p><strong>Chapter 1 - About this Book</strong>This chapter discusses the structure of the book. It introduces different conventions and gives advice on how to get the most value out of the book.</p>
<p><strong>Chapter 2 - Introduction to SpriteBuilder and Cocos2D</strong>Throughout this chapter you will build a first very simple game and learn about essential Cocos2D, SpriteBuilder and general 2D game programming concepts such as scene graphs, code connections and bounding boxes.</p>
<p><strong>Chapter 3 - Asset Handling and Basic Game Mechanics</strong>In this chapter you will start building the “Falling Food!” game on which you will work throughout the rest of the book. Chapter 3 will teach you all about asset handling with SpriteBuilder and Cocos2D. Learn how to integrate sprites and audio assets into your games. You will also learn how to use the update loop to implement object movement.</p>
<p><strong>Chapter 4 - User Interaction</strong>Learn how to implement a drag and drop mechanism. You will also implement the core game mechanic of the game: catching objects. Since this game does not use the physics engine you will learn how to implement physical behaviour. You will also get to know details about Cocos2D’s touch handling API.</p>
<p><strong>Chapter 5 - Scene Graphs, Node Transforms and State Machines</strong>Learn how to incorporate a state machine into game development. You will also get to know details on affine transformations and how they are used to in Cocos2D to implement node hierarchies. Lastly you will learn about the rendering order in Cocos2D and how to use it to create a 3D feel in your 2D game.</p>
<p><strong>Chapter 6 - User Interfaces and Implementing Multiple Game Modes modes</strong>The largest chapter in the book. Learn how to implement a level select screen using a scroll view. Learn how to structure your game to support multiple game modes - without duplicating code. This chapter covers a variety of topics in UI programming and game programming patterns.</p>
<p><strong>Chapter 7 - Persisting Highscores</strong>A brief chapter that explains how to build a simple highscore system with NSUserDefaults.</p>
<p><strong>Chapter 8 - Effects and Animations</strong>Learn how to use the powerful CCEffects API to add lighting effects to your game! You will also learn how to create particle effects. Dive deeper into SpriteBuilder’s and Cocos2D’s animation toolbox and polish the “Falling Food!” game.</p>
<p><strong>Chapter 9 - Where to Go from Here?</strong>This chapter wraps up your learning experience. Find out about additional resources on SpriteBuilder and Cocos2D.</p>
<h2 id="about-the-author">About the Author</h2>
<p><span>l</span><span>0.20</span> <img src="images/Chapter1/benji.png" alt="image" /></p>
<p>Hi! I’m Benjamin. I have four years of development experience on the iOS platform and two years of experience with Cocos2D. I have written the original SpriteBuilder and Cocos2D documentation as well as many successful tutorials on makeschool.com. I regularly give talks on iOS development topics and love teaching passionate developers at Make School. You can find me on Twitter (@benjaminencz) or simply reach out to me via email (me@benjamin-encz.de).</p>
<h2 id="how-to-read-this-book">How to Read This Book</h2>
<p>I recommend to read this book in order when you are reading it for the first time. In Chapter 3 we start working on a game that we complete throughout the book - adding features chapter by chapter. By building this game you will learn about <span>SpriteBuilder</span> and <span>Cocos2D</span> concepts and see them unfold in an actual project.</p>
<p>Once you revisit this book you will have an understanding of how the project evolves throughout the chapters. Then it will be easy to jump into individual parts of the book and use them as a reference.</p>
<p>If you already know the basics of <span>Cocos2D</span> and <span>SpriteBuilder</span> you can jump directly to Chapter 4.</p>
<h2 id="conventions-in-this-book">Conventions in This Book</h2>
<p>This book uses a few conventions to make reading it easier.</p>
<h3 id="info-boxes">Info Boxes</h3>
<p>Whenever I provide additional details on a topic that we just discussed, you will see a special info box:</p>
<p>[An info box] This information is interesting, but not essential.</p>
<h3 id="action-required">Action Required</h3>
<p>This book is very <em>hands on</em>. Whenever you are required to perform some sort of action, you will see a gray bar as an indicator:</p>
<p>Follow the instructions provided in these blocks!</p>
<p>The goal is to clearly separate the parts of the book that explain topics from the parts that require you to do something.</p>
<h2 id="source-code">Source Code</h2>
<p>All the source code shown throughout this book is available on a repository on Github: <a href="https://github.com/SpriteBuilder-Book/Code" class="uri">https://github.com/SpriteBuilder-Book/Code</a>.</p>
<p>In that repository you’ll find one project for each chapter in this book. Each project contains the <span>SpriteBuilder</span> project and source code for the specific progress of one chapter. Whenever you get stuck you can look up the solution in that repository.</p>
<h2 id="getting-involved">Getting Involved</h2>
<p>I would love to have your feedback and hear about issues you found in this book. You can report issues on this GitHub repository: <a href="https://github.com/SpriteBuilder-Book/Errata" class="uri">https://github.com/SpriteBuilder-Book/Errata</a>. And you can email me at any time with feedback or questions: me@benjamin-encz.de.</p>
<h1 id="introduction-to-spritebuilder-and-cocos2d">Introduction to <span>SpriteBuilder</span> and <span>Cocos2D</span> </h1>
<p>Now it’s time to dive into 2D Game Development! I don’t assume any previous knowledge, we will be discussing all the relevant concepts throughout this chapter.</p>
<p>Besides general 2D programming concepts, this chapter will introduce <span>SpriteBuilder</span> and <span>Cocos2D</span> - the Open Source tools that we will use throughout this book. <span>Cocos2D</span> is the game engine (or framework) and <span>SpriteBuilder</span> is a visual content editor for <span>Cocos2D</span>.</p>
<h2 id="installing-the-software">Installing the Software</h2>
<p>First things first. Let’s install the software used throughout this book. If you haven’t developed for iOS or Mac OS X before, you first need to download <span>Xcode</span>. The software is available on the <em>App Store</em>. You should find it when searching for the term <em><span>Xcode</span></em>:</p>
<div class="figure">
<img src="images/Chapter2/install_xcode.png" alt="Xcode on the Mac App Store" />
<p class="caption"><span>Xcode</span> on the Mac App Store</p>
</div>
<p>Next, you should install <span>SpriteBuilder</span>. <span>SpriteBuilder</span> comes bundled with the latest version of <span>Cocos2D</span>, so we don’t need to install these two tools separately.</p>
<p><span>SpriteBuilder</span> is also available on the <em>App Store</em>. You can find it by searching for <em>SpriteBuilder</em>. Note that you should always use the latest version of Mac OS X and <span>Xcode</span> together with <span>SpriteBuilder</span> (as of this writing MacOS X 10.10 and <span>Xcode</span> 6.3).</p>
<div class="figure">
<img src="images/cocos2d/setup/mac_appstore_install.png" alt="SpriteBuilder on the Mac App Store" />
<p class="caption"><span>SpriteBuilder</span> on the Mac App Store</p>
</div>
<p>After a couple of minutes the <span>SpriteBuilder</span> installation should be completed. Later throughout this chapter you will learn how to set up your first project.</p>
<h2 id="introduction-to-cocos2d">Introduction to <span>Cocos2D</span></h2>
<p>First, let us take a look at the features of <span>Cocos2D</span>. That will give you a basic understanding of which tasks you will hand off to the framework. Later on we will be discussing all of these features in detail:</p>
<dl>
<dt>Scene Graphs</dt>
<dd><p><span>Cocos2D</span> provides the concepts of scenes and nodes. Everything that is rendered to the screen is part of a hierarchical <em>scene graph</em>. Instead of performing custom drawing code you define what your scene looks like by providing a scene graph and <span>Cocos2D</span> will render it for you.</p>
</dd>
<dt>Rendering Engine</dt>
<dd><p>When using <span>Cocos2D</span> you don’t need to write your own rendering code. <span>Cocos2D</span> provides a rendering engine built on top of OpenGL ES.</p>
</dd>
<dt>Action System</dt>
<dd><p>A sophisticated action system allows you to define movements of objects and animations instead of writing a lot of custom code.</p>
</dd>
<dt>Physics Engine</dt>
<dd><p>The <span>Cocos2D</span> physics engine automatically calculates movements of objects, collisions and more.</p>
</dd>
<dt>Node Library</dt>
<dd><p><span>Cocos2D</span> provides a large set of nodes as part of the framework. Nodes can be used to represent images, UI elements, solid colors, etc.</p>
</dd>
</dl>
<p>There are many more features - but this brief outline shows the most important. This should help you see why almost all game developers these days use game engines instead of building all of these features from scratch.</p>
<p>Let’s take a closer look at how <span>Cocos2D</span> works.</p>
<h3 id="the-cocos2d-technology-stack">The <span>Cocos2D</span> Technology Stack</h3>
<p><span>Cocos2D</span> is built on top of OpenGL ES 2.0 (and it has recently added experimental support for Apple’s <em>Metal</em> Framework). If you have ever written OpenGL code before, you know that it takes a lot of code to render even the most primitive scenes. OpenGL is a fairly low level framework that gives the graphics programmer a lot of control over how and when certain tasks are performed - more control then you need for most 2D games. <span>Cocos2D</span> abstracts all of these tasks for you.</p>
<p>While <span>Cocos2D</span> makes it easy to mix in custom OpenGL code, many <span>Cocos2D</span> developers write entire games without writing any OpenGL code at all.</p>
<p>The following diagram shows which technologies are used by <span>Cocos2D</span>:</p>
<div class="figure">
<img src="images/cocos2d/TechnologyStack.png" alt="Cocos2D Technology Stack" />
<p class="caption"><span>Cocos2D</span> Technology Stack</p>
</div>
<p>The goal of a game engine like <span>Cocos2D</span> is that the game developer doesn’t have to get in touch with rendering at all. Instead a developer defines which scenes exist in a game, which nodes are part of these scenes and which size, position and appearance these nodes have and <span>Cocos2D</span> will use OpenGL to render these scenes for him.</p>
<p>In order to provide this functionality <span>Cocos2D</span> consists of variety of classes - some important ones will be discussed in this chapter. All <span>Cocos2D</span> classes use the <em>CC</em> prefix (<span>CCScene</span>, <span>CCNode</span>, etc.).</p>
<p>When working with a 2D game engine for the first time, you will be introduced to a whole set of new terminology. We have already talked about nodes and scenes but we haven’t discussed what these terms mean. We will now start discussing the most important ones.</p>
<h3 id="scenes">Scenes</h3>
<p>Scenes are the basic building blocks of all <span>Cocos2D</span> games, they are the highest level on which game content can be structured. Each scene in <span>Cocos2D</span> is a full-screen canvas. For every full-screen section of your game you will use <em>one</em> scene.</p>
<p>Here’s an illustration from the <span>Cocos2D</span> documentation:</p>
<div class="figure">
<img src="images/Chapter1/scenegraph.png" alt="A game with 3 scenes" />
<p class="caption">A game with 3 scenes</p>
</div>
<p>You can see that the game consists of the start scene, the gameplay scene and the game over scene.</p>
<p>Scenes are represented by the <span>CCScene</span> class. Another important <span>Cocos2D</span> class for scene handling is <span>CCDirector</span>. As shown in the image above, the <span>CCDirector</span> class is responsible for deciding which scene is currently active in the game (<span>Cocos2D</span> only allows one active scene at a time). Whenever a developer wants to display a scene or transition between two scenes she needs to use the <span>CCDirector</span> class.</p>
<p>This means creating and displaying a new scene is a two step process:</p>
<ol>
<li><p>Create a new instance of <span>CCScene</span></p></li>
<li><p>Tell the <span>CCDirector</span> to display this new scene</p></li>
</ol>
<p>You will learn a lot more about this down the road, but the important bottom line is: <em>Scenes are the highest level of structure in your game and a class called <span>CCDirector</span> decides which scene is currently displayed</em>.</p>
<h3 id="nodes">Nodes</h3>
<p>Everything that is visible in your <span>Cocos2D</span> game (and a couple of invisible objects) are <em>nodes</em>. Nodes are used to structure the content of a scene. Every node can have other nodes as its children. <span>Cocos2D</span> provides a huge amount of different node types. Every node type is a subclass of <span>CCNode</span>.</p>
<p>Most nodes are used to represent an object on the screen (an image, a solid color, an UI element, etc.), a few other nodes are only used as containers that group other nodes. All nodes have a size, position and children (and many other properties which are less important for us right now). Here are some of the popular node types of <span>Cocos2D</span>:</p>
<dl>
<dt>CCSprite</dt>
<dd><p>represents an image or an animated image. Used for characters, enemies, etc.</p>
</dd>
<dt>CCColorNode</dt>
<dd><p>a node that displays one plain color.</p>
</dd>
<dt>CCLabelTTF</dt>
<dd><p>a node that can represent text in any TTF font.</p>
</dd>
<dt>CCButton</dt>
<dd><p>an interactive node that can receive touches.</p>
</dd>
</dl>
<p>Nodes and their children form a scene graph. The concept of a scene graph isn’t unique to <span>Cocos2D</span>; it is a common concept of 2D and 3D graphics. A scene graph is a hierarchy of many different nodes.</p>
<h3 id="scene-graphs">Scene Graphs</h3>
<p>Let’s take a look at simple example of a <span>Cocos2D</span> scene:</p>
<div class="figure">
<img src="images/cocos2d/SceneGraph.png" alt="Cocos2D Scene Graph" />
<p class="caption"><span>Cocos2D</span> Scene Graph</p>
</div>
<p>The image above shows <span>Cocos2D</span>’s rendering output for a scene alongside with its scene graph. The root node of the scene graph is a <span>CCScene</span>. The first child is a <span>CCNode</span> with two children of type <span>CCLabelTTF</span>. This <span>CCNode</span> is the first example of a grouping node: it groups the score caption label and the label displaying the actual score.</p>
<p>Instances of <span>CCNode</span> don’t have any appearance they are solely used to group other nodes. Throughout this book you will learn that it often makes sense to group nodes under certain parent nodes. The main reason is that all children are placed <em>relative</em> to their parents. So if we would want to move the scoreboard of the example above to the top right corner, we would only have to move the parent node instead of both child nodes. As you can imagine this becomes even more relevant in games that have ten or more entries in their scoreboard.</p>
<p>[Structuring Nodes] Always group nodes that logically belong together under one parent node. That will save you a lot of time when you change the layout of your scene.</p>
<p>The other two objects in the scene graph are simpler. Both are CCSprites, one represents the background image the other one the main character.</p>
<p>For some games scene graphs can get very complex and include hundreds of different nodes. The key takeaways for now are:</p>
<ol>
<li><p>Every node in <span>Cocos2D</span> can have children</p></li>
<li><p>A hierarchy of nodes is called a scene graph</p></li>
<li><p>Children of nodes are placed relative to their parents - often it is useful to group nodes that are moved together under one parent</p></li>
<li><p><span>Cocos2D</span> renders the screen output based on a scene graph that you provide</p></li>
</ol>
<p>As you can see nodes are the most important building block of <span>Cocos2D</span> games - they are used to build everything that is visible in your game. Because it is so important to understand how nodes work in <span>Cocos2D</span>, we will take a look at the most important properties and methods that <span>CCNode</span> provides.</p>
<h3 id="Introduction_CCNode">An Introduction to CCNode</h3>
<p>Every visible object in your game will be a subclass of <span>CCNode</span>. Because you use nodes to build and arrange your scenes, it is important to understand how nodes are positioned and how positions of nodes can be accessed. Let’s take a look at the most relevant properties and methods to access and change size and position of a <span>CCNode</span>:</p>
<dl>
<dt>contentSizeInPoints</dt>
<dd><p>the size of this node in points</p>
</dd>
<dt>positionInPoints</dt>
<dd><p>the position of this node in points, expressed relative to the parent of this node</p>
</dd>
<dt>anchor point</dt>
<dd><p>the anchor point is the center point for rotations and the reference point for positioning this node</p>
</dd>
<dt>boundingBox</dt>
<dd><p>the bounding box is a rectangle that encloses a node. You can only read it but not set it</p>
</dd>
</dl>
<p>The <em>contentSizeInPoints</em> and <em>positionInPoints</em> properties express the size and the position of a <span>CCNode</span>. If you have worked with UI frameworks before, you should be familiar with similar properties.</p>
<p>The <em>bounding box</em> and the <em>anchor point</em> however, are concepts that are more specific to game development. The bounding box is a rectangle that encloses the entire node. You will see an example of a bounding box in the next diagram. The anchor point is relevant for positioning and rotating nodes.</p>
<p>Let’s take a look at how anchor points influence positioning first. We know that the position of a node is expressed relative to its parent. More specifically, every node position in <span>Cocos2D</span> is expressed from the <em>position reference corner</em> of the parent to the anchor point of the <span>CCNode</span>. Here’s a visual example in which a bear node is placed relative to a background node:</p>
<div class="figure">
<img src="images/cocos2d/ccnode/NodePositioning.png" alt="CCNode positioning example" />
<p class="caption"><span>CCNode</span> positioning example</p>
</div>
<p>As you can see, the <em>anchor point</em> and the <em>position reference corner</em> influence the position of a node. The anchor point can have any value between (0, 0), representing the bottom left corner of a node and (1,1), representing the top right corner of a node. In the example above the bear has an anchor point of (0.5, 0.5) which is at the center of the bear. By choosing an anchor point of (0.5, 0.5), the <em>center</em> of the bear will be positioned at (215, 285). If we would choose an anchor point of (0,0) the <em>bottom left</em> corner of the bear would be positioned at (215, 285).</p>
<p>The <em>position reference corner</em> lets us define from which of the four corners of the parent node we are expressing the position of a node. In the example above the top left corner is the <em>position reference corner</em>. We will discuss how to use position reference corners when we start creating games that shall work on multiple screen sizes.</p>
<p>The anchor point is not only important for the positioning of a node. It has a second important function - it represents the center of rotation for a <span>CCNode</span>. Every <span>CCNode</span> rotates around its own anchor point. Here’s an example of rotating the bear node with two different anchor points:</p>
<div class="figure">
<img src="images/cocos2d/ccnode/Rotation.png" alt="CCNode positioning example" />
<p class="caption"><span>CCNode</span> positioning example</p>
</div>
<p>There is a lot more to learn about <span>CCNode</span>. For now our only goal is to get a basic understanding of how <span>Cocos2D</span> games are structured and what the most important parts of <span>Cocos2D</span> are.</p>
<p>You now know that <span>Cocos2D</span> game are structured into scenes. You know that everything visible in your game is a <span>CCNode</span> and that every <span>CCNode</span> can have multiple children. You also got a basic understanding of how nodes are positioned in <span>Cocos2D</span>.</p>
<p>Now that you have that basic understanding, we will take a look at a second tool which we will be using throughout this book: <span>SpriteBuilder</span>.</p>
<h2 id="introduction-to-spritebuilder">Introduction to <span>SpriteBuilder</span></h2>
<p>So far you have learned the basics of the game engine that we will use. Now we will take a look at a tool called <span>SpriteBuilder</span> which we will use to create the majority of our game content. The main purpose of <span>SpriteBuilder</span> is to provide a visual editor for the creation of scenes, animations and more. For most games you will create some basic mechanics in code (enemy movement, score mechanism, etc.) but you will create most of your game content in <span>SpriteBuilder</span> since it is a lot easier to create levels, menus and other scenes in an editor that provides you with a live preview instead of putting these scenes together in code.</p>
<p>If you have never used <span>SpriteBuilder</span> before, it is very important to understand that everything that can be implemented in <span>SpriteBuilder</span> can also be implemented in code. <span>SpriteBuilder</span> is not part of the game engine, it simply allows you to configure <span>Cocos2D</span> scenes and nodes in an editor instead of configuring them in code.</p>
<h3 id="creating-a-first-project">Creating a First Project</h3>
<p>To dive into the features of <span>SpriteBuilder</span> we will create our first project!</p>
<ol>
<li><p>Create a new project by opening SpriteBuilder and selecting <em>File > New > Project...</em>:</p>
<p><img src="images/cocos2d/setup/spritebuilder_new_project.png" alt="image" /></p></li>
<li><p><span>SpriteBuilder</span> will ask for a name and a location for the new project. Name it <em>HelloSB</em>. Also make sure to choose <em>Swift</em> as the primary project language:</p>
<p><img src="images/Chapter1/new_project_swift.png" alt="image" /></p></li>
</ol>
<p>After you create the project the folder structure should look similar to this:</p>
<div class="figure">
<img src="images/cocos2d/setup/project_structure.png" alt="SpriteBuilder project folder structure" />
<p class="caption"><span>SpriteBuilder</span> project folder structure</p>
</div>
<p>Every <span>SpriteBuilder</span> project is contained in a <em>.spritebuilder</em> folder. This folder stores all <span>SpriteBuilder</span> project files - along with an <span>Xcode</span> project.</p>
<p>[<span>SpriteBuilder</span> and Xcode] <span>SpriteBuilder</span> will create an <span>Xcode</span> project for every new project you create! The <span>Xcode</span> project will automatically contain the newest version of <span>Cocos2D</span> - very handy.</p>
<p>Later on you will learn more about how the <span>SpriteBuilder</span> project and the <span>Xcode</span> project work together. The general rule is that all code will be part of the <span>Xcode</span> project and most content creation will happen in the <span>SpriteBuilder</span> project.</p>
<h3 id="the-editor">The Editor</h3>
<p>When you have created your first <span>SpriteBuilder</span> project, you will see that the <span>SpriteBuilder</span> UI gets enabled. Let’s take a look at the different parts of the editor to get a better understanding of <span>SpriteBuilder</span>.</p>
<p>The <span>SpriteBuilder</span> interface is divided into 4 main sections:</p>
<p><img src="images/spritebuilder/spritebuilder_ui.png" alt="image" /></p>
<ol>
<li><p><em>Resource/Component Browser:</em> Here you can see the different resources and scenes you have created or added to your project. You can also select different types of Nodes and drag them into your scene.</p></li>
<li><p><em>Stage:</em> The stage will preview your current scene. Here you can arrange all of the nodes that belong to a scene.</p></li>
<li><p><em>Timeline:</em> The timeline is used to create animations within SpriteBuilder. It also displays the scene graph of the current scene.</p></li>
<li><p><em>Inspector:</em> Once you select a node in your scene, this detail view will display a lot of editable information about that node. You can modify positions, content (the text of a label, for example) and physics properties.</p></li>
</ol>
<p>Let’s take a closer look at some of the most important views.</p>
<h4 id="file-view">File View</h4>
<p>The first tab in the resource/component browser represents the <em>File View</em>. It lists all the <em>.ccb</em> files and resources that are part of the <span>SpriteBuilder</span> project:</p>
<p><img src="images/spritebuilder/spritebuilder_fileview.png" alt="image" /></p>
<p>In this view you can add new resources and restructure your project’s folder hierarchy.</p>
<h4 id="node-library">Node Library</h4>
<p>The third tab in the left view is the <span>Node Library</span>:</p>
<p><img src="images/spritebuilder/spritebuilder_nodeview.png" alt="image" /></p>
<p>This panel shows you all available node types you can use to construct your Gameplay scenes and menus. You will drag these nodes from this view to the stage in the center to add them to your scenes.</p>
<h4 id="inspector">Inspector</h4>
<p>The first tab of the Detail View (the right panel) is the Inspector. Once you have selected an object on your stage you can use this panel to modify many of its properties, like position and color:</p>
<p><img src="images/spritebuilder/spritebuilder_inspector.png" alt="image" /></p>
<h4 id="code-connections">Code Connections</h4>
<p>The second tab on the right panel let’s you manage code connections for your selected node. As mentioned previously the entire code for your games will be written as part of the <span>Xcode</span> project. This view allows you to create connections between the <span>Xcode</span> project and the <span>SpriteBuilder</span> project. For example you can set a custom Swift class for a node or you can select a method in your code that shall be called once a button in your scene is tapped. We will discuss the use of code connections extensively throughout this book.</p>
<p><img src="images/spritebuilder/spritebuilder_codeconnections.png" alt="image" /></p>
<h3 id="ccb-files"><span>CCB File</span>s</h3>
<p><span>CCB File</span>s are the basic building blocks of your <span>SpriteBuilder</span> project. Every scene in your game that is created with <span>SpriteBuilder</span> is represented by one <span>CCB File</span>. However <span>CCB File</span>s are not only used to create entire scenes - they are used to create any kind of scene graph. <span>SpriteBuilder</span> provides different kinds of document types depending on which type of scene graph you want to create. You get an overview of the available <span>CCB File</span> types when you create a new one, by selecting <em>New > File...</em> from the <em>File</em> menu in <span>SpriteBuilder</span>: [DocumentTypes]</p>
<p><img src="images/spritebuilder/new-ccb.png" alt="image" /></p>
<p>These are the different document types briefly explained:</p>
<dl>
<dt>Scenes</dt>
<dd><p>will fill the full screen size of the device.</p>
</dd>
<dt>Nodes</dt>
<dd><p>used primarily for grouping functionality.</p>
</dd>
<dt>Layers</dt>
<dd><p>are nodes with a content size. This is useful, for instance, when creating levels or contents for scroll views.</p>
</dd>
<dt>Sprites</dt>
<dd><p>used to create (animated) characters, enemies, etc.</p>
</dd>
<dt>Particles</dt>
<dd><p>is used to design particle effects.</p>
</dd>
</dl>
<p>You will get a good understanding when to use which type of <span>CCB File</span> once we get started with our example projects. The key takeaway is that <span>CCB File</span>s are used by <span>SpriteBuilder</span> to store an entire scene graph including size, positions and many other properties of all the nodes that you have added.</p>
<h3 id="Publish">How <span>SpriteBuilder</span> and <span>Xcode</span> Work Together</h3>
<p>I have mentioned how <span>SpriteBuilder</span> and <span>Xcode</span> integrate a couple of times briefly. In order to be a well versed and efficient <span>SpriteBuilder</span> game developer it is very important to understand the details of this cooperation.</p>
<p>When creating a <span>SpriteBuilder</span> project, <span>SpriteBuilder</span> will create and maintain a corresponding <span>Xcode</span> project. In <span>SpriteBuilder</span> you’ll create multiple <span>CCB File</span>s that describe the content of the scenes in your game. You will also add the resources that you want to use in your game and set up code connections to interact with the code in your <span>Xcode</span> project. <span>Xcode</span> will be the place where you add code to your project and from where you run the actual game.</p>
<p>Since <span>Xcode</span> is the tool that actually compiles and runs your game it needs to know about all the scenes and resources that are part of your <span>SpriteBuilder</span> project. Therefore <span>SpriteBuilder</span> has a <strong>publish</strong> functionality, provided by a button in the top left corner of the interface:</p>
<div class="figure">
<img src="images/spritebuilder/spritebuilder_publish_button.png" alt="Use the publish button to update your Xcode project with the latest changes in your SpriteBuilder project." />
<p class="caption">Use the publish button to update your <span>Xcode</span> project with the latest changes in your <span>SpriteBuilder</span> project.</p>
</div>
<p>Using that button, you publish your changes in your <span>SpriteBuilder</span> project to your <span>Xcode</span> project. Whenever you changed your <span>SpriteBuilder</span> project and want to run it you should hit this button before building the <span>Xcode</span> project. Alternatively you can use the shortkey <em>CMD + Shift + O</em>.</p>
<p>Here’s a diagram that visualizes how <span>SpriteBuilder</span> and <span>Xcode</span> work together:</p>
<div class="figure">
<img src="images/spritebuilder/spritebuilder_publishing.png" alt="SpriteBuilder creates and organizes a Xcode project for you. Adding all the resources and scenes you have created." />
<p class="caption"><span>SpriteBuilder</span> creates and organizes a <span>Xcode</span> project for you. Adding all the resources and scenes you have created.</p>
</div>
<p><span>CCB File</span>s created in <span>SpriteBuilder</span> store a scene graph; the hierarchy and positions of your nodes. When publishing a <span>SpriteBuilder</span> project the <span>CCB File</span>s and all other project resources are copied to your <span>Xcode</span> project. [CCBReader] When running the project in <span>Xcode</span> a class called CCBReader will parse your <span>CCB File</span>s and create the according <span>CCNode</span> subclasses to reconstruct the scene graph you have designed in <span>SpriteBuilder</span>.</p>
<p>If you would use <span>Cocos2D</span> without <span>SpriteBuilder</span> you would manually create instances of <span>CCNode</span>, <span>CCSprite</span>, etc. in code and add children to these nodes - essentially building the entire scene graph in code.</p>
<p>When using <span>SpriteBuilder</span> the CCBReader class will build this scene graph for you, based on the information stored in the <span>CCB File</span>s that you created in <span>SpriteBuilder</span>.</p>
<p>Another important part of information contained in <span>CCB File</span>s that we have not discussed in detail yet are <em>Code Connections</em>.</p>
<h3 id="CodeConnections">Code Connections</h3>
<p>Code connections are used to create links between your scenes in <span>SpriteBuilder</span> and your code in <span>Xcode</span>. There are three basic types of code connections:</p>
<dl>
<dt>Custom Classes</dt>
<dd><p>are an important information for the CCBReader. As mentioned previously the CCBReader builds the scene graph by creating different nodes based on the information in your <span>CCB File</span>. By default it will create an instance of <span>CCSprite</span> for every sprite you added in <span>SpriteBuilder</span> an instance of <span>CCNode</span> for every node you added, etc. Often however you will want to add custom behaviour to a node (for example a movement pattern for an enemy). Then you will have to use the <em>Custom Class</em> property to tell the CCBReader which class it should instantiate instead of the default one. Whichever class you enter here needs to be a subclass of the default class (e.g. a subclass of <span>CCSprite</span>). You will learn how to use this feature in the final project of this chapter!</p>
</dd>
<dt>Variable Assignments</dt>
<dd><p>If you have assigned a <em>Custom Class</em> you can use variables assignments to retrieve references to different nodes in the scene. For example a character might want a reference to its right arm node (a child of the character node) in order to move it.</p>
</dd>
<dt>Callbacks</dt>
<dd><p>are only available to UI elements like buttons and sliders. They allow you to decide which method should be called on which class once a user interaction occurs.</p>
</dd>
</dl>
<p>Now you should have an idea about what code connections are used for and which kinds exist. We will discuss the details of all types when we use them as part of our example projects.</p>
<h2 id="a-first-spritebuilder-project">A first <span>SpriteBuilder</span> project</h2>
<p>You have already created the <span>SpriteBuilder</span> project called <em>HelloSB</em>. Now we will start adding some content to it. The project built in this chapter will consist of two scenes one start screen and one game screen. In the game screen the user will be able to spawn randomly colored squares that rotate, by tapping on the screen.</p>
<div class="figure">
<img src="images/firstproject/first_project.png" alt="The project build throughout this chapter" />
<p class="caption">The project build throughout this chapter</p>
</div>
<p>By creating this project you will learn all of the following:</p>
<ul>
<li><p>Creating scenes in <span>SpriteBuilder</span></p></li>
<li><p>Creating code connections (callbacks, variable assignments and custom classes)</p></li>
<li><p>Switching between different scenes</p></li>
<li><p>Manipulating a scene graph from code (add/remove nodes, load CCB Files and add them to the scene)</p></li>
<li><p>Using the <span>Cocos2D</span> action system to create animations</p></li>
<li><p>Using the <span>Cocos2D</span> touch handling system to capture touches</p></li>
</ul>
<h3 id="setting-up-the-first-scene">Setting Up the First Scene</h3>
<p>Now it is time to open the <em>HelloSB</em> <span>SpriteBuilder</span> project. We want to add a <em>Start Button</em> to the first scene. When this button is tapped we want to switch to the second scene.</p>
<h4 id="positioning-the-first-button">Positioning the first button</h4>
<p>Start by adding a button to the first scene by following the three steps outlined below:</p>
<div class="figure">
<img src="images/firstproject/add_button.png" alt="The project build throughout this chapter" />
<p class="caption">The project build throughout this chapter</p>
</div>
<dl>
<dt>(1)</dt>
<dd><p>Open <em>MainScene.ccb</em> by double clicking it in the left resource pane. Then open the third tab in the left pane, the <em>Node Library</em>. Remember, this section shows you all the different node types supported by <span>SpriteBuilder</span>. Select the <em>Button</em> and drag it over to the stage, dropping it below the existing label. Dropping it on the stage will add this node to your scene. Another way of adding a node to a scene is dropping it to the timeline at the bottom of the screen - we will look at this later.</p>
</dd>
<dt>(2)</dt>
<dd><p>Make sure the button is selected, because we want to change some properties of it. Whenever you have selected a node the right pane will display all the properties you can edit. Navigate to the <em>Title</em> textfield in the property pane and change the title of the button to <em>Start Game</em>.</p>
</dd>
<dt>(3)</dt>
<dd><p>So far - so simple. Step number three will expose you to a very interesting feature of <span>SpriteBuilder</span>: the positioning system. It will allow you to not only use absolute positions but also positions that are relative to the size of the parent node. We want to center the button horizontally so we choose the position type for the X component to be <em>in percent of parent container</em> by selecting that option from the dropdown menu. Now we assign <em>50</em> as value, because that expresses the horizontal center of the parent container. Whichever screen this button will be displayed on, it will always be vertically centered (yes, even on an iPad)!</p>
</dd>
</dl>
<p>[Positioning System in <span>Cocos2D</span> and <span>SpriteBuilder</span>] [PositioningSystem] The positioning system in <span>Cocos2D</span> is designed from the ground up to make it easy to design scenes and user interfaces for different screen sizes and resolutions. The comfortable days where the 3.5-inch iPhone was the only available iOS device and defining layouts with absolute positions was acceptable are finally over. Today app and game developers face a variety of different devices and customers justifiably expect your software to work great on all of them. <span>Cocos2D</span> offers the following properties on <span>CCNode</span>s to allow developers to design their interfaces with great flexibility:</p>
<ul>
<li><p>Anchor Point</p></li>
<li><p>Reference Corner</p></li>
<li><p>Position Type</p></li>
<li><p>Size Type</p></li>
</ul>
<p>We will use the positioning system throughout multiple chapters in this book. If you want to learn more about dynamic layouts right away, you should read our tutorial: <a href="https://www.makeschool.com/tutorials/dynamic-layouts-with-spritebuilder-and-cocos2d-3-x/" class="uri">https://www.makeschool.com/tutorials/dynamic-layouts-with-spritebuilder-and-cocos2d-3-x/</a>.</p>
<p>Now the button is placed correctly. Next, we want to assign an action to it. When the button is tapped we want to transition to our second scene.</p>
<h4 id="setting-up-a-code-connection">Setting up a code connection</h4>
<p>Earlier you learned that <span>SpriteBuilder</span> has three types of code connections ([CodeConnections]). Now we will use one of them in our project - <em>Callbacks</em>. Callbacks are only available to nodes that allow for some sort of user interaction (this means they need to be subclasses of <span>CCControl</span>). Buttons, as well as Sliders and Text Fields are some of these types of nodes.</p>
<p>Select the button we have added to the scene earlier and select the second tab of the right pane:</p>
<div class="figure">
<img src="images/firstproject/button_callback.png" alt="Nodes that allow user interaction can use callback methods to connect to the code base of a game" />
<p class="caption">Nodes that allow user interaction can use callback methods to connect to the code base of a game</p>
</div>
<p>Inside the CCControll section you can see two options called <em>selector</em> and <em>target</em>. Here you can choose which method (selector) shall be called on which object (target) when this button is tapped by a user. As selector enter <span>startGame</span>. As target choose <em>Document Root</em>.</p>
<p>[Targets and Selectors] [target<sub>s</sub>elector] The concept of targets and selectors is part of design pattern widely used throughout the Cocoa framework (Target/Action pattern). A <em>selector</em> is a method name and a <em>target</em> is the object that shall receive this method. Further reading: <a href="https://developer.apple.com/library/ios/documentation/general/conceptual/Devpedia-CocoaApp/TargetAction.html" class="uri">https://developer.apple.com/library/ios/documentation/general/conceptual/Devpedia-CocoaApp/TargetAction.html</a></p>
<p>As you can see you cannot choose an arbitrary object to be the target of this callback, you can only choose between two different ones:</p>
<dl>
<dt>Document Root</dt>
<dd><p>The document root is the highest node within the current <span>CCB File</span>. The hierarchy of the <span>CCB File</span> is shown in the <span>SpriteBuilder</span> timeline:</p>
<p><img src="images/firstproject/documentroot_node.png" alt="image" /></p>
<p>If you select the document root as target, the <span>startGame</span> method will be called on the top level <span>CCNode</span>.</p>
</dd>
<dt>Owner</dt>
<dd><p>if you want the callback to call an object that is not part of your <span>CCB File</span> you can use the <em>owner</em> option. Later in this book you will learn how to set up an owner object for a <span>CCB File</span>.</p>
</dd>
</dl>
<p>For our button we have decided that the <span>startGame</span> method should be called on the document root when the button is tapped. Next, we will have to implement this <span>startGame</span> method within our document root. But to which <em>class</em> could we add this method? In order to find that out we need to understand the concept of <em>Custom Classes</em> .</p>
<p>Think about it - by default our document root is an instance of a plain <span>CCNode</span> class. Now we want to call a method called <span>startGame</span> on this object. Our problem: the <span>CCNode</span> class does not have a <span>startGame</span> method! This is where custom classes come to rescue us, they allow us to tell <span>SpriteBuilder</span> that our document root node should <strong>not</strong> be a plain <span>CCNode</span> but should be an instance of a class that we have created and implements our <span>startGame</span> method. To define a custom class for the document root you need to select the document root (the top-level <span>CCNode</span>) from the timeline and open the third tab in the right pane:</p>
<p><img src="images/firstproject/custom_class.png" alt="image" /></p>
<p>In the <em>Custom class</em> textfield a developer can enter a class name. The class entered here needs to be part of the <span>Xcode</span> project related to this <span>SpriteBuilder</span> project. As you can see every new <span>SpriteBuilder</span> project already comes with a custom class set up for the root node of <em>MainScene.ccb</em>. When the CCBReader loads this <span>CCB File</span> it will create an instance of <span>MainScene</span> instead of an instance of <span>CCNode</span>. Now our document root object is a <span>MainScene</span> object! That also means that we have saved the puzzle of where to add the code for the <span>startGame</span> method - it needs to be part of the <span>MainScene</span> class. The <span>MainScene</span> class is already part of the template <span>Xcode</span> project generated by <span>SpriteBuilder</span>.</p>
<p>Now that we have the connection set up, it is time to add some code.</p>
<p>[Requirements for Custom Classes] Every custom class has to be a subclass of the default class for a given node. For example, the default class for the <em>Sprite</em> node in <span>SpriteBuilder</span> is <span>CCSprite</span>. If a developer wants to set a custom class for a Sprite node, that class has to be a subclass of <span>CCSprite</span>. <strong>Why?</strong> <span>SpriteBuilder</span> expects custom classes to only <strong>add</strong> behaviour to a default class. All the functionality of the default class should remain available. If your custom class for a Sprite node doesn’t allow <span>SpriteBuilder</span> to set an image, because it is a subclass of <span>CCNode</span> the CCBReader and finally also you will run into problems!</p>
<h4 id="adding-code-to-a-spritebuilder-project">Adding Code to a <span>SpriteBuilder</span> project</h4>
<p>When creating games with <span>SpriteBuilder</span> we are always working with two tools. <span>SpriteBuilder</span> to create interfaces and scenes (our game content) and <span>Xcode</span> to add code (game mechanics, etc.). Now we will add our first few lines of code to the <span>MainScene</span> class.</p>
<p>It’s time to publish the changes in our <span>SpriteBuilder</span> project, so that they are available in our <span>Xcode</span> project.</p>
<ol>
<li><p>Use the publish button in the top left corner of the <span>SpriteBuilder</span> interface ([Publish]). Or use the shortkey: <em>Option + CMD + S</em>.</p></li>
<li><p>Open the <span>Xcode</span> project (it’s called <em>HelloSB.xcodeproj</em> and is located inside the <em>HelloSB.spritebuilder</em> folder). You can also use a shortcut provided by <span>SpriteBuilder</span>: CMD + Shift + O</p></li>
</ol>
<p>You will see that project contains two classes, <span>AppDelegate</span> and <span>MainScene</span>. As part of the template for new <span>SpriteBuilder</span> projects the <span>MainScene</span> class has already been created for you. For any subsequent custom classes you link in your <span>SpriteBuilder</span> project you will need to create the according classes in <span>Xcode</span> on your own.</p>
<p>Now it’s finally time to implement the <span>startGame</span> method.</p>
<p>Open the <em>MainScene.swift</em> and file and add the following method:</p>
<pre><code> func startGame() {
println("Start Game")
}</code></pre>
<p>For now we will simply use the <span>println</span> function to log a text to the console once the button is pressed, this is an easy way to check if our code connection is set up correctly.</p>
<p>[Displaying the console in <span>Xcode</span>] To display the console in <span>Xcode</span> select <em>View -> Debug Area -> Activate Console</em>.</p>
<p>Now, run the <span>Xcode</span> project by hitting the play button in the top left corner. You should check that you have selected <em>HelloSB</em> as target and are set up to run the app on a simulator (indicated by a device description, e.g. iPhone Retina, instead of a device name):</p>
<p><img src="images/firstproject/run_app.png" alt="image" /></p>
<p>Hitting the run button will compile your app and launch it on an iOS simulator. Once your app is launched, click on the start button and check the console for the log message. You should see something similar to this:</p>
<p><img src="images/firstproject/button_success_log.png" alt="image" /></p>
<p>You have successfully set up your first <span>SpriteBuilder</span> scene and have created a working code connection! Later on this button shall trigger a transition to the Gameplay scene. Before we can implement that we need to create the second scene in our <span>SpriteBuilder</span> project!</p>
<p>[Common errors with code connections] If you are not getting the expected result, check for all of these common errors:</p>
<ul>
<li><p>Have you published your <span>SpriteBuilder</span> project before running in <span>Xcode</span>?</p></li>
<li><p>Is the custom class of the root node of <em>MainScene.ccb</em> set to <span>MainScene</span></p></li>
<li><p>Does the button in <em>MainScene.ccb</em> have the correct target and selector?</p></li>
<li><p>Make sure to read the console log as it usually includes details about the failed code connection</p></li>
</ul>
<h3 id="creating-the-gameplay-scene">Creating the Gameplay Scene</h3>
<p>Now it’s time to create your first scene using <span>SpriteBuilder</span> from scratch. The scene we are going to create is the Gameplay scene.</p>
<p>Open <span>SpriteBuilder</span> to create a new scene. To create a new scene (or any other <span>CCB File</span>) select: <em>File -> New -> File…</em> from the <span>SpriteBuilder</span> menu. Then you will see the following dialog appear:</p>
<p><img src="images/firstproject/new_scene.png" alt="image" /></p>
<p>The dialog will ask you for a name for the <span>CCB File</span> and a template type. For now we are going to use the name <em>Gameplay.ccb</em> and the type <em>Scene</em>. Once you hit the create button you will see the new, blank scene appear.</p>
<p>Our Gameplay scene will remain empty. As you have seen in the outline of the project, we want to dynamically add colored objects to the game whenever the user taps into our Gameplay scene - initially however, the scene will be blank. Now that we have created the Gameplay scene we can add the transition from the Main scene to the Gameplay scene.</p>
<h3 id="adding-a-scene-transition">Adding a Scene Transition</h3>
<p>Transitions are essential for any game. We use them whenever we want to switch from one scene to another. Transitions cannot be configured in <span>SpriteBuilder</span>, they always need to be implemented in code.</p>
<p><span>Cocos2D</span> has one central class that is responsible for displaying the active scene and generating transitions between different scenes: <span>CCDirector</span>. CCDirector is implemented as a singleton - thus there’s only one CCDirector per <span>Cocos2D</span> game. The instance can be accessed through the class method <span>CCDirector.sharedInstance()</span>.</p>
<p>[CCDirector is versatile!] CCDirector is responsible for a lot more than only handling active scenes and scene transitions. It is basically a collection of different global <span>Cocos2D</span> settings. The scene handling methods however are the most frequently used CCDirector methods.</p>
<p>CCDirector provides a large collection of methods to present scenes with and without transitions, here are the most important ones:</p>
<pre><code>- (void)presentScene:(CCScene *)scene;
- (void)presentScene:(CCScene *)scene withTransition:(CCTransition *)transition;
- (void)pushScene:(CCScene*) scene;
- (void)pushScene:(CCScene *)scene withTransition:(CCTransition *)transition;
- (void)popScene;
- (void)popSceneWithTransition:(CCTransition *)transition;
- (void)popToRootScene;
- (void)popToRootSceneWithTransition:(CCTransition *)transition;</code></pre>
<p>[<span>Cocos2D</span> is written in Objetive-C] Yes I know, this isn’t Swift code! <span>Cocos2D</span> is written entirely in Objective-C. While it plays nicely with our Swift only code, you will be forced to read some Objective-C headers once in a while. Luckily these header files aren’t too cryptic!</p>
<p><span>Cocos2D</span> has two different approaches for displaying a new scene. <strong>Replacing</strong> the current scene with a new one, using the <span>presentScene:</span> methods, or <strong>Pushing</strong> the new scene on top of the currently active one using the <span>pushScene:</span> methods. Whichever type you choose, you always have the option to provide a transition effect for presenting a scene with an animation, or not to provide a transition effect and display the new scene instantaneously. If you want to provide an effect you need to create an instance of <span>CCTransition</span>.</p>
<p>Before we look into using transition effects, let’s take a look at the differences between pushing and replacing a scene.</p>
<h4 id="replacing-scenes-vs.-pushing-scenes">Replacing scenes vs. pushing scenes</h4>
<p>When you simply want to replace the current scene with a new one you should use the <span>presentScene:</span> method. Here’s an example:</p>
<pre><code>CCDirector.sharedDirector().presentScene(myNewScene)</code></pre>
<p>Very simple! So why would one use the <span>pushScene:</span> method? Let’s assume the following scenario where we want to implement a menu with multiple submenus. Whenever a player hits the back button, he wants to return to the previous menu:</p>
<p><img src="images/firstproject/navigation_stack.png" alt="image" /></p>
<p>This is a case where it is a lot easier to use <span>pushScene:</span> and <span>popScene:</span> instead of simply replacing the currently running scene. Whenever a player selects a button that opens a sub-menu, we call:</p>
<pre><code>CCDirector.sharedDirector().pushScene(submenu)</code></pre>
<p>And whenever a player hits the <em>back</em> button in one of the sub-menus, we simply call:</p>
<pre><code>CCDirector.sharedDirector().popScene()</code></pre>
<p>This works, because CCDirector will remember the scene that we pushed before the current one and can easily return to it. This concept is called a <em>Navigation Stack</em>.</p>
<p>If you would try to implement the menu hierarchy using <span>presentScene:</span> you would have to explicitly define which scene each back button will present. The code for the back button of <em>SubMenu</em> would look like this:</p>
<pre><code>CCDirector.sharedDirector().presentScene(mainMenu)</code></pre>
<p>If you would ever change the menu hierarchy in your game, you would have to change the code for each back button.</p>
<p>[Scene transitions - the right way] For <strong>one time transitions</strong> for example from a splash screen to the gameplay of a game, use <span>presentScene</span>. Whenever a user can navigate between your scenes, e.g. by using a back button to return to the previous scene, make use of the navigation stack by using the <span>pushScene</span> and <span>popScene</span> methods.</p>
<h4 id="adding-transition-effects">Adding transition effects</h4>
<p>For every scene replacement method there’s one variation that takes an instance of <span>CCTransition</span>. The CCTransition instance provides an animation for transitions between different scenes. CCTransition provides multiple convenience initializers which makes for short and readable code. Here’s an example of how to create an animated transition:</p>
<pre><code>let transition = CCTransition(fadeWithDuration: 1.0)
CCDirector.sharedDirector().presentScene(gameplayScene, withTransition: transition)</code></pre>
<p>First we create a transition object, then we hand it to the <span>presentScene</span> method.</p>
<h4 id="implementing-a-scene-transition-for-our-game">Implementing a scene transition for our game</h4>
<p>Now that you know the most important details about scene transitions, let’s add the transition from our start scene to our Gameplay scene. Earlier we have already implemented a test version of the <span>startGame</span> method, where we printed a log message to the console. Now we are going to implement a transition.</p>
<ol>
<li><p>Open <em>MainScene.m</em> in <span>Xcode</span>.</p></li>
<li><p>Replace the current implementation of <span>startGame</span> with this one:</p>
<pre><code>func startGame() {
let gameplayScene = CCBReader.loadAsScene("Gameplay")
let transition = CCTransition(fadeWithDuration: 1.0)
CCDirector.sharedDirector().presentScene(gameplayScene, withTransition: transition)
}</code></pre></li>
</ol>
<p>Now that you are familiar with scene transitions, the only interesting line should be the one where we use the <span>CCBReader</span> to load a <span>CCB File</span>. The CCBReader class was briefly introduced at the beginning of this chapter ([CCBReader]). It is capable of reading <span>SpriteBuilder</span>s <em>.ccbi</em> files and creating the according <span>Cocos2D</span> classes from the information stored in them. Whenever we want to load a scene or any other type of node that we created in <span>SpriteBuilder</span> into code we use the CCBReader class. In the lines shown above we load the content of our <em>Gameplay.ccb</em> into a variable called <span>gameplayScene</span>. The <span>loadAsScene:</span> method wraps whatever scene graph you load into an instance of <span>CCScene</span>. Use it whenever you want to load a <span>CCB File</span> in order to present is as a full-screen scene.</p>
<p>Then we create a simple fade transition and store that object in the <span>transition</span> variable. Finally we use the <span>CCDirector</span> to present our loaded scene with the transition we just created.</p>
<p>You are now ready to run this version of the game from <span>Xcode</span>! When you tap the <em>Start</em> button on the first scene, you should see a transition to our black Gameplay scene that lasts for one second.</p>
<p><strong>Well done!</strong> You have learned how to create a new scene in <span>SpriteBuilder</span> and how to implement transitions between different scenes in a game. Now let’s implement the actual gameplay of our first example game!</p>
<p>[.ccb and .ccbi] The files with the file extension <em>.ccb</em> are in XML-format and are used by <span>SpriteBuilder</span> to store and read information about a scene or node created in <span>SpriteBuilder</span>. When a <span>SpriteBuilder</span> project gets published, <span>SpriteBuilder</span> generates a binary version of each <em>.ccb</em> file. The file extension for these binary files is <em>.ccbi</em> and they are a lot smaller than their corresponding <em>.ccb</em> files. The CCBReader reads these smaller binary files at runtime and turns them into nodes.</p>
<h3 id="implementing-the-gameplay">Implementing the Gameplay</h3>
<p>Now it’s time to implement the actual gameplay. For our first project we want to keep that fairly simple. Whenever a user touches the screen, we want to add a rotating square with a random color to the gameplay scene. We position the square at the location of the touch.</p>
<h4 id="creating-the-square-ccb-file">Creating the Square <span>CCB File</span></h4>
<p>Let’s start by creating the square we want to spawn during the game in <span>SpriteBuilder</span>. In most games each of your different entities will be represented by an individual <span>CCB File</span>. That makes it easy to load entities in Code and reuse them throughout different scenes. For that reason we will create an individual <span>CCB File</span> for our rotating squares.</p>
<p>Create a new <span>CCB File</span> of type <em>Node</em>:</p>
<p><img src="images/firstproject/square_ccb.png" alt="image" /></p>
<p>The squares we generate in the game shall have a color. A default <span>CCNode</span> cannot display a color - it doesn’t have a <span>backgroundColor</span> property. In order to display a color we need to use a <span>CCNodeColor</span>. The <span>SpriteBuilder</span> node for a CCNodeColor is called <em>Color Node</em>. The root node of every <span>CCB File</span> is a plain <span>CCNode</span>, that cannot be changed. This means we need to add the <em>Color Node</em> as a child of the root node of <em>Square.ccb</em>.</p>
<p>Add a <em>Color Node</em> by performing the following steps:</p>
<p><img src="images/firstproject/square_add_colornode.png" alt="image" /></p>
<dl>
<dt>(1)</dt>
<dd><p>Open the <em>Node Library</em> and drag a <em>Color Node</em> to the stage or to the timeline in order to add it to the root node of of <em>Square.ccb</em>.</p>
</dd>
<dt>(2)</dt>
<dd><p>Center the new <em>Color Node</em> on the root node by selecting an <em>Anchor Point</em> of (0.5, 0.5). Change the <em>Content Size</em> of the node to (50, 50).</p>
</dd>
</dl>
<p>Now the basic square is set up. Next, we need to set up a code connection. Earlier you have seen the use of <em>Custom Classes</em> and <em>Callbacks</em>, now we will use the third type of code connections supported by <span>SpriteBuilder</span> a <em>Variable Assignment</em>. Variable assignments are generally used when we want to access a part of our scene graph in code. In our game, whenever a new square is created we want to set a random color for this square. Generating a random color is something we need to do in code and cannot do in <span>SpriteBuilder</span>. This also means that we need a way to <em>apply</em> the random color we generate in code to our square that we have set up in <span>SpriteBuilder</span>. The displayed color is defined in the <em>Color Node</em> that we just added. We will need a reference to this <em>Color Node</em> to change the color of our square from code. Let’s add a code connection to make this possible.</p>
<p><strong>Select CCNodeColor from the timeline</strong> (and make sure that you have selected the Color Node and not the Root Node!) and open the connection tab (the second tab on the right pane):</p>
<p><img src="images/Chapter1/square_code_connection.png" alt="image" /></p>
<p>As the variable name (entered in the text field), choose <em>colorNode</em>. As the second option you need to choose the object to which this variable will be assigned to. Just as for callbacks you can choose between the <em>Document Root</em> and the <em>Owner</em> ([DocumentRoot<sub>O</sub>wner]). We choose the <em>Document Root</em>, which means that <span>SpriteBuilder</span> will attempt to store a reference to the <em>Color Node</em> in a property called <em>colorNode</em> on the root node object of this <span>CCB File</span>.</p>
<p>We now face the same ’problem’ as earlier when we set up a <em>Callback</em>. The root node of <em>Square.ccb</em> is a plain <span>CCNode</span> and a plain <span>CCNode</span> does not have a property called <em>colorNode</em>! We once again need to define a custom class for the root node of this <span>CCB File</span>.</p>
<p><span>Variable Assignments, Callbacks and Custom Classes</span> Always remember that you practically cannot set up a <em>Variable assignment</em> or a <em>Callback</em> for the <em>Document Root</em> without also setting a custom class for the root node of the corresponding <span>CCB File</span>. You will always want to access properties or methods that aren’t available on the default type of the root node.</p>
<p><strong>Select the root CCNode node</strong> from the timeline and set the custom class for this node to <em>Square</em>:</p>
<p><img src="images/firstproject/square_custom_class.png" alt="image" /></p>
<p>When the <em>CCBReader</em> reads this <span>CCB File</span> it will create an instance of the class <em>Square</em> as the root node and it will assign a reference to the <em>Color Node</em> to a property of <em>Square</em> called <em>colorNode</em>. This way we will be able to access the <em>Color Node</em> and change the color of our square programmatically!</p>
<h4 id="setting-up-a-custom-class-for-the-gameplay">Setting up a custom class for the Gameplay</h4>
<p>In our <em>Gameplay</em> scene we want to respond to touches and spawn squares. All of that functionality needs to be implemented in code. Therefore we need to define a custom class for the root node of our <em>Gameplay.ccb</em> (if you struggle with the following instructions you can double check how we set up a custom class for <em>Square.ccb</em>).</p>
<ol>
<li><p>Open <em>Gameplay.ccb</em></p></li>
<li><p>Select the root <span>CCNode</span> from the timeline</p></li>
<li><p>Open the code connections tab (the second tab on the right pane)</p></li>
<li><p>Define the <em>Custom Class</em> to be <em>Gameplay</em></p></li>
</ol>
<p>We’ve set up multiple code connections throughout this chapter. In order for all of them to work, we need to publish the <span>SpriteBuilder</span> project.</p>
<ol>
<li><p>Publish the <span>SpriteBuilder</span> project</p></li>
<li><p>Switch to your Xcode project</p></li>
</ol>
<h4 id="creating-the-square-class">Creating the Square class</h4>
<p>Let’s create the classes and properties that we are referencing in the <span>SpriteBuilder</span> project to our Xcode project. We’ll get started with the <span>Square</span> class.</p>
<ol>
<li><p>Open <span>Xcode</span> and create a new Swift class by selecting <em>File -> New File…</em> and choosing <em>Cocoa Touch Class</em>:</p>
<p><img src="images/Chapter1/new_cocoa_touch.png" alt="image" /></p></li>
<li><p>Hit the next button</p></li>
<li><p>Choose <em>Square</em> as the class name and make sure you have selected <strong>Swift</strong> as the programming language! Define the class to be a subclass of <span>CCNode</span>:</p>
<p><img src="images/Chapter1/new_cocoa_touch_2.png" alt="image" /></p></li>
<li><p>Hit the <em>Next</em> button to create the file.</p></li>
</ol>
<p>Remember, a custom class always has to be a subclass of the node type you have selected in <span>SpriteBuilder</span>. The node type of the root node of <em>Square.ccb</em> is a <span>CCNode</span> therefore <span>Square</span> needs to be a subclass of <span>CCNode</span>.</p>
<p>Now open <em>Square.swift</em> and add the property <span>colorNode</span> to the <span>Square</span> class. This property is the one that we defined in <span>SpriteBuilder</span> to store the reference to the <span>CCNodeColor</span> that displays the color of our square:</p>
<pre><code>class Square : CCNode {
weak var colorNode : CCNodeColor!
}</code></pre>
<p>Note that we are using a <span>weak</span> variable of forcefully unwrapped type (indicated by the trailing <em>!</em> after the type name). This will be default for all code connections throughout this book for the following two reasons:</p>
<ol>
<li><p>The property is declared as <span>weak</span> because it doesn’t <em>own</em> the referenced child node. We only want to use this property as a reference - we know that another part of our game is responsible for keeping the referenced object around. In this case the <span>colorNode</span> will stay in memory as long as it is a child node of a scene that is rendered on the screen. Unowned references should always be marked as <span>weak</span> (or by using the Swift keyword <span>unowned</span>, but that is beyond the scope of this book!).</p></li>
<li><p>Since the code connection we set up will not have a value assigned as soon as <span>Square</span> is initialized we need to declare the property as either <em>optional</em> or <em>forcefully unwrapped</em>. Swift has pretty strict initialization rules! We choose <em>forcefully unwrapped</em> because we know that <span>Cocos2D</span> guarantees that this property will have a value as soon as the <span>CCB File</span> is loaded and <span>didLoadFromCCB</span> is called (we will discuss the <span>Cocos2D</span> lifecycle in detail shortly). Given this knowledge it’s preferable to choose <em>forcefully unwrapped</em> over <em>optional</em> because it avoids a lot of optional-unwrapping code.</p></li>
</ol>
<p>[Swift initialization and optionals] You can read more about Swift initialization and optionals in our following tutorial: <a href="https://www.makeschool.com/tutorials/learn-swift-by-example-part-3-classes-and-initialization" class="uri">https://www.makeschool.com/tutorials/learn-swift-by-example-part-3-classes-and-initialization</a></p>
<p>Now that we have a reference to the <span>CCNodeColor</span> we need a position in code where we can set a random color for that node.</p>
<p>The requirements for this project state that we need to choose a random color for our Square as soon as it is added to the Gameplay scene. <strong>How can we be informed about the square being added to the Gameplay scene?</strong> Therefore we need to take a closer look at what we call the <strong>Node Lifecycle</strong>.</p>
<p>We have five important methods that inform us about certain lifecycle events on <span>CCNode</span> subclasses. All of the methods below are called on all nodes that are part of the scene that is being loaded/presented/hidden:</p>
<dl>
<dt>didLoadFromCCB</dt>
<dd><p>this method is called when the <span>CCBReader</span> has created the complete node graph from a CCB file and all code connections are set up. You implement this method to access and manipulate the content of a node. You cannot access child nodes of the node or code connection variables before this method is called. Note that this method is only called on nodes that are loaded from <span>CCB File</span>s.</p>
</dd>
<dt>onEnter/onEnterTransitionDidFinish</dt>
<dd><p>are called as soon as a node enters the stage. If you are presenting a scene with an animated transition, <span>onEnter</span> will be called on that scene as soon as the transition starts and <span>onEnterTransitionDidFinish</span> will be called when the transition completes. If a scene or node is being presented/added without an animated transition both methods are called directly after each other. It’s also important to note that the content size of a node that is expressed relative to the parent node will not be available until <span>onEnter</span> has been called.</p>
</dd>
<dt>onExitTransitionDidStart/onExit</dt>
<dd><p>are called as soon as a node leaves the stage. If you are hiding a scene with an animated transition, <span>onExitTransitionDidStart</span> will be called on that scene as soon as the transition starts and <span>onExit</span> will be called when the transition completes. If a scene or node is being hidden/removed without an animated transition both methods are called directly after each other.</p>
</dd>
</dl>
<p>You will get to see lots of examples of how to use the lifecycle methods throughout this book, for now we know that we need to override <span>onEnter</span> to pick and apply a random color for our square as soon as it gets added to the Gameplay scene. It is also important to know that you need to call the <span>super</span> implementation if you override any of the <span>onEnter…</span> or <span>onExit…</span> methods. <span>CCNode</span> has its own implementation of these methods and they are important for the functionality of the framework - if you do not call them this will result in unexpected behaviour throughout your game.</p>
<p>[Overriding <span>Cocos2D</span> lifecycle methods] As of <span>Cocos2D</span> 3.1 not calling <span>super</span> when overriding one of these lifecycle methods will result in a compiler warning - this can save a lot of debugging time. You are interested in how that can be done? <span>Cocos2D</span> makes use of a nice compiler feature to implement this requirement. You simply need to add an according <span>__attribute__</span> to the method definition:</p>
<pre><code> -(void) onEnter __attribute__((objc_requires_super));</code></pre>
<p>Add this implementation of <span>onEnter</span> to <em>Square.m</em>:</p>
<pre><code>override func onEnter() {
super.onEnter()
let red = Float(arc4random_uniform(256)) / 255.0
let green = Float(arc4random_uniform(256)) / 255.0
let blue = Float(arc4random_uniform(256)) / 255.0
colorNode.color = CCColor(red: red, green: green, blue: blue)
}</code></pre>
<p>The lines above generate three random numbers, with a value between 0.0 and 1.0, using the C function <span>arc4random_uniform</span>. That’s one number for each color component. These three numbers are used to create an instance of <span>CCColor</span> and set it as the color of our node. Since <span>CCColor</span> wants to be initialized with <span>Float</span> values we need to explicitly create <span>Float</span> numbers from the result of calling the <span>arc4random_uniform</span> function which returns a <span>UInt32</span>.</p>
<p>Now the square will appear in a random color as soon as we add it to a scene. The second requirement for our square is that it shall rotate while on the screen. One of the ways to move and/or animate a node in <span>Cocos2D</span> is using the <span>Cocos2D</span> Action System.</p>
<h3 id="adding-actions-in-code">Adding Actions in Code</h3>
<p>Throughout most of the book we will be using <span>SpriteBuilder</span> to create animations. It is still very useful to know how to generate actions in code, as that approach can be easier to use for certain types of animations.</p>
<p>The <span>Cocos2D</span> Action System provides a simple and expressive way for developers to implement animated changes and movements such as: <em>Move the main character to the top left corner of the screen over the period of 2 seconds</em>.</p>
<p>The Action System consists of dozens of subclasses of <span><span>CCAction</span></span> - a majority of these actions represent some type of animated movement or transformation. <span>CCActionMoveTo</span> for example moves a node to a target position within a provided time interval. This is how to use it:</p>
<pre><code>let move = CCActionMoveTo(duration:2.0, position:ccp(20, 100))
aSimpleNode.runAction(move)</code></pre>
<p>All actions can be run by calling the <span>runAction</span> method of <span>CCNode</span> and providing the action as an argument.</p>
<p>The Action System also provides several actions that take other actions as arguments. One example is <span>CCActionReverse</span> that reverses the action it is initialized with - for example moving a node backwards instead of forwards. Another example is <span>CCActionRepeatForever</span> that takes another action and - exactly, repeats it forever!</p>
<p>Let’s use the Action System to rotate our squares!</p>
<p>Add the following lines to the <span>onEnter</span> method of <em>Square.m</em> to make the square rotate endlessly:</p>
<pre><code>let rotate = CCActionRotateBy(duration: 2.0, angle: 360.0)
let repeatRotation = CCActionRepeatForever(action: rotate)
runAction(repeatRotation)</code></pre>
<p>One of the nicest aspects of the Action System is that it produces very readable code, just as the one shown above. We rotate our square by 360 degrees in 2 seconds and repeat that forever!</p>
<p>Now our implementation of <span>Square</span> is complete. Along the way you have learned about code connections, generating random numbers and using the action system. Let’s move on to implementing the <span>Gameplay</span> class so that we can see our delightfully colored and rotating squares in action.</p>
<h4 id="creating-the-gameplay-class">Creating the Gameplay class</h4>
<p>After we have set up all the code for the square it’s now time to implement the gameplay. In <span>SpriteBuilder</span> we have already created the <span>CCB File</span> <em>Gameplay.ccb</em> and set up the custom class for the root node to be <span>Gameplay</span>. Now we need to add the <span>Gameplay</span> class in <span>Xcode</span> and implement touch handling code that creates a square and adds it to the gameplay scene as soon as a player touches the screen.</p>
<p>Create the new class just as you have created the <span>Square</span> class.</p>
<ol>
<li><p>In <span>Xcode</span> select <em>File -> New -> File…</em> and select <em>Cocoa Touch Class</em>.</p></li>
<li><p>This class needs to be a subclass of <span>CCNode</span> since the root node of <em>Gameplay.ccb</em> is a <span>CCNode</span>.</p></li>
<li><p>Name the class <span>Gameplay</span></p></li>
</ol>
<h4 id="Introduction_FirstTouchHandling">Adding Touch Handling to the Gameplay</h4>
<p>Now we need to add touch handling to the Gameplay scene. This will be the first time you will add User Interaction to a <span>Cocos2D</span> game!</p>
<p>The <span>Cocos2D</span> touch handling system works on a <em>per node basis</em>. This means that every <span>CCNode</span> instance can choose to receive touches or not. You can activate touch handling on any node using the <span>userInteractionEnabled</span> property. If <span>userInteractionEnabled</span> is set to <span>true</span>, <span>Cocos2D</span> will automatically check if your node is touched by the user. In <span>Cocos2D</span> the front most node receives touch events first.</p>
<p>Each touch in <span>Cocos2D</span> has a lifecycle. That lifecycle consists of four different states and four corresponding methods that are called on your <span>CCNode</span>:</p>
<dl>
<dt>touchBegan</dt>
<dd><p>called when a touch begins</p>
</dd>
<dt>touchMoved</dt>
<dd><p>called when the touch position of a touch changes</p>
</dd>
<dt>touchEnded</dt>
<dd><p>called when a touch ends because the user stops touching the screen</p>
</dd>
<dt>touchCancelled</dt>
<dd><p>called when a touch is cancelled because user moves touch outside of the touch area of a node</p>
</dd>
</dl>
<p>You can override all of these methods in any <span>CCNode</span> subclass in order to respond to these lifecycle events. For our simple example now, we only need to respond to the <span>touchBegan</span> method.</p>
<p>Note, that you always need to implement <span>touchBegan</span> in order to receive touches! If <span>touchBegan</span> is not implemented in your class, any touches will be ignored and none of the other lifecycle events will be called.</p>
<p>[The <span>Cocos2D</span> Touch System] We will see more complicated use cases of the <span>Cocos2D</span> touch system throughout other examples in this book. If you are interested in more details right away you should read:<a href="https://www.makeschool.com/docs/#!/cocos2d/1.2/user-interaction" class="uri">https://www.makeschool.com/docs/#!/cocos2d/1.2/user-interaction</a> and <a href="https://www.makeschool.com/tutorials/touch-handling-in-cocos2d" class="uri">https://www.makeschool.com/tutorials/touch-handling-in-cocos2d</a>.</p>
<p>Now that you know the basics, let’s implement touch handling for the <span>Gameplay</span> class. First, we need to enable user interaction. A great place to do this is in the <span>onEnterTransitionDidFinish</span> method. Why? If you have an animated transition that presents your gameplay scene you will likely not want to the player to interact with your game before this transition has finished entirely.</p>
<p>Let’s start receiving touches in the <span>Gameplay</span> class!</p>
<p>Add the following method to <em>Gameplay.swift</em>:</p>
<pre><code>override func onEnterTransitionDidFinish() {
super.onEnterTransitionDidFinish()
self.userInteractionEnabled = true
}</code></pre>
<p>As discussed earlier you need to call the <span>super</span> implementation of the lifecycle method you are overriding. In the second step we are setting <span>userInteractionEnabled</span> to <span>true</span>. Now <span>Cocos2D</span> knows that this node wants to receive touch events.</p>
<p>In the next step we need to decide which touch events we want to subscribe to and implement the corresponding methods. For this simple game we only need to know when a touch begins because we will add a square to the screen immediately. This means we only need to implement the <span>touchBegan</span> method.</p>
<p>Add the following implementation to <span>Gameplay.swift</span>:</p>
<pre><code>override func touchBegan(touch: CCTouch!, withEvent event: CCTouchEvent!) {
let touchPosition = touch.locationInNode(self)
let square = CCBReader.load("Square")
addChild(square)
square.position = touchPosition
}</code></pre>
<p>The <span>touchBegan</span> method above will be called every time the user taps onto the gameplay scene. As one parameter of this method we receive a <span>CCTouch</span>. The <span>CCTouch</span> stores all information about the touch. <span>Cocos2D</span> provides a useful method called <span>locationInNode:</span>. This method returns the touch position relative to the provided node. In the first line we call this method to receive the touch location within the gameplay scene (referred to by <span>self</span>). In the next line we load one <span>Square</span> node using the <span>CCBReader</span>. Then we add that loaded square as a child to the gameplay scene. The <span>addChild:</span> method of <span>CCNode</span> will add the square to the node hierarchy of the gameplay scene. As soon as node becomes part of the node hierarchy of the currently active scene it will be displayed on the screen. Finally we choose a position for the square. We provide the touch position that we determined in the first line - this way the square will be spawned exactly at the position touched by the player.</p>
<p>Now it’s time to run your project again. Once the game started, select the <em>Start</em> button to go to the gameplay scene then click onto the screen multiple times to simulate touches. Every time you simulate a touch you should see a new square spawn at the touch position:</p>
<p><img src="images/firstproject/spinning_squares.png" alt="image" /></p>
<h2 id="summary">Summary</h2>
<p><strong>Well done!</strong> You have come a very long way from the blank project to a first simple game that uses scene transitions, actions and the <span>Cocos2D</span> touch system.</p>
<p>This chapter has introduced you to the fundamental concepts of 2D game programming, <span>SpriteBuilder</span> and <span>Cocos2D</span>. But this is only the very beginning. In the next chapter we will start working on a much more complex game that will teach you many more important concepts of mobile game development with <span>SpriteBuilder</span> and <span>Cocos2D</span>.</p>
<h1 id="asset-handling-and-basic-game-mechanics">Asset Handling and Basic Game Mechanics</h1>
<p>Graphics and Sounds are the essence of every good game. In the first chapter you have learned the very basics of <span>SpriteBuilder</span> and <span>Cocos2D</span> by building a game that only uses plain colored shapes. In this chapter you will learn how <span>SpriteBuilder</span> helps you to integrate assets into your game. Learning by example is the most fun, so starting in this chapter and lasting until the end of the book, we will build a full iOS game! The final product is available on the App Store! Here’s what the final game will look like:</p>
<div class="figure">
<img src="images/Chapter2/final_game.png" alt="The game that is built throughout this book" />
<p class="caption">The game that is built throughout this book</p>
</div>
<p>The goal of that game is for the user to drag a pot across the screen in order to collect food items and avoid inedible kitchen equipment and other electronic devices.</p>
<p>When building this type of game you can choose whether or not to use the <span>Cocos2D</span> physics engine. For this book I have chosen to build the game <strong>without</strong> it. Here are the reasons:</p>
<ol>
<li><p>Games built with a physics engine have a very different feel from games where all objects are moved through custom code. A physics engine is never 100% accurate. The player can feel this in collisions and other interactions throughout the game. This is one of the main reasons while many platformers do not rely on physics engines. They are great for game concepts that entirely rely on a physics engine - such as the popular game angry birds. But there are more games out there that don’t use a physics engine than the other way round.</p></li>
<li><p>Many games are a little bit easier to build with a physics engine, but you will end up learning a very different set of skills. The main goal of this book is to teach you skills that you can use to build your own games. I felt I can provide more value by implementing object movement, collision detection, etc. customly.</p></li>
<li><p>There are already great resources on physics based games with <span>SpriteBuilder</span> and <span>Cocos2D</span> out there, including our Peeved Penguins tutorial (<a href="https://www.makeschool.com/tutorials/getting-started-with-spritebuilder/" class="uri">https://www.makeschool.com/tutorials/getting-started-with-spritebuilder/</a>) and Steffen Itterheim’s book <em>Learn SpriteBuilder</em> (<a href="http://www.apress.com/9781484202630" class="uri">http://www.apress.com/9781484202630</a>).</p></li>
</ol>
<p>Now you should have a decent idea of the game we will be building throughout the rest of this book! Let’s get started with the first part: asset management and setting up the basic mechanics of our game.</p>
<h2 id="adding-assets-to-a-spritebuilder-project">Adding Assets to a SpriteBuilder Project</h2>
<p>First of all we need to create a new <span>SpriteBuilder</span> project. You will also need to download the art pack for this game.</p>
<ol>
<li><p>Create a new <span>SpriteBuilder</span> project and name it <em>FallingObjects</em>.</p></li>
<li><p>Download the assets from <a href="http://bit.ly/sb-book-assets" class="uri">http://bit.ly/sb-book-assets</a>.</p></li>
<li><p>Unzip the folder once the download completes</p></li>
<li><p>Add the assets to the project by dragging the entire folder into the left <em>File View</em> in the left panel of <span>SpriteBuilder</span>:</p>
<p><img src="images/Chapter2/DragAssets.png" alt="image" /></p></li>
</ol>
<p>Great, now we have some assets to use in our game. Now is a good time to take a close look at how <span>SpriteBuilder</span> and <span>Cocos2D</span> handle assets.</p>
<h2 id="asset-handling-in-spritebuilder-and-cocos2d">Asset Handling in <span>SpriteBuilder</span> and <span>Cocos2D</span></h2>
<p>One of the main goals of <span>SpriteBuilder</span> is to make game development for multiple device types as easy as possible. This means that games should automatically be able to run on differently sized iPhones and on iPads. Since each of these devices has a different resolution <span>Cocos2D</span> and <span>SpriteBuilder</span> allow developers to use different assets to target them. <span>SpriteBuilder</span> provides four different resolution categories:</p>
<dl>
<dt>phone</dt>
<dd><p>resolution for non-retina iPhone</p>
</dd>
<dt>phone-hd</dt>
<dd><p>retina resolution for iPhone</p>
</dd>
<dt>tablet</dt>
<dd><p>resolution for non-retina iPad</p>
</dd>
<dt>tablet-hd</dt>
<dd><p>resolution for retina iPad</p>
</dd>
</dl>
<p>Luckily using <span>SpriteBuilder</span> there is no need to provide four resolutions for each asset thanks to <strong>automatic downscaling</strong>. Per default <span>SpriteBuilder</span> assumes that all assets added to a project are provided in <em>tablet-hd</em> resolution, then <span>SpriteBuilder</span> generates downscaled images for the other resolutions. While you can provide different images for the four targets, <span>SpriteBuilder</span> only knows three resolution types:</p>
<dl>
<dt>1x</dt>
<dd><p>non-retina images</p>
</dd>
<dt>2x</dt>
<dd><p>retina images</p>
</dd>
<dt>4x</dt>
<dd><p>double sized retina images</p>
</dd>
</dl>
<p>By default <span>SpriteBuilder</span> maps these resolution types to the different devices in a way that every asset has the same relative size, in relation to the screen size, on every device. This means games running on an iPad will look very similar to games running on an iPhone, except that they have a slightly different aspect ratio. Here is an example from on of our tutorials showing what a game looks like on different device types:</p>
<div class="figure">
<img src="images/Chapter2/ResultsFlexibleScaleMode.png" alt="From our tutorial Dynamic Layouts with SpriteBuilder and Cocos2D" />
<p class="caption">From our tutorial <em>Dynamic Layouts with SpriteBuilder and Cocos2D</em></p>
</div>
<p>Let’s take a look at all of the options for image sizes in the context of our <span>SpriteBuilder</span> project - that will make it easier to understand how the parts fit together.</p>
<p>Let’s start in the project settings. When you open the project settings (<em>File -> Project Settings…</em>) you can see the available downscaling options:</p>
<p><img src="images/Chapter2/DownScalingGlobal.png" alt="image" /></p>
<p>The <em>Default scaling from</em> setting defines the <em>global</em> downscaling option, i.e. which resolution <span>SpriteBuilder</span> uses to generate all of our assets. Individual assets can define their own behaviour, thereby overriding this global setting. To make support of multiple devices as easy as possible you should provide all of your assets in <em>4x</em> resolution and keep this default setting.</p>
<p>When you select an individual asset from the File View you can see different downscaling settings:</p>
<p><img src="images/Chapter2/DownScalingPerAsset.png" alt="image" /></p>
<p>Each asset can have its own <em>Scale from</em> setting. <em>Default</em> means that the global project setting applies (in this project: downscaling from <em>4x</em>). Additionally you can see how the different resolution types are mapped to the different device types. Here you could for example choose that a certain asset should not be scaled up on retina tablets by choosing a <em>2x</em> resolution for <em>tablethd</em> - however, the default settings work best most of the time.</p>
<p>For future reference, this is an example that shows you which sizes your assets will have on the different devices by default:</p>
<table>
<tbody>
<tr class="odd">
<td align="left"><strong>Device</strong></td>
<td align="left"><strong>Default Resolution Type</strong></td>
<td align="left"><strong>Size on Screen (points)</strong></td>
<td align="left"><strong>Size in Pixels</strong></td>
</tr>
<tr class="even">
<td align="left">iPhone</td>
<td align="left">1x</td>
<td align="left">50x50</td>
<td align="left">50x50</td>
</tr>
<tr class="odd">
<td align="left">iPhone Retina</td>
<td align="left">2x</td>
<td align="left">50x50</td>
<td align="left">100x100</td>
</tr>
<tr class="even">
<td align="left">iPad</td>
<td align="left">2x</td>
<td align="left">100x100</td>
<td align="left">100x100</td>
</tr>
<tr class="odd">
<td align="left">iPad Retina</td>
<td align="left">4x</td>
<td align="left">100x100</td>
<td align="left">200x200</td>
</tr>
</tbody>
</table>
<p>The key takeaway for now is that it’s best to provide assets in <em>4x</em> resolution in order to build games that look good on all device types. All the assets in the art pack that you downloaded earlier are provided in <em>4x</em> resolution.</p>
<p>That’s enough of theory for now - let’s get started on building the <em>Falling Object!</em> game.</p>
<p>[Different images for different devices] You can not only change the scaling option for an asset on different devices, you can even use an entirely different image for a certain resolution. You can do that by dragging an image <strong>that is currently not part of the <span>SpriteBuilder</span> project</strong> from Finder into one of the four boxes below the asset preview:</p>
<p><img src="images/Chapter2/DifferentImageDevice.png" alt="image" /></p>
<p>Note that images you add this way will be displayed in exactly the size you have added them and will not be downscaled.</p>
<p>[Behind the scenes] If you are interested in how <span>SpriteBuilder</span> and <span>Cocos2D</span> organize assets you can take a look at the resource package (<em>/Packages/SpriteBuilder Resources.sbpack</em>) by right-clicking and selecting <em>Show Package Contents</em>:</p>
<p><img src="images/Chapter2/behindscenes_resourcepack.png" alt="image" /></p>
<p>You will see that <span>SpriteBuilder</span> groups images inside the assets folder into a <em>resources-auto</em> folder, all images in that folder are subject to automatic downscaling. If you explicitly add images for a certain resolution as shown with the carrot in the above example, a new folder for that resolution (e.g. <em>resources-phonehd</em>) is created.</p>
<p>In <span>Cocos2D</span> a class called <span>CCFileUtils</span> is responsible for loading the correct images for the current device during runtime. <span>SpriteBuilder</span> uses a special configuration of <span>CCFileUtils</span> that is set up in <span>[CCBReader configureCCFileUtils]</span>.</p>
<h2 id="adding-the-background-image">Adding the Background Image</h2>
<p>Now that we have a basic understanding of how asset management works, lets get started working on our game. For now it will only consist of one scene, so we can start working directly in the <em>MainScene.ccb</em> that is part of the <span>SpriteBuilder</span> template.</p>
<ol>
<li><p>Open <span>MainScene.ccb</span> in your <span>SpriteBuilder</span> project</p></li>
<li><p>Remove all of the content from <span>MainScene.ccb</span> by selecting all nodes on stage and hitting the return key</p></li>
<li><p>Drag the <span>background.png</span> file from the asset folder, in the left panel of <span>SpriteBuilder</span>, to the stage. <span>SpriteBuilder</span> will automatically generate a Sprite Node from this image</p></li>
</ol>
<p>First, remove the existing content so that we can start with a blank scene. Now we can add the background image. To add a sprite to a scene we can simply drag the asset from the left panel to the stage, <span>SpriteBuilder</span> will automatically create an instance of <span>CCSprite</span>. Add the <em>background.png</em> image to the stage.</p>
<p>How should we position this background image? We already have briefly discussed the <span>SpriteBuilder</span> positioning system ([PositioningSystem]). Using the positioning system correctly is especially important when we create games that shall work on both phones and tablets - which we always should try to do. In most cases - like in this game - it is best to center the background image. That way phones and tablets will display a very similar portion of it. The background image that is part of the asset catalog has a size of <em>(2272 x 1536)</em>. This is an image in <em>4x</em> resolution that has exactly the right dimensions to support phones and tablets in landscape mode. It’s high enough for the higher tablet screens and wide enough for the wider phone screens.</p>
<p>Let’s position the background image correctly!</p>
<p>Center the image by choosing a <em>normalized</em> position type (<em>in % of parent container</em>) and setting the position to (50, 50) as shown below:</p>
<p><img src="images/Chapter2/center_background.png" alt="image" /></p>
<p>You can preview what your game will look like on different device types directly in <span>SpriteBuilder</span>, without the need to compile and run the game - you should do this as often as possible! The option is available from the menu <em>Document -> Resolution</em>. You can also use the CMD+1, CMD+2 and CMD+3 shortcuts. This feature will allow you to preview the game on a 3.5-inch iPhone, a 4-inch iPhone and an iPad. [preview<sub>s</sub>creen<sub>s</sub>izes]</p>
<h2 id="create-falling-objects">Create Falling Objects</h2>
<p>Now let’s dive into the implementation of the actual game. The next step should be adding falling objects. Our game will have two categories of objects, ones that should be caught (food) and ones that shouldn’t (electronic devices).</p>
<p>In total we have over ten different objects in our game but these just exist as visual enhancement, actually we are only differing between two types of objects. One way to implement the falling objects would be creating a <span>CCB File</span> for each object but that isn’t actually necessary for this game. We need to create all falling objects dynamically, while the game is running, and for each object we only need to store if it should be caught or not. That can be best accomplished by a subclass of <span>CCSprite</span> that we create in code. This way you will also learn how to use assets you added in <span>SpriteBuilder</span> to create <span>CCSprite</span>s in code.</p>
<p>Open the <span>Xcode</span> project of the game to get started. Remember that you can use the <em>CMD + Shift + O</em> shortcut to do so!</p>
<h3 id="create-a-falling-object-class">Create a Falling Object Class</h3>
<p>In general we have two ways to differentiate objects a player should catch and ones he shouldn’t catch. We could:</p>
<ul>
<li><p>Create two distinct subclasses of <span>CCSprite</span>, each representing one type of object</p></li>
<li><p>Only have one subclass and add a <span>type</span> property to it</p></li>
</ul>
<p>Since our falling objects won’t have any type-specific behaviour, creating two distinct subclasses is not necessary in this case. Instead, as of now, one subclass with a <span>type</span> property is the better solution.</p>
<p>Create a new class called <span>FallingObject</span> and make it a subclass of <span>CCSprite</span>. If you run into issues, check how we created new classes in the last chapter.</p>
<p>The best way to implement our <span>type</span> property is using an enumeration. Enumerations define multiple mutually exclusive values.</p>
<p>Add this enum definition to <em>FallingObject.swift</em>, inside of the <span>class</span> block:</p>
<pre><code>enum FallingObjectType: Int {
case Good
case Bad
}</code></pre>
<p>The enumeration above can only be in one of the two states at a time, either <span>.Good</span> or <span>.Bad</span>. Swift supports multiple types of enumerations and enumeration values. In the example above we are creating an enumeration with <em>Raw Values</em>. When we use an enumeration with raw values we need to assign a type as part of the enum definition, as shown in the first line (<span>enum FallingObjectType: Int</span>).</p>
<p>Each enum value will be mapped to one value of this provided type. In the example shown above, the raw value for <span>FallingObjectType.Good</span> will be 0 and the value for <span>FallingObjectType.Bad</span> will be 1. Thanks to auto-increment we do not need to map entries to numbers explicitly. Associating enum values with raw values is optional, throughout this chapter you will see why this feature is useful to us.</p>
<p>[Enumerations in Swift] You can read everything about the different ways of creating enumerations in Swift in the official documentation (<a href="https://developer.apple.com/library/ios/documentation/
Swift/Conceptual/Swift_Programming_Language/Enumerations.html" class="uri">https://developer.apple.com/library/ios/documentation/
Swift/Conceptual/Swift_Programming_Language/Enumerations.html</a>). You can also read a more practical tutorial on Swift enums on our website: (<a href="https://www.makeschool.com/tutorials/learn-swift-by-example-part-2-enums" class="uri">https://www.makeschool.com/tutorials/learn-swift-by-example-part-2-enums</a>)</p>
<p>Additionally we add a property to store the object type. Later we will add an initializer to set the type of the falling object upon initialization.</p>
<p>Add a property to store the falling object type, so that the class looks as following:</p>
<pre><code>import Foundation
class FallingObject: CCSprite {
enum FallingObjectType: Int {
case Good
case Bad
}
private(set) var type:FallingObjectType
}</code></pre>
<p>We define the property to be <em>readonly</em> because we will not support changing the type of a falling object after it has been created. In Swift we can define variables as <em>readonly</em> by marking the <em>setter</em> as private.</p>
<p>Note that the code will not compile at this point. Since <span>type</span> isn’t declared as an optional value, Swift requires us to provide an initializer that sets this value. We will fix this in the next section.</p>
<h3 id="choosing-an-asset-for-a-falling-object">Choosing an Asset for a Falling Object</h3>
<p>We want the game to spawn entirely random falling objects. As you remember we have a couple of assets for both types of objects. Whenever we spawn an object we will need to choose a random asset, based on the object type. A good place to implement this functionality is directly in the <span>FallingObject</span> class. We can provide a custom initializer that allows the class to be initalized with an object type. When this initializer gets called we choose a random asset and apply it as a texture to the <span>FallingObject</span>.</p>
<p>How can we create a list of images for objects that should be caught (e.g. food) and ones that shouldn’t (e.g. radios)? One way of implementing this would be creating two arrays, one for each object type, and storing filenames for different assets in these arrays. As good game developers however, we try to keep game content and code as strictly separated as possible. That makes it easier to update the list of assets later on and it keeps our codebase small and well structured. So instead of creating these arrays in code we could use some sort of resources file that stores information on available images. A very common format for storing such type of information in iOS applications is a <em>plist</em> (Property List). A plist is a special type of XML file that allows us to store structured data. The iOS frameworks have some features that make it easy to interact with plists and to generate them or read them from source code.</p>
<p>Let’s a plist file to our project!</p>
<p>Create a <em>plist</em> by selecting <em>File -> New -> File…</em> from <span>Xcode</span>’s menu. Then select <em>Resource</em> from the left panel and choose <em>Property List</em> on the right:</p>
<p><img src="images/Chapter2/create_plist.png" alt="image" /></p>
<p>As the name choose <em>FallingObjectImages</em>.</p>
<p>Next, let’s fill the <em>plist</em> with two arrays that contain the filenames of the assets that we added in <span>SpriteBuilder</span>, grouped into <em>good</em> and <em>bad</em> objects.</p>
<p>When referencing assets from a <span>SpriteBuilder</span> project you always need to include the folder names in which the images are contained. Instead of referencing the tomato with <span>tomato.png</span> you need to use <span>assets/tomato.png</span> since the image is in the <span>assets</span> folder in the <span>SpriteBuilder</span> project.</p>
<ol>
<li><p>Right-click onto the <em>plist</em> root and select <em>Add Row</em> from the context menu</p></li>
<li><p>Click onto the <em>Type</em> column of the new row and select the type to be <em>Array</em></p></li>
<li><p>Double-click onto to the name of the array and rename it to <em>FallingObjectTypeBadImages</em></p></li>
<li><p>Repeat step 2 and 3 to create another array</p></li>
<li><p>Name that new array <em>FallingObjectTypeGoodImages</em></p></li>
<li><p>Add all the assets as <em>String</em> entries to the according arrays</p></li>
</ol>
<p>The resulting <em>plist</em> should look like this:</p>
<p><img src="images/Chapter2/plist_setup.png" alt="image" /></p>
<p>Now we have a list of all asset names grouped into the two object type categories. Time to implement the <span>FallingObject</span> class.</p>
<p>When a falling object is initialized we want to choose random image from the <em>plist</em> that we just created. The first step is loading the <em>plist</em> in code. Luckily <em>plists</em> consist of Dictionaries, Arrays, Strings, etc. and all of these types exist in Swift as well - there are some very convenient methods to load <em>plists</em> and turn their content into Swift types.</p>
<p>During each playing session we are going to create hundreds of falling objects. Since the images that represent these objects won’t change it would be a waste of resources to load the <em>plist</em> every time we create a new instance of <span>FallingObject</span>. Instead we should only load it once and then keep a reference to it for future use. A good way of doing this is using a class constant to store a reference to the <em>plist</em> once it is loaded.</p>
<p>[Class variables in Swift] Swift 1.2 does not support stored class variables. However, we can use the <span>static</span> keyword to create class-wide variables. The difference between a <span>static</span> and a <span>class</span> variable is that the <span>static</span> variable is not inherited by subclasses. However, that isn’t an issue for our use case!</p>
<p>Let’s add the code that loads the plist and stores the content in a static variable.</p>
<p>Place the following code within the class definition of <span>FallingObject</span> (no worries, we will discuss the code in detail right away):</p>
<pre><code> private static let imageNames = ImageNames()
private struct ImageNames {
var good: [String]
var bad: [String]
init () {
let path = NSBundle.mainBundle().pathForResource("FallingObjectImages", ofType: "plist")!
let imageDictionary:Dictionary = NSDictionary(contentsOfFile: path)! as! [String : AnyObject]
good = imageDictionary["FallingObjectTypeGoodImages"] as! [String]
bad = imageDictionary["FallingObjectTypeBadImages"] as! [String]
}
}</code></pre>
<p>First, we are defining a private static constant. This static constant is initialized with an instance of the structure <span>ImageNames</span> which we declare a few lines later. Since <span>imageNames</span> is a static constant, the expression will ever only be evaluated once. This means only one instance of <span>ImageNames</span> will be created, independently of how often the static constant is accessed.</p>
<p>Inside of the <span>ImageNames</span> struct, the actual work happens. First we declare two array variables that store strings. They store the filenames of the <em>good</em> object assets and the <em>bad</em> object assets. Inside of the initializer we fill these variables.</p>
<p>The initializer takes no parameters. The first line gets the path of the <em>FallingObjectImages.plist</em> file. Then we use a convenience initializer on <span>NSDictionary</span> called <span>contentsOfFile:</span>. That initializer creates a dictionary from a provided plist. This only works because the root element of our plist is a dictionary! Since the file from which we are creating a dictionary might not exist, or could be of an invalid file type, the <span>contentsOfFile:</span> initializer returns an optional. Therefore we need to use the <span>!</span> operator to unwrap the value. Additionally we need to cast the Objective-C dictionary that doesn’t have any type information about the elements it contains to a Swift dictionary of type <span>[String : AnyObject]</span> using the <span>as!</span> operator.</p>
<p>We’ve set up our plist to contain two arrays of strings, <em>FallingObjectTypeGoodImages</em> and <em>FallingObjectTypeBadImages</em> below the root element. We can now extract these two arrays from our dictionary and assign them to the <span>good</span> variable and <span>bad</span> variable, respectively. During this assignment we need to cast the arrays into <span>[String]</span> arrays using the <span>as!</span> operator. This is again necessary because we are receiving an Objective-C Array (<span>NSArray</span>) that cannot store type information about the elements it contains. We however know that this array only contains strings so we want to treat it as a <span>[String]</span> array in Swift.</p>
<p>Now we have successfully set up a static constant that will load the required image names when it is accessed the fist time and store these images on a class level. That will avoid reloading the plist for every instance of <span>FallingObject</span> that we create.</p>
<p>Now that we have access to the image names we can implement the actual initializer of <span>FallingObject</span>. We need to:</p>
<ul>
<li><p>Pick a random image based on the object type</p></li>
<li><p>Call the designated initializer of our superclass <span>CCSprite</span></p></li>
</ul>
<p>Add the following initializer to <span>FallingObject.swift</span>:</p>
<pre><code> init(type: FallingObjectType) {
self.type = type
var imageName:String? = nil
if (type == .Good) {
let randomIndex = randomInteger(FallingObject.imageNames.good.count)
imageName = FallingObject.imageNames.good[randomIndex]
} else if (type == .Bad) {
let randomIndex = randomInteger(FallingObject.imageNames.bad.count)
imageName = FallingObject.imageNames.bad[randomIndex]
}
let spriteFrame = CCSpriteFrame(imageNamed:imageName)
super.init(texture: spriteFrame.texture, rect: spriteFrame.rect, rotated: false)
anchorPoint = ccp(0,0)
}</code></pre>
<p>We start of by storing the type we receive in a property. Then we create a local variable called <span>imageName</span> that we will use to load the correct texture for this object type. Next, we check whether we are initializing a good or a bad object. In each case we generate a random number, using our helper function <span>randomInteger</span>, that picks one image name from the set of available image names in the arrays.</p>
<p>Next, we need to call an initializer of our superclass <span>CCSprite</span>. Here we run into another limitation of the current version of Swift: <strong>we can only call <em>designated</em> initializers of our superclass</strong>, but not any <em>convenience</em> initializers. This means instead of calling:</p>
<pre><code>CCSprite(imageNamed: String!)</code></pre>
<p>We have to call the designated initializer:</p>
<pre><code>CCSprite(texture: CCTexture!, rect: CGRect, rotated: Bool)</code></pre>
<p>This unfortunately means some extra code! We create a <span>CCSpriteFrame</span> with the image name that we have selected from one of our lists, then we use that sprite frame to call <span>CCSprite</span>’s designated initializer. Finally, we set the anchor point of our object to the bottom left corner. That will make it easier to calculate the spawn position later on.</p>
<p>You will notice that this code won’t compile! The <span>randomInteger</span> function is not part of the Swift standard library. Instead it is a convenience function that I’ve created to make generation of random numbers in Swift easier. You need to download the file containing the helper and add it to your project.</p>
<p>Download <span>Helpers.swift</span> from this url <a href="http://bit.ly/sb-book-helpers" class="uri">http://bit.ly/sb-book-helpers</a> and add it to your project.</p>
<p>Now the compiler should be satisfied!</p>
<p>That’s all we need in order to create a <span>FallingObject</span>! Now we can move on and spawn some objects.</p>
<h2 id="spawn-falling-objects">Spawn Falling Objects</h2>
<p>Now it’s time to implement one of the core mechanics of the game: Spawning objects and making them fall from the top of the screen to the bottom. We are going to implement this in <em>MainScene.swift</em>.</p>
<p>We will spawn objects after a certain time period. The spawning objects will start at the top of the screen and fall to the bottom. To not use an increasing amount of memory we will need to take care of removing objects that have fallen below the bottom edge of the screen. A good way to do this is creating an array to store all the objects we spawn.</p>
<p>Add the following property to <span>MainScene</span></p>
<pre><code>class MainScene: CCNode {
private var fallingObjects = [FallingObject]()
}</code></pre>
<p>We also need to define a falling speed and an interval at which we want to spawn objects. A good way to do this is by defining constants - we want to avoid to have these numbers all over our code.</p>
<p>Add the two constants so that your class definition looks as following:</p>
<pre><code>class MainScene: CCNode {
private var fallingObjects = [FallingObject]()
private let fallingSpeed = 100.0
private let spawnFrequency = 0.5
}</code></pre>
<p>We are going to spawn falling objects ever 0.5 seconds as expressed in the constant <span>spawnFrequency</span>. Through the <span>CCNode</span> class <span>Cocos2D</span> provides convenient methods for scheduling repeating events without the need to instantiate a timer.</p>
<p>Schedule the <span>spawnObject</span> method in the <span>onEnterTransitionDidFinish</span> method:</p>
<pre><code> override func onEnterTransitionDidFinish() {
super.onEnterTransitionDidFinish()
// spawn objects with defined frequency
schedule("spawnObject", interval: spawnFrequency)
}</code></pre>
<p>Remember, <em>onEnterTransitionDidFinish</em> is called as soon as the presentation transition is completed and the current scene is fully visible. This is when we want to kick off the spawning mechanism. All we need to provide is a <em>selector</em>, which simply means a method name as a string, and a frequency at which it shall be called. Now, as soon as the <span>MainScene</span> is presented on the stage, the <span>spawnObject</span> method will be called twice a second. To complete the spawning functionality we will have to implement the <span>spawnObject</span> method and additionally move the spawned objects from the top of the screen to the bottom.</p>
<p>We want to randomly spawn either positive objects that should be caught or negative ones that should not, for that we will generate a random number between 0 and 1. Based on the random number we will generate a falling object of positive or negative type. We will place that spawning object just above the screen at a random X position.</p>
<p>Add the following <span>spawnObject</span> method to <span>MainScene</span>:</p>
<pre><code> func spawnObject() {
let randomNumber = randomInteger(2)
let fallingObjectType = FallingObject.FallingObjectType(rawValue:randomNumber)!
let fallingObject = FallingObject(type:fallingObjectType)
// add all spawning objects to an array
fallingObjects.append(fallingObject)
// spawn all objects at top of screen and at a random x position within scene bounds
let xSpawnRange = Int(contentSizeInPoints.width - CGRectGetMaxX(fallingObject.boundingBox()))
let spawnPosition = ccp(CGFloat(randomInteger(xSpawnRange)), contentSizeInPoints.height)
fallingObject.position = spawnPosition
addChild(fallingObject)
}</code></pre>
<p>As you can see here we can create an enum value directly from a number. This is possible because we defined the <span>FallingObjectType</span> enumeration to have a raw integer value earlier. The <span>rawValue</span> initializer is very handy for this specific situation. Besides that the spawning code is not too exciting, it primarily consists of a little math and type conversions. We add each spawned object to the <span>fallingObject</span> array, choose a spawn position and add it as a child to <span>MainScene</span>.</p>
<p>This is a schematic diagram of where we are spawning objects with the code shown above:</p>
<p><img src="images/Chapter2/SpawnObjects.png" alt="image" /></p>
<p>Our current version of the game spawns new objects twice a second at the top of the screen and at a random X position. However, these objects don’t move yet so you won’t be able to see them falling down. Let’s implement the falling code to complete the entire spawning functionality!</p>
<h2 id="move-falling-objects">Move Falling Objects</h2>
<p>The last step for this chapter will be making the objects we are spawning fall to the ground. While building your very first <span>SpriteBuilder</span> game you have learned to use the <span>Cocos2D</span> action system to move nodes. The action system lets us describe changes over time, e.g. <em>move 100 points to the right over 2 seconds</em>. Another option to move nodes that we haven’t discussed yet is using the <span>Cocos2D</span> <em>update loop</em>.</p>
<h3 id="update-loop">Update Loop</h3>
<p>When we build games with <span>Cocos2D</span> the engine attempts to render 60 frames a second and draws theses rendered frames to the screen of the device. 60 discrete updates a second are so fast, that they appear as one continous movement to the human eye.</p>
<p>When we move objects between rendering frames, they will appear as moving objects to the user. <span>Cocos2D</span> provides a method that is called directly before a frame is rendered, the <span>update</span> method.</p>
<p>The <span>update</span> method is defined as part of the <span>CCSchedulerTarget</span> protocol. <span>CCNode</span> implements this protocol, that means any subclass of <span>CCNode</span> can override the method. This is the signature of the <span>update</span> method:</p>
<pre><code>func update(delta: CCTime)</code></pre>
<p>We receive one parameter called <span>delta</span> from the <span>Cocos2D</span> framework. The delta parameter contains the milliseconds since the <span>update</span> method was called last. Most of the time this value will be <em>0.0167</em> milliseconds, which is 1/60 of a second. If the performance of our game drops below 60 FPS this value will be higher, because the time between two rendered frames will increase. If we want our objects to move at the same speed, independent of the current framerate, we can use this delta parameter to calculate how far we need to move nodes between two given frames.</p>
<p>Enough of the theory - let’s implement our update method, that will help you understand the details.</p>
<h3 id="implementing-the-update-method">Implementing the Update Method</h3>
<p>Here is what we want to do in the update method:</p>
<ul>
<li><p>Iterate over all falling objects</p></li>
<li><p>For each object check if it is within the screen boundaries</p></li>
<li><p>If the object is outside of the screen, remove it</p></li>
<li><p>If the object is inside of the screen boundary, let it fall to the bottom</p></li>
</ul>
<p>Add the following <span>update</span> method to <span>MainScene</span>:</p>
<pre><code> override func update(delta: CCTime) {
// use classic for loop so that we can remove objects while iterating over the array
for (var i = 0; i < fallingObjects.count; i++) {
let fallingObject = fallingObjects[i]
// check if falling object is below the screen boundary
if (CGRectGetMaxY(fallingObject.boundingBox()) < CGRectGetMinY(boundingBox())) {
// if object is below screen, remove it
fallingObject.removeFromParent()
fallingObjects.removeAtIndex(i)
} else {
// else, let the object fall with a constant speed
fallingObject.position = ccp(
fallingObject.position.x,
fallingObject.position.y - CGFloat(fallingSpeed * delta)
)
}
}
}</code></pre>
<p>The interesting aspect of the code snippet above is how we check if the falling object is out of bounds and how we move the falling object. Note that we are using the <span>CGRectGetMaxY</span> and <span>CGRectGetMinY</span> functions to determine the top and the bottom of the bounding boxes of the falling object and the gameplay scene. The <span>CGRectGetMaxY</span> function returns the largest Y value of the bounding box. Using these functions is preferred over accessing values directly (e.g. <span>fallingObject.boundingBox.origin.y</span>) because they also work for rectangles with negative sizes, e.g. a rectangle with a height of <em>-10</em> (which is technically possible in 2D math!).</p>
<p>If we detect that the top border of the falling object is below the bottom border of the screen, we remove the falling object from the scene. We do that by first calling <span>removeFromParent</span> on the node - which removes it from the scene graph and makes it invisible. Then we additionally remove the node from the <span>fallingObjects</span> array, so that the node gets destroyed and the memory gets freed.</p>
<p>If the falling object is within the screen boundary we move it to the bottom with the constant speed that we defined earlier multiplied by the value of <span>delta</span>.</p>
<p>Now the falling mechanic is entirely implemented! In the next and last section of this chapter you will learn how to add sound assets to the game.</p>
<p>[Update vs. Fixed Update] This chapter discusses the <span>update:</span> method of <span>Cocos2D</span> in detail. <span>Cocos2D</span> provides a second similar method called <span>fixedUpdate:</span>. Unlike the <span>update:</span> method, the <span>fixedUpdate:</span> method is <strong>guaranteed</strong> to be called at a specified interval (per default 1/60) and is not dependent on the framerate the game is running at. The physics engine integrated in <span>Cocos2D</span> uses the <span>fixedUpdate:</span> method to perform all of its calculations. For you as developer that means that you should implement code that changes physical attributes in the <span>fixedUpdate:</span> method and <strong>not</strong> in the <span>update:</span> method. Building games involving physics is not part of this book. If you pursue a physics game on your own after finishing this book you can read a nice blog post about the <span>fixedUpdate</span> method here: <a href="http://kirillmuzykov.com/update-vs-fixedupdate-in-cocos2d/" class="uri">http://kirillmuzykov.com/update-vs-fixedupdate-in-cocos2d/</a>.</p>
<h2 id="adding-sound-effects">Adding Sound Effects</h2>
<p>The goal of this chapter is for you to learn how to use assets with <span>SpriteBuilder</span> and <span>Cocos2D</span>. Obviously images are the most important assets in games, but sound effects also play a big role in creating games that your players enjoy. In this section you will learn how to add a sound effect that gets played whenever one of the falling objects drops off the screen.</p>
<p><span>SpriteBuilder</span> is designed to take care of your entire asset management. This means that you want to add all image files and all audio files to your <span>SpriteBuilder</span> project.</p>
<p>All sound files need to be added to <span>SpriteBuilder</span> projects in the <em>Wave</em> format. <span>SpriteBuilder</span> will then generate compressed versions of that sound as you publish the project. You can add the sound effect - just like any other asset - by dragging it from Finder to the resource pane (in the bottom left) of <span>SpriteBuilder</span>. For this project I have included a <span>drop.wav</span> file in the <span>assets</span> folder that you downloaded and added to your project earlier.</p>
<p>There are different ways to play sound effects added to your <span>SpriteBuilder</span> project: you can add a sound effect to a <span>SpriteBuilder</span> timeline or you can play a sound effect directly from code. We will first look at the timeline approach, later in the book I will show you how to play sound effects in code. Before we set up the sound effect I want to give you a basic introduction to the timeline feature of <span>SpriteBuilder</span> since it is one of the most powerful tools that <span>SpriteBuilder</span> provides.</p>
<h3 id="spritebuilders-timeline-feature"><span>SpriteBuilder</span>’s Timeline Feature</h3>
<p>The <span>SpriteBuilder</span> timeline is a tool that allows developers to create animations and sequences of sound effects without writing code. Every <span>CCB File</span> has one <em>Default Timeline</em> associated with it as soon as it is created. However, a <span>CCB File</span> can, and often will, have multiple different timelines. Each timeline is a sequence of sound effects, callbacks and most importantly keyframes. Keyframes allow us to create animations by defining how sprites move and change over time. We can change properties such as position, rotation, color, etc. <span>SpriteBuilder</span>’s animation tool is very similar to the famous Flash keyframe editor. It is extremely useful in creating polished games and throughout later parts of this book we will use the <span>SpriteBuilder</span> timeline to create UI and game animations.</p>
<p>Timelines can either be idle or playing. Timelines start playing in one of three cases:</p>
<ol>
<li><p><em>Autoplay</em> is activated. That’s the default setting for the <em>Default Timeline</em></p></li>
<li><p>The timeline is triggered to play from code</p></li>
<li><p>The timeline has been chained to another timeline</p></li>
</ol>
<p>We’ll discuss each of these three cases as we use the timeline feature throughout this book.</p>
<p>You will get to know the value of <span>SpriteBuilder</span>s timeline as we add more features to our game.</p>
<h4 id="adding-the-sound-effect-to-a-timeline">Adding the sound effect to a timeline</h4>
<p>For now let’s take a look at how we can play sound effects using the timeline!</p>
<p>Start by creating a new timeline for the sound effect as shown in the following screenshot:</p>
<div class="figure">
<img src="images/Chapter2/new_timeline_audio.png" alt="WAV files can be added by dragging them to the resource pane" />
<p class="caption">WAV files can be added by dragging them to the resource pane<span data-label="fig:audionewtimeline"></span></p>
</div>
<p>Now we can add the audio file to this new timeline.</p>
<p>Take a look at the next image and follow the individual steps below it:</p>
<p><img src="images/Chapter2/audio_timeline.png" alt="image" /></p>
<dl>
<dt>(1)</dt>
<dd><p>Drag the sound effect from the asset library in the left panel to the <em>Sound effects</em> row of <span>SpriteBuilder</span>’s timeline (the second row from the top). When the sound is added to the timeline it will be displayed in wave form.</p>
</dd>
<dt>(2)</dt>
<dd><p>You should adjust the duration of the timeline to match the duration of the sound effect. Click onto the time indicator to adjust the timeline duration.</p>
</dd>
<dt>(3)</dt>
<dd><p>In the popup that shows up next, change the timeline duration to 10 frames.</p>
</dd>
</dl>
<p>Now the sound is ready to play! The last step is assigning a unique name to this timeline which we can reference from code. You can rename a timeline by either choosing <em>Animation -> Edit Timelines…</em> or selecting the dropdown button next to the timeline name.</p>
<p>Rename the sound timeline to <em>DropSound</em>[timeline<sub>r</sub>ename].</p>
<ol>
<li><p>Open the timeline editor dialog:</p>
<p><img src="images/Chapter2/edit_timeline.png" alt="image" /></p></li>
<li><p>Then rename the timeline by double-clicking onto the name:</p>
<p><img src="images/Chapter2/rename_timeline.png" alt="image" /></p></li>
</ol>
<p>Now everything is set up and you can hit the publish button in <span>SpriteBuilder</span>.</p>
<p>Publish the <span>SpriteBuilder</span> project and switch to <span>Xcode</span>.</p>
<h3 id="triggering-a-sound-effect">Triggering a Sound Effect</h3>
<p>Now we have set up the sound effect in <span>SpriteBuilder</span> and published the project, all that is left to do is to open the <span>Xcode</span> project and add code to play the sound effect as soon as an object falls below the screen boundary.</p>
<p>We are going to implement this in <em>SBBMainScene.m</em>. <span>Cocos2D</span> provides a very simple API call to run a timeline animation from code. The following line added to <span>SBBMainScene</span> will run the timeline animation and thus play the sound we added to the project:</p>
<pre><code>animationManager.runAnimationsForSequenceNamed("DropSound")</code></pre>
<p>The animation manager of the root node of a <span>CCB File</span> provides us access to the different timelines and allows us to run and pause them and to react to their completion - we will use these capabilities extensively throughout this book.</p>
<p>As mentioned earlier we want to play the sound effect when an object falls off the screen. We already have code that checks for that condition in our <span>update</span> method. All we need to do this to add the line that runs the timeline.</p>
<p>Extend the relevant part of the <span>update</span> method to look as following:</p>
<pre><code>// check if falling object is below the screen boundary
if (CGRectGetMaxY(fallingObject.boundingBox()) < CGRectGetMinY(boundingBox())) {
// if object is below screen, remove it
fallingObject.removeFromParent()
fallingObjects.removeAtIndex(i)
// play sound effect
animationManager.runAnimationsForSequenceNamed("DropSound")
} else {...}</code></pre>
<p>Now you can compile and test the project. Every time an object falls of the screen you should hear the drop sound play!</p>
<h2 id="summary-1">Summary</h2>
<p>In this chapter you have learned how to work with an essential component of all video games - image and audio assets. You have learned how to design scenes with sprites in <span>SpriteBuilder</span>, and how to load and change sprite textures in code. You got to know how <span>SpriteBuilder</span> handles different asset resolutions for different screen and device types and you have played your first sound effect. You have learned some of the most important essentials of game development with <span>SpriteBuilder</span> and <span>Cocos2D</span>.</p>
<p>The focus of the next chapter is <em>User Interaction</em>. You will learn how to incorporate user input into your game by implementing a drag and drop mechanism!</p>
<h1 id="user-interaction">User Interaction</h1>
<p>In this chapter we will incorporate User Interaction into our game. First, we will add the player’s avatar, the pot, to the game. Then we will be implementing a drag and drop mechanism that lets the user move that pot in order to catch objects.</p>
<p>While implementing the drag and drop feature you’ll learn how <span>Cocos2D</span>’s touch system works in detail.</p>
<h2 id="add-the-pot-to-the-game">Add the Pot to the Game</h2>
<p>The goal of our game will be to move a pot across the screen and try to catch food while avoiding catching inedible objects. Before we can implement the drag and drop mechanism we need to add the pot assets to our game, we’re going to do that in the <span>SpriteBuilder</span> project.</p>
<p>Just as in the game we built in the very first chapter we are going to create an individual <span>CCB File</span> for this new entity. That way we can encapsulate its assets, behavior and animations nicely.</p>
<p>One important aspect of this game is the ability to for objects to fall into our pot. Since we are building a 2D game we need to fake the conception of depth in our scene. In <span>Cocos2D</span> we can use the z-order to influence which sprites are rendered in which order. Using that z-order, and using two assets for to create the pot, we can make it look like objects drop into the pot:</p>
<div class="figure">
<img src="images/Chapter3/drawing_order.png" alt="Left: Sprites rendered on different layers, Right: How the z-Order influences on which layer a sprite is rendered" />
<p class="caption">Left: Sprites rendered on different layers, Right: How the z-Order influences on which layer a sprite is rendered</p>
</div>
<p>It’s essential for this trick to break down the pot into two assets. Such rendering tricks are very common in 2D games!</p>
<h3 id="setting-up-the-pot-assets">Setting Up the Pot Assets</h3>
<p>Now that we know which assets we’ll use for the pot, let’s set up its <span>CCB File</span> in <span>SpriteBuilder</span>:</p>
<ol>