• No results found

Evaluation of Sprite Kit for iOS game development

N/A
N/A
Protected

Academic year: 2021

Share "Evaluation of Sprite Kit for iOS game development"

Copied!
56
0
0

Loading.... (view fulltext now)

Full text

(1)

Institutionen för datavetenskap

Department of Computer and Information Science

Final thesis

Evaluation of Sprite Kit for iOS game

development

by

Amaru Ubillus

LIU-IDA/LITH-EX-A--14/061--SE

2014-11-28

(2)

Linköping university

Department of Computer and Information Science

Final thesis

Evaluation of Sprite Kit for iOS game

development

by

Amaru Ubillus

LIU-IDA/LITH-EX-A--14/061--SE

2014-11-28

Supervisor: Anders Fröberg

Examinator: Erik Berglund

(3)

Abstract

The purpose with this thesis is to investigate whether Sprite Kit is a good tool to simplify the development process for game developers when making 2D games for mobile devices. To answer this question a simple turn based strategy game has been developed with Sprite Kit. Sprite Kit is a game engine for making 2D games released by Apple.

Based on the experience I got during the development I will go through and discuss some of the most important tools provided by the game engine and how they helped us to complete our game.

The conclusions I reached after making a game with Sprite Kit is that the frame-work provides all the tools necessary for creating a simple 2D mobile game for iOS. Sprite Kit hides much of the lower level details and gives the game de-veloper comprehensive development support. This helps the game dede-veloper to save a lot of time and focus more on the gameplay when creating a game.

(4)

Contents

1 Introduction 1 1.1 Background . . . 1 1.2 Purpose . . . 1 1.3 Problem . . . 2 1.4 Method . . . 2 1.5 Limitations . . . 2 1.6 Literature . . . 3 1.7 Structure . . . 3 2 Theoretical Background 4 2.1 Why to use a game engine? . . . 4

2.2 iOS game development: a history . . . 5

2.3 Introduction to Sprite Kit . . . 5

2.3.1 The game loop . . . 6

2.4 Sprite Kit basics . . . 7

2.4.1 SKScene . . . 8

2.4.2 Sprite Kit nodes . . . 8

2.4.3 SKActions . . . 9

2.4.4 Particle emitter editor . . . 10

2.4.5 Physics engine . . . 11

2.4.6 Texture atlases . . . 11

2.5 Game engine requirements . . . 12

2.5.1 Why we chose Sprite Kit . . . 13

3 Introduction to the game 14 3.1 A turn based strategy game . . . 14

3.2 The structure of the game . . . 14

4 Programming using Sprite Kit 18 4.1 Scene management . . . 18

4.2 Rendering . . . 20

4.2.1 Adding a sprite using OpenGL ES and GLKit . . . 21

4.2.2 Adding a sprite using Sprite Kit . . . 26

(5)

4.4 Actions . . . 30

4.5 Texture Atlases and Animations . . . 32

4.6 Physics systems . . . 37

4.7 Special effects . . . 39

5 Result 43

6 Discussion 46

(6)

Chapter 1

Introduction

1.1

Background

Today most of the games for mobiles are developed using an already existing game engine. Software tools are an important part of modern game development and improve the efficiency of making games by comprehensive development sup-port. There are a lot of different game engines to choose from when developing a game for iOS. Which game engine to choose for the next project can be a difficult choice and depends on many different factors.

Not long ago Sprite Kit was announced as Apple’s rendering engine for games along with iOS 7 at the past Worldwide Developers Conference (WWDC) on June 10-14, 2013 [1]. Sprite Kit is a graphics framework based on Objective C for developing all sorts of 2D games for iOS and OS X. It comes with much functionality that is useful for games, including rendering sprites on the graph-ics hardware, support for basic sound playback, physgraph-ics simulation, animations and many other features.

As a student at Link¨oping University I have studied many programming courses and have now decided to start develop my own game together with a friend. The plan is to make an attractive 2D multiplayer strategy game and later even launch the game on the App Store. Sprite Kit is planed to be used as the game engine for our game.

1.2

Purpose

The aim for this report is to investigate Sprite Kit, and how the game engine can be used to simplify the development process for developers. What tools does the framework provide and in which way does the tools help the programmer to more easily create games? What are the benefits of using Sprite Kit in terms of time saved and code complexity? The main technologies commonly included

(7)

in mobile game engines to be discussed in this thesis is: • Scene management

• Rendering • HUD Rendering • Actions

• Texture atlases and animations • Physics systems

• Special effects

Each of these technologies will be explained and discussed more in detail in the following sections.

1.3

Problem

There are a lot of game engines to choose from when developing a game and to find one that suits all the requirements for a specific game can be a hard match. Sometimes it can be even better to build your own game engine if you have special needs. This report present a game engine used for developing 2D mobile games for iOS and OS X.

1.4

Method

A game targeting iPhones and iPads will be implemented from scratch using Sprite Kit as the game engine. My personal experience working with the game engine will be documented and analyzed unrelated to other game engines. Ex-perience will be obtained trough development and literature and a subjective view on the workflow and programming with Sprite Kit will be presented.

1.5

Limitations

This report will entirely be focusing on Sprite Kit and no other game engines or third-party applications will be compared to Sprite Kit or taken into account. Also the implementation of the game must be delimited to the time for the master thesis. The goal is to have an almost complete game created with Sprite Kit at the time when the work is finished. To achieve this all the desired functionality can not be implemented straight away. It is important to keep the game simple and clean in the beginning and make room for further development according to time.

(8)

1.6

Literature

The literature is collected from articles containing people’s opinions about Sprite Kit in the game community and from Apples official documentation about Sprite Kit. Some of the literature is also taken from ACM and IEEE, from research on mobile game engines and what game developer expect and need when developing their games. Finally the book ”iOS Games by tutorials” by Ray Wenderlich is used as an reference. The chosen literature is shown at the Bibliography and is the foundation for the report.

1.7

Structure

Chapter 1: Introduction - This chapter presents the background and the purpose of the thesis. The problem and the approach are also described as well as the limitations that have been done.

Chapter 2: Theoretical Background - In this chapter the reader is given a theoretical background for help in understanding certain concepts. The reader will also get a better understanding of Sprite Kit, how it works and what it offers. Chapter 3: Introduction to the game - In this chapter a brief descrip-tion of our implemented game will be presented. What type of game it is and how it is structured.

Chapter 4: Programming using Sprite Kit - This chapter describes how the tools in Sprite Kit can be used to help in the development process, and how I implemented some of them in our game. Some alternative methods for adding sprites and actions without Sprite Kit are also presented.

Chapter 5: Result - This chapter describes the result after the implemen-tation is finished. Some suggestions for future work are also presented.

Chapter 6: Discussion - In this chapter I will discuss how I felt it was to work with Sprite Kit and reflect on my own personal experiences with the game engine. I will also take up some pros and cons.

Chapter 7: Conclusion - In this last chapter I will answer my questions based on the experience I have gained during the project. Is Sprite Kit a good game engine for game development?

(9)

Chapter 2

Theoretical Background

2.1

Why to use a game engine?

Jonathan Blow [3] mention that in recent years games have become more com-plex and now the primary technical challenge is simply getting the code to work to produce an end result. There is such a wide variety of algorithms to know about and so much work overall that is just needs to be done to make a game. When making a game there are different levels of programming. Gameplay code control the overall content rules, and high-level behavior of the game. Sit-ting below gameplay code is the engine, which provides all the basic mechanisms for simulation and I/O. Engine code is more difficult to write than gameplay code because it requires advanced knowledge and must be held to more strin-gent quality and performance standards.

To reduce the workload when making a game, game engines exist to take care of the engine code. According to a study made by Kasurinen et al. [10] most of the interviewed game developing organizations use complex third party com-ponents such as game engines, allowing the development team to focus on the gameplay code and game core functionalities. Jingming Xie [7] adds that the mobile market is growing quickly and it is full of competition. This makes the speed and quality of developing a mobile game to important factors considered by game companies. Game engines can improve the efficiency of making games by comprehensive development support.

(10)

2.2

iOS game development: a history

In early days, the only option to make a game for iOS was with OpenGL ES, which is a lightweight subset of desktop OpenGL. The API is optimized for the mobile platforms and is the lowest-level cross platform API used to program 2D and 3D graphics on the iPhone [10]. For many people just starting with game development OpenGL ES could be a big barrier to entry. To solve this problem third-party developers released game frameworks such as Cocos2D, Sparrow, Corona, or Unity that is some popular frameworks built on top of OpenGL. Many of the games at the top of the App Store charts were made with these frameworks, and for many developers some of these frameworks was their entry point into the world of game development.

Since none of these frameworks was written or supported by Apple there could be problem when new versions of iOS where released, or with integrating other Apple API’s into the system. To resolve this, with iOS7 Apple released a brand new framework for making 2D games: Sprite Kit. Its API is very similar to Co-cos2D, with similar types for the sprites, actions and scenes as used in Cocos2D. So people that already have experience with Cocos2D should have no problem to learn Sprite Kit.

2.3

Introduction to Sprite Kit

Sprite Kit is fully supported by Apple and heavily optimized to make 2D games for both iOS and OSX. Sprite Kit empowers the developer to build fully featured games using Objective-C. The framework provides a graphics rendering and animation infrastructure that can be used to animate arbitrary textured images, or sprites. It uses the graphics hardware available on the hosting device to composite 2D images at high frame rates [2]. Sprite Kit also provides other functionality that is useful for games such as basic sound playback support, an action system, the possibility to render text and a built in physics engine. In addition, Xcode provides built-in support for Sprite Kit and a particle emitter editor is built into Xcode as an inspector in the right pane that make it possible to create complex particle effects to your game directly in Xcode.

(11)

2.3.1

The game loop

Behind the scenes Sprite Kit runs an endless loop, often referred to as the game loop, which looks like this:

Figure 2.1: The Sprite Kit game loop [2]

Each individual picture that you draw is called a frame. Games typically try to draw frames between 30 to 60 times per second so that the animations feel smooth. For each frame Sprite Kit does the following as shown in figure 2.1:

1. Calls a method on your scene called -update: which runs to every frame. This is the place to put code that you want to run every frame. It is a good spot for checking victory or lose conditions and update the position or rotation of your sprites.

2. Sprite kit comes with many built in actions which allows the programmer to rotate, scale or change a sprite’s position over time with just one line of code. These actions are evaluated after the update method. Code for collision detection is therefore best to place in the -didEveluateActions method after Sprite Kit has evaluated the actions and all the sprites are in their new positions.

3. After executing update: and evaluating the actions, and just before ren-dering the sprites onscreen, Sprite Kit performs the physics simulations and move the sprites accordingly. After this occurs, there is a chance to perform any code you might like in the -didSimulatePhysics method. This can be code that you want to use to check for conditions or positions of your sprites every frame after the physics engine has done its job. 4. Finally Sprite Kit draws all of the objects that are in your scene graph.

(12)

for the programmer. Sprite Kit tries to draw frames as fast as possible, up to 60 FPS (frames per second). But if the update method is to slow due to heavy algorithms or if Sprite Kit has to draw more sprites at once than the hardware can handle, the frame rate might decrease.

2.4

Sprite Kit basics

When using Sprite Kit nodes are the main building blocks for all content. Ev-erything that appears on the screen in Sprite Kit derives from a class called SKNode. The SKNode has no size or contents itself but the position, rota-tion, scale, alpha and other attributes as seen in figure 2.2 can be set.

Figure 2.2: SKScene and SKSpriteNode inherits from SKNode [2]. SKNode can also be used to organize other nodes such as using multiple layers to separate the background and gameplay nodes. Also by setting properties such as scale, position and visibility on a SKNode will influence all of its child nodes. Hiding or changing the position of a parent node will hide or change the positions of all its children.

Animation and rendering is performed by an SKView object that is responsible for displaying content on the screen. Contents in your game are organized into scenes. A scene holds sprites and all the other content to be rendered which are represented by SKScene objects.

(13)

2.4.1

SKScene

SKScene inherits from SKEffectsNode which inherits from SKNode. Only one scene can be presented at a time, and when your scene is presented by the SKView, the Sprite Kit game loop begins and processes each frame in the order shown in section 2.3.1.

2.4.2

Sprite Kit nodes

As mention in section 2.4 everything that appears on the screen in Sprite Kit derives from a class called SKNode. The following nodes are all available in Sprite Kit and derives from SKNode. The first three nodes are the most common and used in almost all games created with Sprite Kit. The four later nodes are more advanced types of nodes used for adding cool and unique effects into your game:

1. SKSpriteNode: This node is the most common SKNode subclass that are used when building a game with Sprite Kit. The node draws textures from images ”sprites” or a colored square or a textured image blended with a color.

2. SKLabelNode: This node is another common node used for displaying text as a sprite in a single line. It support all the system fonts, custom fonts and will also respond to any SKAction just like other nodes that derive from SKNode.

3. SKEmitterNode: This node creates and render particle systems. The particles are owned by Sprite Kit and cannot be accessed directly. Emit-ters can either be coded or created using the Particle Emitter Editor. 4. SKCropNode: This node allows the programmer to apply a mask to

a node or node tree, effectively ”cropping” its children to only display a certain area.

5. SKVideoNode: This node allows the programmer to play video content right within your games by simply pass in the URL of the video to play or initialize it with an AVPlayer.

6. SKShapeNode: This node draws an arbitrary shape from a CGPath path. It is possible to apply different colors and glow to the stroke and fill the path.

7. SKEffectNode: This node allows the programmer to apply special effects to its children nodes. It applies a filter effect to an image and can modify a sprite’s vibrance, hue, blur or exposure.

(14)

2.4.3

SKActions

SKActions are used to perform the sprites animations and to play sound ef-fects. SKActions can be applied to any of the nodes mention above in section 2.4.2 in order to rotate, scale or change the nodes position. The SKActions are designed to make it easier to do things that would normally require the programmer to write a lot of code if he were to roll these actions by himself. The SKActions can also be grouped (run in parallel), sequenced (run serially), repeated and some can even be reversed. Some of the most common groups of actions are described below:

1. Move actions: These actions are used to change a sprites x and y posi-tions to move a sprite to a particular point in space. These acposi-tions also allow the programmer to specify a change in only the x or y position where the other axis is assumed to remain the same.

2. Sequence action: The real power of actions lies in how easily they can be chained together. The sequence action is one of the most useful and commonly used actions when programming with Sprite Kit. The sequence action will run one action after another, which allows for more complex behavior.

3. Group action: Sometimes the programmer do not want to run actions in sequence and instead run two actions at the exact same time. For this sort of multitasking the group action can be used. It works similar to the sequence actions where you pass in a list of actions. But instead of running them one at time, a group action runs them all at once.

4. Reversed action: This actions gives the possibility to reverse certain actions in Sprite Kit. It results is a new action that is the opposite of the original action. For example, if you run a move action on a sprite, it is possible to run the reverse of that action and the sprite will go back to where it came from to its original position. Notice that not all actions are reversible in Sprite Kit.

5. Repeat actions: These actions are used to repeat an action a certain number of times or an endless number of times by repeating an action forever.

6. Animation action: This action is used for adding animations to your sprites which is an easy way to add a lot of polish and fun to your game. To run an animation action, you first need to gather a list of textures that will make up the frames for the animation. A sprite has a texture assigned to it, but you can always swap out the texture with another. That is exactly what the animation action does, it swap out your sprite’s texture over time, with a short delay between each frame.

7. Sound action: This action are the one that plays sound effects. Note that the node on which you run this action does not matter. Normally the action runs as an action on the scene itself.

(15)

2.4.4

Particle emitter editor

Particle system are designed to create special effects in your game and can be used for a wide range of special effects like the smoke effect shown in figure 2.3

Figure 2.3: Smoke made with the Sprite Kit.

Table 2.1: Shows just a few effects you might simulate with particle systems:

smoke water fog

star fields snow rain

fire explosions magical potions

sparks blood bubbles

As seen in tabel 2.1 it is impossible to imagine all you could do with particle system, it pays to be creative.

With particle systems, the special effects are generated by one small texture and a configuration file, greatly reducing the memory requirements and allow-ing real-time editallow-ing. A particle is two triangles drawn together to create a quad. This quad is then textured, colored and rendered to the screen. During each frame, the particle system looks at each individual particle it owns and advances it according to the systems configuration.

To achieve a special effect like this without particle systems, you will have to make a traditional frame-by-frame animation, which would require many images taking up much texture space and memory requirements.

(16)

A particle emitter editor is built into Xcode as an inspector in the right pane. It renders the emitter live in an SKView so that the programmer can make changes to the emitter and see the result live as he tweak its properties.

2.4.5

Physics engine

As mention earlier sprites can be moved around by running actions on them. But what if the programmer wants to simulate real-life behavior, like bouncing, collisions and other physical phenomenas? It is possible to accomplish this with a lot of mathematical equations that will require a lot of code, but there is an easier way. Sprite Kit has a built in physics engine that can be used to make objects move in a realistic way.

Under the hood, Sprite Kit uses an open source library called Box2D to perform all the physics calculations. The library is used by many other popular game engines and games for iPhone, Android, BlackBerry, Nintendo DS, Wii, OSX and Windows. However Apple does not expose Box2D directly - instead, it abstracts it behind its own Objective-C API calls in Sprite Kit. The reason for this seems to be because Box2D are written in C++ rather than Objective-C, and that the library could stand to be more user-friendly for beginning devel-opers. As seen in figure 2.4 Box2D is walled so well that Apple could change the physics engine in a later version of iOS and the most programmer would probably not notice a thing.

Figure 2.4: In Sprite Kit you get access to Box2D through a friendly, polished Apple-style API [15].

2.4.6

Texture atlases

A texture atlas is a single image file made up of many smaller image files. Im-age location within the atlas is mapped in an atlas plist. Packing imIm-ages into a texture atlas will bring many benefits. The main advantage of using tex-ture atlases is that it decreases your game’s memory usage. Since memory is an expensive resource on iOS devices it is very important to keep the memory

(17)

as low as possible for your game apps. The iPhone 4S has for example only 512MB memory versus 4GB+ on laptop computers. The more you can reduce the memory requirements, the faster your app will run and it will prevent your app from crashing due to insufficient memory. When memory gets low, iOS ter-minates apps that are running in the background, beginning with the largest. By decreasing your memory requirements, you decrease the chances of iOS ter-minating your app when it is in the background.

Above and beyond the performance boost you get from using less memory your app will also use fewer OpenGL calls. To draw a texture on the screen with OpenGL, there are two steps:

1. Bind the texture: First OpenGL needs to make the texture you want to use active. This is called binding the texture.

2. Draw the texture: Then OpenGL draws the texture this is two expensive operations.

If you are just using sprites directly, every time you draw a sprite you have to perform both of these steps. Since both of these calls are expensive, once you have a lot of sprites in your game your games frame rate will drop as the GPU spends more and more time binding and drawing the individual textures. Since texture atlases combine all of your sprites into a single larger image, you only need about one bind call and one draw call total for all the sprites that are part of the texture atlas. With fewer OpenGL calls, your game runs faster.

Sprite Kit comes with texture atlas support built into Xcode 5.

2.5

Game engine requirements

There are several game engines out there today. To know which one to choose can be a hard choice and depends on the needs and requirements for the game. The game covered by this thesis is a turn based strategy game designed for iOS devices. More detailed information about the game will be found in chapter 3. The following technical requirements has been taken into account and must be fulfilled by our game engine:

• Build fully featured, high quality games for iOS. • Free to use (or with a very low onetime cost). • Well written official documentation.

(18)

2.5.1

Why we chose Sprite Kit

Sprite Kit fulfills all the criterias mention in section 2.5. The framework use Objective-C to create games for iOS and render 2D frames at high frame rates using the device’s (iPhone,iPad, Macbook Pro etc.) graphics processor. Sprite Kit is also free to use and the only thing the programmer needs to publish a game on App Store, and to test it on an actual device, is an Apple developer license for $99 dollars.

In conjunction with the release of Sprite Kit, Apple also launched Sprite Kit programming guide which is Apples official documentation containing a lot of information and coding examples about how program with Sprite Kit. Ray Wendrich [16] has also published many tutorials for Sprite Kit on his website which is a good place for beginners (but even more advance users) to start look-ing for programmlook-ing examples. Some of those tutorials are summarized and forms a part of the book iOS games by tutorials [15], which is a good book for programmer starting with iOS game development and want to increase their knowledge in how to work with Sprite Kit.

According to Nils Kbler [11] simplicity is also something that characterizes Sprite Kit and it seems to bee very straight forward and easy to jump right into. The API is intuitive and easy to use where game objects are organized in a tree structure and every object inherits from SKNode.

There are also other game engines that fulfills the criterias mention in sec-tion 2.5. The game engine most similar to Sprite Kit is Cocos2D that also uses objective C to create games for iOS. Unity 2D is another good game engine that provides the developer with many good tools for creating 2d games for different platforms. The reason why Sprite Kit was chosen was because it was new and just released at the time when the development of the game for this thesis started. Since we wanted to try something new and focused mainly on development for iOS 7 and higher we decided to try Sprite Kit.

(19)

Chapter 3

Introduction to the game

3.1

A turn based strategy game

The game is a turn based strategy game where players take turns when playing. This is distinguished from real time strategy where all players play simultane-ously. Chess is widely considered the ultimate turn-based strategy game as it is one of the oldest and most competitive games of its kind [8]. Turn-based tactical gameplay is characterized by military tactics, in general small-scale confronta-tions. The player has to make smart moves and think carefully before moving his units. It is also important to keep in mind what will happens next after your move, to always make it more difficult for your enemy to strike back. The Heroes of Might and Magic series [14] has been one of the biggest sources of inspiration for the game. Especially the old and popular games Heroes of Might and Magic II and III.

3.2

The structure of the game

The goal was to implement a turn based strategy game adapted for iPhones and ipads. One thing that had to be taken into consideration is that the screen sizes of those devices are smaller compared to laptop computers and instead of mouse they use touch for navigation and interaction. The game must therefore be designed to fit those criterias which made us to make the game as simple and clean as possible to fit the requirements for the selected platforms.

To create a simple architecture for the game a decision was made that the game should consist of three main scenes:

(20)

• The map scene: When the player first enters the game this is the first scene displayed. The scene is shown in figure 3.1 and all the other scenes can be accessed from this one.

Figure 3.1: The map scene

The scene can be seen as a map of the world where the player constantly returns after battles to advance in the game and to move on to higher levels. The scene helps the player to get an overview of the game and to navigate to other more important scenes.

(21)

• The battle view: After the player has selected a level from the map scene the player will enter this scene. This is the scene that contains the core gameplay and where the player spends most of the time while playing our game. The scene is shown in figure 3.2 and it is here where the battles are determined.

Figure 3.2: The battle scene

The turn-based tactical gameplay described in section 3.1 take place in this scene and the players move their units in turns in order to knock out the units of the opponent’s army. The scene will look slightly different depending on level and the enemy troops encountered.

(22)

• The castle scene: This scene is accessible from the map scene when the player hits the castle on the map. The scene is shown in figure 3.3 and this is the place where the player can buy and upgrade new units and items to be used for the battles.

Figure 3.3: The castle scene

For the moment the scene contains two different shops. One training camp for unlocking, buying and upgrade the units that later are used in the battle scene. And another shop for buying items that can be used together with the units to give them advantages in battles.

(23)

Chapter 4

Programming using Sprite

Kit

As mention in section 1.2 the purpose of this thesis is to investigate how Sprite Kit can be used to simplify the development process for programmers. Jingming Xie [7] mention that the main technologies in game engines commonly include scene management, rendering, physics systems, etc. The following sections will discuss them and some other technologies that I find important when making a 2D game for mobile devices.

4.1

Scene management

A scene manager manages the game objects, organizes their relationships and is simply handling replacing one scene with another. Various types of games makes it hard to design a data structure suitable for all games. A tree structure is the most commonly used method [7] also used by Sprite Kit [2]. The point of having a scene manager is to provide a reusable starting point for the game. Scenes are the visual layers of the game that act as a parent container for all other visible nodes in the scene. In every game there are multiple scenes. In our game there are at least tree scenes described in section 3.2. Multiple scenes helps the game developer to get a better organization and overview of the game. It also helps to break apart the code into manageable chunks where each scene contains discrete bits of game logic. As mention in section 2.4.1 SkScene is the main object used to draw other objects in Sprite Kit. SkScene is the root node in a tree of Sprite Kit nodes. [2]

When creating a new project using the ”Sprite Kit Game Template” (figure 4.1) a storyboard with a view controller, and a view set to SKView is created for you. The project game template will also create header and class files called MyScene.h and MyScene.m that derives from SKScene.

(24)

Figure 4.1: The battle scene

These are the main files for the programmer to work with when building a game. The files can be renamed and other set of scene files can also be added to your game. To create a new set of scene files to your game, you simply create a new class that derives from SKScene. Xcode will generate two new files for you, where you can implement the methods you want to get the desired functionality. In Sprite Kit only one scene can be visible and running at a time [5]. To navigate trough your game’s UI the current scene has to be replaced with a new one. The new scene is visible and old scene is dead. Transition from one scene to another is easily done in Sprite Kit with the following steps: [15]

Listing 4.1: Transition between scenes 1 //1

2 SKScene ∗gameScene =

3 [[ GameScene alloc] initWithSize:CGSizeMake(1024, 768)]; 4 5 //2 6 SKTransition ∗reveal = 7 [SKTransition flipHorizontalWithDuration:0.5]; 8 9 //3

10 [self.scene.view presentScene:gameScene transition:reveal ];

1. First you create an instance of the scene itself. -initWithSize: is the custom initializer setting the size for the window.

(25)

2. Next you create a transition object that specifies the type of animation to display when the new scene is presented. There are cross fade transitions, flip transitions, door-opening transitions, and many more.

3. Finally you call the SKView’s presentScene:transtion: method where you pass in your scene and the transition created in the two earlier steps.

4.2

Rendering

Rendering generate an image of the objects. That includes primitives rendering, occlusion culling, texture mapping, model rendering, lighting, shading, LOD management, and HUD rendering, etc. Each of the above subjects can be di-vided as smaller sub-parts for proposing specific algorithms. For example, there are planar shadow, shadow volume and shadow map algorithms for shading. Gouraud, Phong and ray tracing algorithms are used to deal with lighting [7]. To simulate the world in games takes a large number of calculations. OpenGL ES is the subset of OpenGL, which is designed for mobile devices. OpenGL ES is the lowest-level API that is used to program 2D and 3D graphics on the iPhone [17]. Sprite Kit is built on top of OpenGL ES and contains everything developers need to write a 2D game from scratch, without having to worry about OpenGL. OpenGL is notoriously difficult to learn and you have to write a lot of code to get a simple game working. Because of this, many developers prefer to use an engine that allows them to deal with complex graphics in a discrete way, rather than having to worry about every triangle and lighting algorithm. Under the hood, all game engines designed for mobile devices use OpenGL ES, they just hide the lower level details from the programmer to make things simpler [15]. When making a 2D game, you usually put images on the screen representing your game’s hero, enemies, obstacles and so on. Each of these images is called a sprite. Figure 4.2 shows a scene from the game with all the containing sprites.

(26)

Figure 4.2: Many images are put on top of each other to create the map scene. The main sprites in the scene are identified.

The two following sections will present two different methods to programmati-cally add a sprite to your game. The first method, without the use of a game engine, which is more complex and require more code and experience. The sec-ond method demonstrates the benefits of using Sprite Kit which makes it easier and faster for programmers to add sprites to their games.

4.2.1

Adding a sprite using OpenGL ES and GLKit

GLKit is a set of APIs that makes working with OpenGL ES on iOS much easier than it used to be. GLKit saves you from writing code regarding setting up a basic display, creating basic shaders, preforming vector/matrix math and loading textures. The following code examples in this section is taken from a OpenGL ES 2.0 and GLKit tutorial made by Wenderlich [15]

To add a sprite to your scene using OpenGL ES 2.0 and GLKit we must imple-ment a sprite class. Two new files named SGGSprite.h and SGGSprite.m is created. The SGGSprite.h contain the interface for our sprite class. The setup in listing 4.2 is the simplest possible.

(27)

Listing 4.2: SGGSprite.h 1 #import<Foundation/Foundation.h>

2 #import<GLKit/GLKit.h> 3

4 @interface SGGSprite : NSObject 5

6 − (id)initWithFile :( NSString ∗)fileName effect :( GLKBaseEffect ∗)effect; 7 − (void)render;

8

9 @end

We allow the user to specify the image file for the sprite to display, and the GLKBaseEffect (shader) that will render it. We also define a routine that the GLKViewCintroller will call to render the sprite.

The SGGSprite.m contains most of the code for our sprite class. We start at the top of the file shown in listing 4.3

Listing 4.3: SGGSprite.m 1 #import”SGGSprite.h” 2 3 typedef struct { 4 CGPoint geometryVertex; 5 CGPoint textureVertex; 6 } TexturedVertex; 7 8 typedef struct { 9 TexturedVertex bl; 10 TexturedVertex br; 11 TexturedVertex tl; 12 TexturedVertex tr; 13 } TexturedQuad;

At the top line the header file is imported, and next some structures needed to store information about the sprite is created. The TexturedVertex is a structure that will keep track of the information we need at each corner of the sprite. The second structure, TexturedQuad, contains 4 TexturedVertex structures, one for each corner.

After defining the data structure that hold the geometry and texture vertex values we have to set it up. This is shown in listing 4.4

(28)

Listing 4.4: SGGSprite.m 1 @interface SGGSprite()

2

3 @property(strong) GLKBaseEffect ∗ effect; 4 @property(assign) TexturedQuad quad;

5 @property(strong) GLKTextureInfo ∗ textureInfo; 6

7 @end

8

9 @implementationSGGSprite 10 @synthesize effect = effect ; 11 @synthesizequad = quad;

12 @synthesizetextureInfo = textureInfo;

Here we define an synthesize three private properties:

1. GLKBaseEffect * effect: The effect (shader) that we will use to render the sprite.

2. TexturedQuad quad: The instance of our TexturedQuad structure. 3. GLKTextureInfo * textureInfo: We are going to use GLKits

GLK-TextureLoader class to easily load our texture. It will return some info about the texture that is stored here.

We continue on by adding this next:

Listing 4.5: SGGSprite.m

1 − (id)initWithFile :( NSString ∗)fileName effect :( GLKBaseEffect ∗)effect { 2 if ((self = [super init ]) ) {

3 // 1

4 self. effect = effect ; 5

6 // 2

7 NSDictionary ∗ options = [NSDictionary dictionaryWithObjectsAndKeys:

8 [NSNumber numberWithBool:YES],

9 GLKTextureLoaderOriginBottomLeft,

10 nil];

11

12 // 3

13 NSError ∗ error;

14 NSString ∗path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];

15 // 4

16 self. textureInfo = [GLKTextureLoader textureWithContentsOfFile: path options:options error:&error];

(29)

18 NSLog(@”Error loading file: %@”, [error localizedDescription ]) ; 19 return nil;

20 }

21 // TODO: Set up Textured Quad

22 }

23 return self; 24 }

Here we create the initializer for our class:

1. Stores the GLKBaseEffect that will be used to render the sprite. 2. Sets up the options so that when we load the texture, the origin of the

texture will be considered the bottom left.

3. Gets the path to the file we are going to load. The filename is passed in. Note that if you pass nil as the type, it will allow you to enter the full filename in the first parameter.

4. Finally loads the texture with the GLKTextureLoader class. Next this is added after the TODO in listing 4.5:

Listing 4.6: SGGSprite.m 1 TexturedQuad newQuad;

2 newQuad.bl.geometryVertex = CGPointMake(0, 0);

3 newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0); 4 newQuad.tl.geometryVertex = CGPointMake(0,self.textureInfo.height); 5 newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width,self.

textureInfo.height); 6 7 newQuad.bl.textureVertex = CGPointMake(0, 0); 8 newQuad.br.textureVertex = CGPointMake(1, 0); 9 newQuad.tl.textureVertex = CGPointMake(0, 1); 10 newQuad.tr.textureVertex = CGPointMake(1, 1); 11 self.quad = newQuad;

Were going to fill in the TexturedQuad (and its four TexturedVertex) struc-ture with values based on the size of the sprite we are displaying:

(30)

Figure 4.3: This fills in our quad as described in listing 4.6.

Note that the texture vertex values will be the same no matter what sprite you use, since we always want to map the texture the same way with respect to the various corners. The geometry vertex values will change though, based on the size of the texture.

The final bit to add for our sprite class:

Listing 4.7: SGGSprite.m 1 − (void)render {

2

3 // 1

4 self. effect .texture2d0.name =self.textureInfo.name; 5 self. effect .texture2d0.enabled =YES;

6

7 // 2

8 [self. effect prepareToDraw]; 9 10 // 3 11 glEnableVertexAttribArray(GLKVertexAttribPosition); 12 glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 13 14 // 4

15 long offset = (long)& quad;

16 glVertexAttribPointer(GLKVertexAttribPosition, 2, GL FLOAT, GL FALSE,sizeof(TexturedVertex), (void∗) (offset + offsetof( TexturedVertex, geometryVertex)));

17 glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL FLOAT, GL FALSE,sizeof(TexturedVertex), (void∗) (offset + offsetof( TexturedVertex, textureVertex)));

(31)

19 // 5

20 glDrawArrays(GL TRIANGLE STRIP, 0, 4); 21

22 } 23 24 @end

1. When you use a GLKBaseEffect to render geometry, you can spec-ify a texture to use for the drawing. You do this by setting the tex-ture2d0.name to the textureInfo.name, and setting texture2d0.enabled to YES.

2. Before you draw anything, you have to call prepareToDraw on the GLK-BaseEffect.

3. There are two pieces of information we want to pass to the effect/shader: the position and texture coordinate of each vertex. We use this function to enable us to pass the values through.

4. Next we need to actually send each piece of data. We do that via the glVertexAttribPointer method. For example, the first function says I want to send some position values. Im going to send 2 floats over. After you read the first two floats, advance the size of the TexturedVertex structure to find the next two. And heres a pointer to where you can find the first vertex.

5. Finally, we draw the geometry, specifying 4 vertices of data drawn as a triangle strip.

This sprite class is now complete and ready to use in order to draw a simple sprite to the screen.

4.2.2

Adding a sprite using Sprite Kit

Sprite Kit has a special class that makes it easier to create and work with sprites, called SKSpriteNode. So instead of writing your own sprite class like the example in the previous section, the programmer can use SKSpriteNode to add all the sprites to the game.

To add a sprite to a Sprite Kit scene is very simple. You just use the spriteN-odeWithImageNamed: method, and pass in the name of the image as seen in listing 4.8. Finally you call addChild: to add it as a child of the scene, or one of the scenes descendent nodes [2].

Listing 4.8: Adding a sprite in Sprite Kit 1 SKSpriteNode ∗bg =

2 [SKSpriteNode spriteNodeWithImageNamed:@”background”]; 3 [self addChild:bg];

(32)

Note that you don’t need to pass the image’s extension. Sprit Kit will by default look for png images, so the extension is not necessary. If your images are in other formats, such as jpg, you will need to add the extension [15]. So what took us a tremendous amount of code to achieve with OpenGL ES 2.0 and GLKit can be done with Sprite Kit with only 2-3 lines of code. All the sprites in our game is added with SKSpriteNodes.

4.3

HUD rendering

In games, the term HUD takes it name from the head-up displays used in modern aircraft. The HUD is the method by which information is visually conveyed to the player as a part of a game’s user interface. The HUD is frequently used to simultaneously display several pieces of information including, how much health the player has, items available, and an indication of game progression such as score or level. This makes the HUD an invaluable method of conveying information to the player during a game [18]. By looking at the map and castle scene in our game the HUD can be found in the left lower corner where an icon of the Hero is displayed as seen in figure 4.4.

Figure 4.4: The lower left corner of the map scene.

To the right of the hero icon a status bar is found displaying the gold collected and the level reached by the hero. The purple indicates your heros experience and the experience needed to reach the next level. Here the HUD layer is created with a green status bar and an icon of the hero which both are SKSpriteN-odes. The text on the other hand is created with an SKLabelNode which is perfect for displaying text as a sprite in a single line.

(33)

It is often useful in games to display text to help keep your player informed. SKLabelNode supports all the system fonts, custom fonts and derives from SKNode. Creating a label is easy as seen in listing 4.9 [15]

Listing 4.9: Adding a label in Sprite Kit 1 SKLabelNode ∗ label =

2 [SKLabelNode labelNodeWithFontNamed:fontName]; 3 label . text =@”your text here!”;

4 label . fontSize = 20.0;

5 label . position = yourPosition; 6 [self addChild:label ];

You simply call labelNodeWithFontName:, and pass in the name of the font. Then you set the text to what you want the font to display and the font size. Finally just lite other nodes, you can position it and add it as a child of another node or to the scene itself as in this case.

In the battle scene seen in figure 4.5 the Hud can be found in all the four cor-ners indicating buttons, to show the units health, the items available and which special abilities to use. All the buttons are created by receiving touch callbacks from SKSpriteNodes and also the health bar above the units is built up with SKSpriteNodes where each health indicator is an separate SKSpriteNode.

Figure 4.5: A popup shown in the battle scene

Popups are also used in the game to show information for the player as seen in figure 4.5. This popup shows specific information about the unit telling which

(34)

rank it belongs to. The basic attack damage, health, movement speed and the units special abilities can also be found under the icon. At the bottom of the popup an little description of the unit can be read .

Unfortunately SKLabelNode does not support multiline functionality which means that it is not possible to write more than one line of text. To write a longer text with line breaks, as the description of the unit at the bottom of the popup, without having to create many SKLabelNodes an DSMulti-lineLabelNode can be used. DSMultiDSMulti-lineLabelNode does not originally come with Sprite Kit but can be imported to your project by downloading an extended class created by Allwein [19]. DSMultilineLabelNode support all the properties and methods of SKLabelNode. The main difference to using an SKLabelNode is that you may specify the property paragrapWith as seen in listing 4.10

Listing 4.10: Adding a DSMultilineLabelNode 1 DSMultilineLabelNode ∗ textField =

2 [DSMultilineLabelNode labelNodeWithFontNamed:fontName]; 3 textField . text =@”your text here!”;

4 textField . fontSize = 20.0; 5 textField .paragraphWidth = 200; 6 textField . position = yourPosition; 7 [self addChild:textField ];

paragrapWith is the value in pixels as to how wide you want your label node to expand before creating new lines.

Drawing text seems quite easy when using SpriteKit but it is often a hard task without the use of an game engine for most beginning game developers. In openGL ES there is no API that renders text out of the box. This means you have to create one yourself. There are several methods one can use to render text on screen. Each has his advantages and its disadvantages. One common approach involves creating a font atlas texture, and then creating a quad for each letter with just the right placement and texture coordinates. Hollander [20] has written a article where he shows a basic implementation of this method with OpenGL ES 2.0. As can be seen by following the article there are more work and code needed to render text with that method, compared by using an SKLabelNode with Sprite Kit.

(35)

4.4

Actions

Drawing sprites is useful, but a static image is a picture and not a game. To add gameplay, you need to be able to move your sprites around the screen and perform other logic. An action is an object that defines a change you want to make to the scene. If you want to move a sprite across the screen, you create a move action and tell the sprite node to run that action. Sprite Kit will then animate that sprite’s position until the action completes.

As mention in section 2.4.3 Sprite Kit has a class called SKAction that can be used to move and change the positions of the sprites. In our game SKAction is used to move the hero between the different levels in the map scene. Also in the battle scene all the turn based movement on the hexagonal grid is done with SKActions. Animation effects occurring on the popups in our game is yet another way to use SkActions.

SKAction make it incredibly easy to do things that would normally require the programmer to write a lot of code. To create an action in Sprite Kit, you call one of several static constructors on the SKAction class. In listing 4.11 the constructor moveTO:duration: is called. This particular constructor returns an action that moves a sprite to a specified position, over a specified duration (in seconds) [15].

Listing 4.11: A move action 1 SKAction ∗actionMove =

2 [SKAction moveTo:CGPointMake(self.size.width/2,self.size.height/2) 3 duration :2.0];

4 [ sprite runAction:actionMove];

Here you set up the action to move the sprite to the center off the screen at whatever speed is necessary to take it from its current position to the center in two seconds. Once an action has been created, you need to run it. You can run an action on any SKNode by calling runAction:, as you did in the above code. This can also be done manually in Sprite Kit without the use of SKAction. You might then update the sprites position each frame according to a velocity. This requires more work and to show how this is done in Sprite Kit we add the following new method [15]:

(36)

Listing 4.12: Moving a sprite manually

1 − (void)moveSprite:(SKSpriteNode ∗)sprite toward:(CGPoint)location velocity:(CGPoint)velocity

2 {

3 // 1

4 CGPoint offset = CGPointMake(location.x − sprite.position.x,

5 location .y − sprite . position .y);

6 // 2

7 CGFloat length =

8 sqrtf ( offset .x ∗ offset .x + offset .y ∗ offset .y); 9

10 // 3

11 CGPoint direction = CGPointMake(offset.x / length,

12 offset .y / length) ;

13 velocity =

14 CGPointMake(direction.x ∗ velocity.x, 15 direction .y ∗ velocity .y); 16 }

1. First the offset between the new location you want to reach, and the location of the sprites current position, need to be figured out. You get this by simply subtracting the sprites position from the new position. By subtracting these two positions, you get something with a direction and length, the offset vector.

2. The next step is to figure out the length of the offset vector. You can think of the offset vector as the hypotenuse of a triangle, where the lengths of the other two sides of the triangle are defined by the x and y components of the vector. To find the length of the hypotenuse Pythagorean theorem can be used. Put this theory into practice and the following line can be added.

3. The offset vector is converted to a unit vector, which is a vector of length 1. Dividing the offset vectors x and y components by the offset vectors length does this. The vector is now normalized, and once we have the unit vector it is easy to multiply it by a velocity to make it to the desirable length.

Finally to use this method it has to be placed inside the update: method according to the Sprite Kit game loop in section 2.3.1. Then the sprites position will be processed each frame. The method can be called with one line as seen in listing 4.13

Listing 4.13: Calling the moveSprite method

1 [self moveSprite: sprite towards:CGPointMake(size.width/2, size.height/2) velocity:CGPointMake(120, 0)];

(37)

The purpose of SkActions is to assist the programmers, and provide them with a set of actions that is frequently used in game development. If you have an action that is used repeatedly in your game, a single instance of the action can be created and reused whenever you need a node to execute it.

4.5

Texture Atlases and Animations

A good game cannot only be fun to play it also needs to preform well. The players expect a smooth frame rate while they play without any disturbance. One of the most important optimizations you can make to your game is to use texture atlases. In our game almost every sprite belongs to a texture atlas. We have three larger texture atlases for all the objects in our three game scenes described in section 3.2. As well as one extra texture atlas that contains all the elements for the popup windows. Since all the units is our game consist of separate body parts used for animations each individual unit also has its own texture atlas.

As mention in section 2.4.6 Sprite Kit comes with texture atlas support built into Xcode 5.

A texture atlas can be created by doing the following [5]:

1. Turn on atlas generation. When using the Sprite Kit Project Template, the Enable Texture Atlas Generation build setting is automatically set to YES. In this case, it is not necessary to manually set this yourself. 2. Place all your related image files into a folder on disk called .atlas 3. Drag the folder into your Xcode project

The files in the .atlas will be processed and available for use right away. When compiled in the bundle, the folder will have a .atlasc extension. When the project is built, the following occurs:

1. Textures are automatically combined

2. Automatic image rotation for maximum packing 3. Transparent edges are trimmed

4. Hardware specific atlases are generated

5. According to Apples documentation [2], the maximum texture atlas size is 2000x2000 pixels. If more images than can fit 2000x2000 are put into a texture atlas, Xcode will create additional texture atlases until all images in the .atlas folder are inside an atlas. A single plist file will be created. The generated atlas will look something similar like figure 4.6

(38)

Figure 4.6: A texture atlas of the objects in the map scene

You will see the images packed nice and tight along with a .plist file that has descriptive information for each of the packed images including the location of each image within the single image file. All this helps to improve developer iteration time. Just utilizing texture atlases can save hundreds of megabytes. Texture atlas references are tracked in memory; when the developer decides to load the same texture, the in-memory texture is used. Loading an image from a texture atlas is almost the same as loading a standalone image as seen in listing 4.14 [15].

Listing 4.14: Loading an image from a texture atlas 1 SKTextureAtlas ∗mapAtlas =

2 [SKTextureAtlas atlasNamed:@”map”];

3 SKTexture ∗ texture = [mapAtlas textureNamed:@”castle”]; 4 SKSpriteNode ∗ castle =

5 [SKSpriteNode spriteNodeWithTexture:texture];

You can use the SKTextureAtlas class to get a reference to a specific texture atlas and the SKTexture class to get a reference to a particular texture within a texture atlas. Then you can create a SKSpriteNode from that texture to have fine-grained control over which texture atlas a sprite comes from.

Adding animations is a super easy way to add a lot of polish and fun to your game. There are various ways to animate your game sprites. The most common method supported by Sprite Kit is to run an animation action as described in section 2.4.3. This method is called frame-by-frame animation and can be done with the code shown in listing 4.15 [15]:

(39)

Listing 4.15: Using animation action 1 //1

2 NSMutableArray ∗animationFrames = [NSMutableArray array]; 3 SKTextureAtlas ∗bearAtlas = [SKTextureAtlas atlasNamed:@”bear”]; 4

5 //2

6 int numImages = bearAtlas.textureNames.count; 7 for (int i=1; i= numImages; i++)

8 {

9 NSString ∗textureName = [NSString stringWithFormat:@”bear%d”, i]; 10 SKTexture ∗temp = [bearAtlas textureNamed:textureName];

11 [animationFrames addObject:temp]; 12 }

13 //3

14 SKAction ∗bearAnimation =

15 [SKAction animateWithTextures:animationFrames timePerFrame:0.1]; 16 [ bear runAction:[SKAction repeatActionForever:bearAnimation];

1. Fist an array to hold the animation frames and a texture atlas is created 2. The animation textures are then added to the array by looping through your images names and try to find a sprite frame by that name in the texture atlas

3. The array with the animation frames and a time interval is sent to the SKAction animateWithTextures:. Finally this action is set to the

bear sprite, repeated over and over again.

For this method to work, a sequence of animated images is needed inside the texture atlas as seen in figure 4.7.

Figure 4.7: Four separate images that are lined up to show a short animation sequence of a walking bear.

As seen in figure 4.7 a lot of art is needed, especially if you want smooth and good quality animations.

An alternative method to traditional frame-by-frame animation is to use an animation tool. Esoteric Software offers an animation tool called Spine [6] that focuses specifically on 2D animations for games. Animation in Spine is done by attaching images to bones and then animating the bones. This means that

(40)

the art for your game characters must be divided into body parts in order to animate as seen in figure 4.8.

Figure 4.8: A texture atlas of our hero’s body parts.

This has numerous benefits over traditional, frame-by-frame animation [6]: • Smaller size Traditional animation requires an image for each frame of

animation. Spine animations store only the bone data, which is very small, allowing you to pack your game full of unique animations.

• Art requirements Spine animations require much fewer art assets, freeing up time and money better spent on the game.

• Smoothness Spine animations use interpolation so animation is always as smooth as the frame rate.

• Attachments Images attached to bones can be swapped to outfit a acter with different items and effects. Animations can be reused for char-acters that look different.

• Mixing Animations can be blended together. For example, a character could play a shoot animation while also playing a walk, run or swim ani-mation.

Spine can be used together with Sprite Kit. In our game all the animations for the units in the battle scene is done with Spine.

After creating your animations, Spine exports animation data in its own, docu-mented JSON and binary formats that are ideal for use with the Spine runtimes. The Spine Runtimes are libraries that allow your game toolkit to load and ren-der animations in your games, just as they do in Spine. Unfortunately Spine does not offer an official runtime for Sprite Kit. But there is an third party runtime that works with Sprite Kit that have been developed by the gaming community and can be found at the website of Spine [6] under runtimes. It does

(41)

not fully support all the features of Spine 2D but it does the most important like:

• Places Bones and Slot Attachments on SKScene.

• Animates Bone Timelines using SKAction for translate, rotate, and scale sequences

To add a Spine animation to your game with the unofficial runtime you first has to import the entire Spine importer folder to your project. You then add the following lines in Sprite Kit to create a spine object:

Listing 4.16: Creating a spine object 1 #import”SpineImport.h”

2

3 spine = [SGG Spine node];

4 [ spine skeletonFromFileNamed:@”skeletonhero”andAtlasNamed:@”hero” andUseSkinNamed:Nil];

5 spine . position = CGPointMake(self.size.width/2,self. size . height/2); 6 spine . zPosition = 0;

7 [ spine runAnimation:@”walk” andCount:−1]; 8 [self addChild: spine ];

As seen in listing 4.16 you first add the header file of the spine importer whatever you need to add the runtime. Then you create a spine node and connect it to the exported JSON file (skeletonhero.json) and the texture atlas (hero.atlas) containing all the art used for the animation. The spine node is then positioned on the screen and the zposition is to specify if the animation should be drawn on top or above other nodes. Finally, you decide which animation to run and how many times that specific animation should run, before you add the node to the scene. -1 is typed if you want the animation to be repeated forever.

(42)

4.6

Physics systems

Sprite Kit has an built-in 2D physics engine as described in section 2.4.5. Since our game is a turn based strategy game the need of a physics engine is not necessary for our type of game. But for many other game genres like physics-based puzzle games, real time strategy, action and adventure games, physics simulations might be necessary. For that reason I decided to show how the built-in physics engine in Sprite Kit can be used to help the programmer in the process of game development.

Physics simulation are applied by adding an SKPhysicsBody to a node. You can think of a physics body as a rough boundary for your sprite that is used for collision detection as seen in figure 4.9

Figure 4.9: The shape is matched with a close representation.

There are various shapes that can be used to apply physics to a scene. These shapes define the node’s ”personal space”. When one node’s shape intersects with another node’s shape, the method -didBeginContact is called and physics may be applied. The shape of the physics body does not need to match the boundaries of the sprite exactly. Usually, you choose a simpler shape so the collision detection algorithms can run faster. For example, in Figure 4.9, the eagle has a narrow shape that is not well represented by either a circle or a rectangle. A convex polygon shape is chosen and fitted to match the sprites artwork. Sprite Kit also provides a few standard shapes, as well as shapes based on arbitrary paths. Figure 4.10 shows the shapes available [2].

(43)

Figure 4.10: Physics bodies [2].

Adding a standard shape in Sprite Kit can easily be done with the following code shown in listing 4.17 [15]:

Listing 4.17: Attaching a physics body to a circle sprite 1 SKSpriteNode ∗ circle =

2 [SKSpriteNode spriteNodeWithImageNamed:@”circle”]; 3 circle . position = CGPointMake(self.size.width/2,

4 self. size . height/2);

5 [self addChild: circle ]; 6

7 circle .physicsBody =

8 [SKPhysicsBody bodyWithCircleOfRadius: circle.size.width/2];

Here a circle sprite is first created and added to the scene. In this simple exam-ple since the circle sprite uses an image shaped like a circle, you want to create a physics body of roughly the same shape. SKPhysicsBody has a simple fac-tory method called bodyWithCircleOfRadius: that creates a circle-shaped body.

Once you set a physics body for your sprite, it will move similarly to how it would in real life. When the frame is processed by the scene, the calculations are performed on the physics bodies attached to the nodes in the scene. Physics friction, gravity, and collisions with other physics bodies are some things that can be set for the node. Custom forces can also be applied to a body. Physics bodies are rigid and can not get squished or deformed under pressure, and do not change shape as a consequence of the physics simulation.

All the physics above could also be accomplished without using the built in physics engine, and instead using a bunch of math to perform the physical

(44)

cal-culations. That would require a lot of work and much more code to make the objects move in a realistic way.

4.7

Special effects

The difference between a good game and a great game is all in the details. Great games are filled with a dozed of small details that are so subtle that you might not even notice them while you are playing. Polishing a game means paying attention to these details. A common mistake is to stop developing once your game reaches a playable state and rush it to the App Store. Pushing your game further by adding more details and cool special effects will improve the visual experience.

One common way to spice up your game is to add particle systems to cre-ate special effects in your game. As mention in section 2.4.4 Sprite Kit comes with an particle emitter editor built into Xcode. This editor makes it possible to visualize and create particle effects to your games. In our game particle emitters are used to create the smoke and fire effect in the map scene and for all the units special abilities in the fight scene like the bomb explosion seen in figure 4.11.

Figure 4.11: A bomb explosion in the battle scene made with Sprite Kits em-bedded particle system.

To create a particle system with the visual editor, you simply create a new file with the iOS”\Resource\Sprite Kit Particle File template, which will create a

(45)

.sks file that you can edit with the built-in particle system editor. Then in code you create an SKEmitterNode with the file like shown in listing 4.18 /cite15:

Listing 4.18: Particle system with the visual editor 1 SKEmitterNode ∗ emitter =

2 [NSKeyedUnarchiver unarchiveObjectWithFile:

3 [[ NSBundle mainBundle] pathForResource:@”rain”ofType:@”sks”]]; 4 emitter . position = CGPointMake(100, 100);

5 [self addChild: emitter ];

First you load the SKS file from your bundle and unarchive it to obtain an SKEmitterNode. Next you position the particle emitter and add it to the scene.

Not only can you create particle systems with Xcode’s built-in editor visu-ally, you can also create them programmatically. To use a SKEmitterNode programmatically, you simply declare an instance of the node and set up its properties, like this [15]:

Listing 4.19: Particle system programmatically 1 SKTexture ∗ rainTexture =

2 [SKTexture textureWithImageNamed:@”rainDrop.png”]; 3 SKEmitterNode ∗ emitterNode = [SKEmitterNode new]; 4 emitterNode.particleTexture = rainTexture;

5 emitterNode.particleBirthRate = 80.0;

6 emitterNode.particleColor = [SKColor whiteColor]; 7 emitterNode.particleSpeed = −450; 8 emitterNode.particleSpeedRange = 150; 9 emitterNode.particleLifetime = 2.0; 10 emitterNode.particleScale = 0.2; 11 emitterNode.particleAlpha = 0.75; 12 emitterNode.particleAlphaRange = 0.5; 13 emitterNode.particleColorBlendFactor = 1; 14 emitterNode.particleScaleRange = 0.5; 15 emitterNode.position =

16 CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame ) + 10);

17 emitterNode.particlePositionRange =

18 CGVectorMake(CGRectGetMaxX(self.frame), 0); 19 [self addChild: emitterNode];

The code above is used for simulating rain. At the first 4 lines a texture for the raindrops is created and set to an emitter node. Properties for the emitter node are then set between line 5-14. At the last lines the position for the emitter and all the particles are set to make it look like rain and finally the emitter is added to the scene.

(46)

Particle Systems can also be made from scratch with OpenGL ES. As mak-ing a physics engine this require a lot of code and experience and is a larger project to dig into not covered by this thesis. Many game engines do not come with a fully integrated particle system and to achieve particle effects with those engines a third part library needs to be included. Ricardo Rendon Cepeda [4] has written an good article on how to implement a particle system from scratch with OpenGL ES for those who are interested.

As mention in section 2.4.2 Sprite Kit also has four more advanced types of nodes for adding cool and unique effects into your game. When using these nodes, it is important to keep an eye on performance because these nodes all require greater resources. An SKEffectNode allows you to apply special ef-fects to its children nodes. For example, you could use it to modify a sprite’s vibrance, hue, exposure, blur, or convert it to black and white.

In our game an SKEffectNode is used to blur the background sprite when a popup is active to achieve an depth of field effect. This special effect is cre-ated with a technology introduced in iOS 5 called Core Image. Core Image allow you to perform many of the functions that writing custom shaders would perform in other game engines.

At the time when this report was written Sprite Kit did not support custom render code for writing special effects. This may not be a big drawback for the average game but more advance user will feel that this hit the visual limits of Sprite Kit. For custom rendering we still require an open source framework, or write our own game engine on top of OpenGL ES. The last rumors says that custom shaders will be supported for Sprite Kit in iOS 8.

However the benefits of using effect nodes is that they are much easier to use than writing OpenGL and GLSL code. To filtering a SKEffectNode you can apply a Core Image effect to it and all of its children node will also be effected. So you could create a SKEffectNode, add a sprite to it as a child, and it would apply the Core Image effect to just that sprite. One simple example how to do this is shown in listing 4.20 [15]:

(47)

Listing 4.20: Applying a blur effect 1 SKEffectNode ∗effectNode = [[SKEffectNode alloc] init]; 2 SKTexture ∗texture =

3 [SKTexture textureWithImage:[UIImage imageNamed:@”background”]]; 4 SKSpriteNode ∗sprite = [SKSpriteNode spriteNodeWithTexture:texture]; 5 sprite . position = self.view.center ;

6 effectNode. filter = [self blurFilter ]; 7 effectNode.blendMode = SKBlendModeAdd; 8 effectNode.shouldEnableEffects =YES; 9 [effectNode addChild:sprite ]; 10 [self addChild:effectNode]; 11 12 //applying blur 13 − (CIFilter ∗) blurFilter 14 {

15 CIFilter ∗ filter = [CIFilter filterWithName:@”CIGaussianBlur”]; 16 [ filter setDefaults ];

17 [ filter setValue :[ NSNumber numberWithFloat:20] forKey:@” inputRadius”];

18 return filter ; 19 }

At the first 10 lines a effect node and a texture set to a sprite node is created. A filter, some properties and the sprite node are then added to the effect node, which are added to the scene. Core image provides over 100 filters for iOS. In the above code, you use the NSString name of the filter to create an instance of that filter. The actual blur filter is created between line 13-19.

(48)

Chapter 5

Result

The end result is a simple game made with Sprite Kit running on all iPhones from iPhone 4 and above and all iPads as seen in figure 5.1 and 5.2 .

References

Related documents

The thesis is based on three empirical studies in which particular attention is paid to detailing the impact of geographic factors on various daily travel activities (paper I);

The thesis is based on three empirical studies in which particular attention is paid to detailing the impact of geographic factors on various daily travel activities (paper

You can either use only one primary antibody which will increase the sensitivity of the method or use two primary antibodies directed against two different epitopes on the same

För att uppskatta den totala effekten av reformerna måste dock hänsyn tas till såväl samt- liga priseffekter som sammansättningseffekter, till följd av ökad försäljningsandel

Inom ramen för uppdraget att utforma ett utvärderingsupplägg har Tillväxtanalys också gett HUI Research i uppdrag att genomföra en kartläggning av vilka

Från den teoretiska modellen vet vi att när det finns två budgivare på marknaden, och marknadsandelen för månadens vara ökar, så leder detta till lägre

The lower values found for the first energy comparison for the atria scenarios observed in Graph 1 are the culmination of the previous results from Sections 3.1

Figure 5.1 shows the planned overall layout of the system where the Request sender is a program that sends requests to the different Spring boot programs, Spring boot program is