iOS 7 Game Development

This book is intended for those who have great ideas for games and who want to learn about iOS game development.

Dmitry Volevodz

120 Pages

12145 Reads



PDF Format

1.38 MB

Game Development

Download PDF format

  • Dmitry Volevodz   
  • 120 Pages   
  • 19 Feb 2015
  • Page - 1

    read more..

  • Page - 2

    iOS 7 Game DevelopmentDevelop powerful, engaging games with ready-to-use utilities from Sprite KitDmitry VolevodzBIRMINGHAM - MUMBAI read more..

  • Page - 3

    iOS 7 Game DevelopmentCopyright © 2014 Packt PublishingAll rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold read more..

  • Page - 4

    CreditsAuthorDmitry VolevodzReviewersJayant C VarmaDave JewellAcquisition EditorsMeeta RajaniRebecca YoueCommissioning EditorManasi PandireTechnical EditorsKunal Anil GaikwadKrishnaveni HaridasManal PednekarCopy EditorsAlfida PaivaSayanee MukherjeeProject CoordinatorsSherin PadayattyAkash PoojaryProofreaderPaul HindleIndexerMariammal ChettiyarGraphicsYuvraj MannariProduction CoordinatorKyle AlbuquerqueCover WorkKyle Albuquerque read more..

  • Page - 5

    About the AuthorDmitry Volevodz is an iOS developer. He has been doing freelance software development for a few years and has finally settled in a small company. He does enterprise iOS development by day and game development is his hobby.I would like to thank my beloved wife Olesya for her patience and support in everything I do. I would also like to thank Gennady Evstratov for believing in my programming abilities. Without him, this book would have never happened. I would also like to thank read more..

  • Page - 6

    About the ReviewersJayant C Varma is an Australian author, developer, and trainer who has gained experience from several other countries. He is the author of Learn Lua for iOS Game Development and is the founder of OZ Apps, a development consultancy specializing in mobile development. He has managed the IT operations for BMW dealerships since the mid 90s and has been an adopter of new technologies. He has also been an academic with James Cook University, and is actively involved in training and read more..

  • Page - 7

    www.PacktPub.comSupport files, eBooks, discount offers and moreYou might want to visit for support files and downloads related to your book. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at for more details.At, you can also read more..

  • Page - 8

    Table of ContentsPreface 1Chapter 1: Updates on iOS 7 5Redesigning the iOS 5New APIs 7Developing games for iOS 7 8Framework for game development 8Knowing about Sprite Kit 10Benefits of Sprite Kit 10Game controller support 11Game center renovations 12Summary 12Chapter 2: Our First Sprite Kit Project 13Sprite Kit basics 14Anatomy of a Sprite Kit project 15Scenes 16Nodes 16Node types 17Actions 18Game loop 19Adding a background image to our game 22Moving the character with actions 28Adding infinite read more..

  • Page - 9

    Table of Contents[ ii ]Chapter 3: Interacting with Our Game 33Handling touches 33Using gesture recognizers 36Accelerometer 38Physics engine 42Physics simulation basics 42Implementing the physics engine 44Summary 47Chapter 4: Animating Sprites 49What is animation? 49What is a texture atlas? 50Adding animations to our project 51Character states 56Adding shield animations 58Adding a parallax background 62Summary 65Chapter 5: Particle Effects 67Particle emitters 67First particle effect 68Advanced read more..

  • Page - 10

    PrefaceSprite Kit is a new framework from Apple for developing 2D games for iOS devices. It is new, fresh, and exciting.Developers have been waiting long for a native library for games, but Apple did not deliver it until Version 7.0 of their operating system. Developers had to use unreliable third-party libraries, work on fixing bugs in these libraries, and experiencing headaches when suddenly your project just stops compiling under new versions of the operating system.All these problems can be read more..

  • Page - 11

    Preface[ 2 ]Chapter 3, Interacting with Our Game, shows you the way to control our character sprite, either by using gesture recognizers or with raw touch processing.Chapter 4, Animating Sprites, walks you through the process of creating a texture atlas, animating our character, and creating actions to handle starting and finishing animations. We will also add nice parallax scrolling to our game.Chapter 5, Particle Effects, explains how to create cool-looking particle effects, how to store read more..

  • Page - 12

    Preface[ 3 ]A block of code is set as follows:- (void) stopRunningAnimation{ [self removeActionForKey:@”running”];}New terms and important words are shown in bold. Warnings or important notes appear in a box like this.Tips and tricks appear like this.Reader feedbackFeedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of.To send read more..

  • Page - 13

    Preface[ 4 ]ErrataAlthough we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting, selecting your book, clicking on the errata read more..

  • Page - 14

    Updates on iOS 7In this chapter, we will find out what's new in iOS 7, starting from new designs, which new APIs and SDKs were presented by Apple with iOS 7, and why you should pick Sprite Kit for game development.Redesigning the iOSThe new operating system from Apple features overhauled design in almost every element. All buttons, pickers, labels, navigation bars—everything looks and feels different. The concepts that Apple has chosen are simplicity and minimalism. Apple designers have read more..

  • Page - 15

    Updates on iOS 7[ 6 ]On comparing the following two screenshots, you can see the old and new look of the Calendar application. Apple has focused on the user-generated content; you can see that the space for user data is much larger in the iOS 7 version; however, in the old Calendar application, we can see only two lines of our content. The Calendar application in iOS 6Buttons have transformed into simple lines of text, without any background or frame, while gradients on the navigation and bottom read more..

  • Page - 16

    Chapter 1[ 7 ]The Calendar application on iOS 7New APIsThe new operating system from Apple features numerous new APIs. Some of them are long overdue and expected, and some are quite surprising. Some of them that are worth mentioning are as follows:• Text Kit: This is an API for laying out text and for fine typography. Text Kit helps you lay out text in the way you like without any headache.• Dynamic behaviors for views: With this, you can now assign physics effects to your views so they can read more..

  • Page - 17

    Updates on iOS 7[ 8 ]• Sprite Kit framework: This is a new framework for developing 2D games, and features hardware sprites acceleration, simple sound playback support, and physics simulation.• Game controller support: This is a new framework that provides common ground for hardware controllers.Developing games for iOS 7In June 2013, Apple announced that the App Store has hit the next milestone—50 billion downloads with more than 14 billion dollars paid to developers all over the world. read more..

  • Page - 18

    Chapter 1[ 9 ]Let us see each of them in detail:• OpenGL is very customizable and open-ended, but it is hard to learn, and you need to know a lot of things just to get an image on screen. It is good if you are an experienced programmer or a company, and you want to write cross-platform solutions. OpenGL offers good performance, but you have to pay with code complexity.• Next up is UIKit, which is the default iOS programming framework. Every element that you see in a regular iOS read more..

  • Page - 19

    Updates on iOS 7[ 10 ]Knowing about Sprite KitApple presented iOS 7 in September 2013, featuring numerous new features for users and developers. One of them is Sprite Kit—a new framework for game developers.Sprite Kit is a native SDK from Apple that allows simple entry into game development, without unnecessary overhead and a long learning process. If you are familiar with Cocos2d, you will have an easy time with Sprite Kit, as it is heavily inspired by the former. Sprite Kit provides native read more..

  • Page - 20

    Chapter 1[ 11 ]• Your game will work both on iOS and Mac without much effort: Sprite Kit supports both Mac and iOS, and all you need to change is controls. You will have touch controls for your iPhone and iPad versions and the mouse and keyboard controls for Mac.Game controller supportOne of the most interesting features of iOS 7 is the native controller support. Some companies such as iCade and others tried working on their own controllers, but this effort has not seen much success. Surely, read more..

  • Page - 21

    Updates on iOS 7[ 12 ]There have been rumors that vendors such as Logitech are already working on such controllers, and you as a developer should probably work on implementing them in your game, as the effort required to make them work is really small, and the satisfaction that your player gets when the game works with his controller is enormous.The new Game Controller framework allows discovering and connecting compatible game controllers to your iOS device.Game center renovationsGame center read more..

  • Page - 22

    Our First Sprite Kit ProjectIn this chapter, we will look into Sprite Kit basics. Sprite Kit consists of a lot of small elements and we need to have a clear understanding of what they do to have an overview of a typical Sprite Kit project to see how we might plan and implement a full-featured game.We will explore everything that we might need when creating our own project, as the main goal of the book is to provide an understanding of Sprite Kit as a tool for game development. We will start read more..

  • Page - 23

    Our First Sprite Kit Project[ 14 ]Sprite Kit basicsFirst of all, we need to create a basic project from the template to see how everything works from the inside. Create a new project in Xcode by navigating to File | New | Project. Choose SpriteKit Game after navigating to iOS | Application, as shown in the following screenshot:Creating a Sprite Kit projectOn the next screen, enter the following details:• Product Name: Endless Runner.• Organization name: Enter your name.• Company read more..

  • Page - 24

    Chapter 2[ 15 ]• Class Prefix: This is used to prefix your classes due to poor Objective-C namespace. People often ignore this (it makes sense when you make small projects, but if you use any third-party libraries or want to follow best practices, use three-lettered prefixes). We will use ERG (denoting Endless Runner Game) for this. Apple reserves using two-lettered prefixes for internal use.• Devices: We are making the game for iPhones, so ensure iPhone is selected.Now, save the project and read more..

  • Page - 25

    Our First Sprite Kit Project[ 16 ]ScenesAn object where you place all of your other objects is the SKScene object. It represents a single collection of objects such as a level in your game. It is like a canvas where you position your Sprite Kit elements. Only one scene at a time is present on SKView. A view knows how to transition between scenes and you can have nice animated transitions. You may have one scene for menus, one for the gameplay scene, and another for the scene that features read more..

  • Page - 26

    Chapter 2[ 17 ]Node typesThere are different node types that serve different purposes:• SKNode: This is a parent class for different types of nodes• SKSpriteNode: This is a node that draws textured sprites• SKLabelNode: This is a node that displays text• SKShapeNode: This is a node that renders a shape based on a Core Graphics path• SKEmitterNode: This is a node that creates and renders particles• SKEffectNode: This is a node that applies a Core Image filter to its childrenEach of read more..

  • Page - 27

    Our First Sprite Kit Project[ 18 ]ActionsActions are one of the ways to add life to your game and make things interactive. Actions allow you to perform different things such as moving, rotating, or scaling nodes, playing sounds, and even running your custom code. When the scene processes its nodes, actions that are linked to these nodes are executed.To create a node, you run a class method on an action that you need, set its properties, and call the runAction: method on your node with action as read more..

  • Page - 28

    Chapter 2[ 19 ]Game loopUnlike UIKit, which is based on events and waits for user input before performing any drawing or interactions, Sprite Kit evaluates all nodes, their interactions, and physics as fast as it can (capped at 60 times per second) and produces results on screen. In the following figure, you can see the way a game loop operates:update:Evaluating actionsSimulating physicsRendering sceneThe update loopFirst, the scene calls the update:(CFTimeInterval)currentTime method and read more..

  • Page - 29

    Our First Sprite Kit Project[ 20 ]Add this code right after = @"theLabel";Find the update: method; it looks like this:- (void)update:(CFTimeInterval)currentTimeInsert the following code into it: [self enumerateChildNodesWithName:@"theLabel" usingBlock:^(SKNode *node, BOOL *stop) { node.position = CGPointMake(node.position.x - 2, node.position.y); if (node.position.x < - node.frame.size.width) { node.position = read more..

  • Page - 30

    Chapter 2[ 21 ]There are two problems with our code. The first issue is that the frame is not changing when you rotate the screen, it stays the same even if you rotate the screen. This happens because the scene size is incorrectly calculated at startup. But we will fix that using the following steps:1. Locate the Endless Runner project root label in the left pane with our files. It says Endless Runner, 2 targets, iOS SDK 7.0. Select it and select the General pane on the main screen.There, read more..

  • Page - 31

    Our First Sprite Kit Project[ 22 ]The second problem is the anchoring of the nodes. Unlike UIViews, which are placed on screen using their top-left corner coordinates, SKNodes are getting placed on the screen based on their anchorPoint property. The following figure explains what anchor points are. By default, the anchor point is set at (0.5, 0.5), which means that the sprite position is its center point. This comes in handy when you need to rotate the sprite, as this way it rotates around its read more..

  • Page - 32

    Chapter 2[ 23 ]Next, we should utilize this image somehow. The first thing that comes to mind is to make SKSpriteNode out of the image and move it in the update: method. Sounds good, but if we add everything into the scene, it will be too bloated and unmanageable. Let's make a separate class file that will handle background images for us:1. We will need some place to store all our constants and variables that we might need throughout our game. Common header file looks like a good place to store read more..

  • Page - 33

    Our First Sprite Kit Project[ 24 ]3. Add the name of our background node, static NSString *backgroundName = @"background"; to the Common.h file so we can reference it from anywhere.4. Again, create a new file, an Objective-C class, name it ERGBackground, and set SKSpriteNode as its parent class when asked.We will be handling everything background related in the ERGBackground class. Let's make the class method return the preset background so we can use it in our game.Add this method read more..

  • Page - 34

    Chapter 2[ 25 ]We will hold the currently shown background in it. Next up, remove everything inside the brackets of the initWithSize: method, create a new background there, and add it as a child node to the scene:-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { self.currentBackground = [ERGBackground generateNewBackground]; [self addChild:self.currentBackground]; } return self;} Build and run the project now and you will see the read more..

  • Page - 35

    Our First Sprite Kit Project[ 26 ]Having done this, we can set up a much more precise movement. Let's add a new constant to the Common.h file:static NSInteger backgroundMoveSpeed = 30;We will use this to handle background scrolling, new code to scroll background that uses timing, and add it after handling time in the update: method: [self enumerateChildNodesWithName:backgroundName usingBlock:^(SKNode *node, BOOL *stop) { node.position = CGPointMake(node.position.x - read more..

  • Page - 36

    Chapter 2[ 27 ]We need to redefine its init method so that we always get the same character for the player. Add the following code to ERGPlayer.m:-(instancetype)init{ self = [super initWithImageNamed:@"character.png"]; { = playerName; } return self;}This method calls the parent implementation of the designated initializer. Next, add the player object to ERGMyScene.m by adding this code to the scene init method: ERGPlayer *player = [[ERGPlayer alloc] read more..

  • Page - 37

    Our First Sprite Kit Project[ 28 ]Moving the character with actionsLet's discover how we can add simple player movements to our game, for example, jumping. One of the ways to handle this could be by creating a new action that will move the character up by a certain amount of pixels and then move the character down. Let's try this out.Remove everything from the touchesBegan: method in ERGMyScene.m. It should look like this:-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // we read more..

  • Page - 38

    Chapter 2[ 29 ]But this is unnecessarily complicated. What if we wanted to add platforms, how would we handle that?Generally speaking, the action system is useful if you know you need to do a certain thing with your objects and nothing changes while executing them. This way, actions are useful and very helpful, since doing something like that in the update loop can be daunting.Another powerful feature of actions is that they can be sequenced or repeated, and you can make very complex read more..

  • Page - 39

    Our First Sprite Kit Project[ 30 ] } [self enumerateChildNodesWithName:backgroundName usingBlock:^(SKNode *node, BOOL *stop) { node.position = CGPointMake(node.position.x - backgroundMoveSpeed * timeSinceLast, node.position.y); if (node.position.x < - (node.frame.size.width + 100)) { // if the node went completely off screen (with some extra pixels) // remove it [node removeFromParent]; }}]; if (self.currentBackground.position.x read more..

  • Page - 40

    Chapter 2[ 31 ] self.scoreLabel.zPosition = 100; [self addChild:self.scoreLabel]; SKAction *tempAction = [SKAction runBlock:^{ self.scoreLabel.text = [NSString stringWithFormat:@"%3.0f", self.score]; }]; SKAction *waitAction = [SKAction waitForDuration:0.2]; [self.scoreLabel runAction:[SKAction repeatActionForever:[SKAction sequence:@[tempAction, waitAction]]]];Why would we need so many actions? We could go the easier read more..

  • Page - 41

    read more..

  • Page - 42

    Interacting with Our GameIn this chapter, we will discuss the ways in which we can get input from the player. As there are many different ways to handle user input, we will see the advantages and disadvantages of each of them. Some of the ways to interact with the game are as follows:• Touching the screen (taps)• Gesture recognizers• Accelerometer and gyroscope• Game controller eventsHandling touchesWhen the user touches the iOS device screen, our current running scene will receive a read more..

  • Page - 43

    Interacting with Our Game[ 34 ]Each method gets an NSSet class of a UITouch object (which holds the coordinates of our touch), and the event holds information about the window and view in which the touch was triggered as well as information about the touch. Let's see what each of them does:• touchesBegan:: This method gets triggered each time the user touches the screen, unrelated to whether this touch continues as a long press or not.• touchesMoved:: This method provides you with events read more..

  • Page - 44

    Chapter 3[ 35 ]2. Add the following code to the beginning of the touchesBegan: method in ERGScene: UITouch *touch = [touches anyObject]; SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:[touch locationInNode:self]]; if ( == playerName) { ERGPlayer *player = (ERGPlayer *) touchedNode; player.selected = YES; return; }On the first line, we get the touch object from the touches set and then try to find if it intersects any node. To read more..

  • Page - 45

    Interacting with Our Game[ 36 ]And the thing that we need to do last is remove the selected property after the touch has ended:- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ ERGPlayer *player = (ERGPlayer *)[self childNodeWithName:playerName]; if (player.selected) { player.selected = NO; }}Now, if you build and run the project, you will be able to drag the character sprite around. Another option to consider is to move the score label around the screen to the read more..

  • Page - 46

    Chapter 3[ 37 ]The first thing that comes to mind is adding a gesture recognizer to our scene, pointing it to some method, and be done with it. But unfortunately, this won't work—SKNodes and SKScenes do not support adding gesture recognizers. But there is a way to make this work.SKScene has a handy method, — (void)didMoveToView:(SKView *)view, which we can use, and it gets called each time a scene is about to be attached to some view. When we run our game, this happens right after the read more..

  • Page - 47

    Interacting with Our Game[ 38 ]The interesting part here is a second check for background speed in the handleSwipeLeft: method. We don't want to go into negative or zero speed, since our background generator works only with positive scrolling (from right to left), and if we have negative scrolling, the background will end.Another thing that we need to remember is to remove the gesture recognizer once the scene gets removed from the view, as we might get another scene in the same view that read more..

  • Page - 48

    Chapter 3[ 39 ]Some games benefit greatly from accelerometer support, and we are going to implement this in our game.Accelerometer data is available only on devices. Thus, if you test it on the simulator, this code won't do anything, as the accelerometer will return 0 all the time. Consider getting an Apple developer license if you have not got one already, as it offers the option of testing on a real device. You can get it at It is especially useful read more..

  • Page - 49

    Interacting with Our Game[ 40 ]In the first line, we instantiate the manager, and in the second one, we set the update interval—how often the values in the motion manager will be updated. On the third line, we tell the manager to start updating, as it won't do anything before that.Using the accelerometer increases the power use of the device. Heavy use will drain the battery faster, thus making your game unlikely to be played further. Only use the accelerometer when you actually need to, and read more..

  • Page - 50

    Chapter 3[ 41 ]As you rotate the device, you can see that values change very fast, and different device positions yield different results. For every person, that baseline will be different, and we need to acknowledge that. To compensate that baseline, we will read the starting value on the launch of an application and base our movement on it.For our landscape mode game, reading the X axis' coordinates will be most useful. To get it, we poll self.manager.accelerometerData.acceleration.x.In order read more..

  • Page - 51

    Interacting with Our Game[ 42 ]First, we get the pointer to our player sprite. Then, we calculate the new position by multiplying the accelerometer data and the out multiplier to get the sprite position on the Y axis. As we don't want to have our character fly off screen, we add a check; if it goes below or over a certain point, its vertical position is reset to the minimum value. Build and run the project to see if everything works.Physics engineThe next big topic that we will discover is read more..

  • Page - 52

    Chapter 3[ 43 ]In order to simulate physics on many bodies in real time, there are many different optimizations and simplifications. Let's cover some of them:• All movements, just like in real life, are handled by impulses and forces. The impulse is applied instantaneously; for example, if a moving ball collides with a standing ball, the standing ball gets an impulse in one moment. Force is a continuous effect that moves the body in some direction. For example, launching a rocket is slow and read more..

  • Page - 53

    Interacting with Our Game[ 44 ]• collisionBitMask: This is the bitmask that identifies what bodies this body collides with. You might want some objects to collide with others, and other objects to pass through others. You will need to set the same bitmasks for objects that you want to collide.• contactBitMask: This is the bitmask that identifies the body for handling collisions manually. You might want to have special effects when things collide; that's why we have this. When bodies have the read more..

  • Page - 54

    Chapter 3[ 45 ]This looks sufficient for our character sprite. What can we do with backgrounds?Obviously, we need the player to collide with the top and bottom of the screen. This is when other methods come in handy. Add this code right before the return statement in the generateNewBackground method in ERGBackground.m: background.physicsBody = [SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(0, 30) toPoint:CGPointMake(background.size.width, 30)]; background.physicsBody.collisionBitMask = read more..

  • Page - 55

    Interacting with Our Game[ 46 ]Or, you may just follow us. Change the didMoveToView method to the following:- (void) didMoveToView:(SKView *)view{ UILongPressGestureRecognizer *tapper = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(tappedScreen:)]; tapper.minimumPressDuration = 0.1; [view addGestureRecognizer:tapper];}Here, we initialize and use the new gesture recognizer that will set the player's state to accelerating, meaning that the player is moving up read more..

  • Page - 56

    Chapter 3[ 47 ]This code uses the playerJumpForce variable, which sets it in Common.h, as well as the gravity vector:static NSInteger playerJumpForce = 8000000;static NSInteger globalGravity = -4.8;We set gravity to custom as the real world's gravity is too high, and this strips away the fun and precise controls of our game.To affect gravity, add the following statement in ERGMyScene.m in the initWithSize: method:self.physicsWorld.gravity = CGVectorMake(0, globalGravity);In order to make read more..

  • Page - 57

    read more..

  • Page - 58

    Animating SpritesIn the last few chapters, we managed to get the basics of our game out of the way—we already have an infinite scrolling background, we handle collision detection with the physics engine, and we already have established controls. How can we improve our game? Of course, it can be enhanced with animation.Our character does not move his legs while running, and that is clearly not the way it should be. In this chapter, we are going to add animations to our character—he will read more..

  • Page - 59

    Animating Sprites[ 50 ]But there are some problems with it. Rendering individual frames from separate textures is not a fast task. It requires a lot of so-called draw calls. Each time you draw something on screen, you transfer that data to the video chip, and it performs the drawing. But each of these calls is expensive as it bears some overhead. If you have many animated objects on screen, you might experience slowdowns (lags) and the frame rate may drop. To optimize our sprite drawing, we will read more..

  • Page - 60

    Chapter 4[ 51 ]Images in a texture atlasTexture atlases are also smart. If you run on a retina device and you have two versions of the atlas—one for the retina and one for regular resolution—it will use the correct images. All you have to do is have one atlas with all of the images, but retina images should have a @2x suffix, for example, spaceship.atlas, and images such as spaceship1.png and spaceship1@2x.png. Xcode will create different texture atlases for different devices, so you read more..

  • Page - 61

    Animating Sprites[ 52 ]3. Add the following code at the end of the ERGPlayer.m init method: [self setupAnimations]; [self runAction:[SKAction repeatActionForever:[SKAction animateWithTextures:self.runFrames timePerFrame:0.05 resize:YES restore:NO]] withKey:@"running"]; First, we will call the setupAnimations function, where we will create an animation from the atlas. On the second line, we will create an action that repeats forever, takes an array of animation frames, read more..

  • Page - 62

    Chapter 4[ 53 ]On the third line of this method, we create a new array for animation frames. Then, we load the texture atlas named run. In the for loop, we create a new name for the texture and load it with that name into the frames array. We need to check for nil, as adding nil objects to an array raises an exception, and we don't want that. The format specifier, @"run%.3d", might have caught your attention. It means that we want a string starting with run and ending with a decimal read more..

  • Page - 63

    Animating Sprites[ 54 ]In the startRunningAnimation method, we do the same action that we did before in the init block, but we check if the player already has an animation with this key, and if he does, we do nothing here. In the second method, we find the animation and remove it, effectively stopping it.If you change the images in your project or add new ones, Xcode doesn't make new atlases. In order to do that, execute the Run and Clean commands from the Product menu on the Xcode file menu. read more..

  • Page - 64

    Chapter 4[ 55 ]3. Add the following code to the setupAnimations method in ERGPLayer.m. It does the same, in that we create an array and add frames to it: self.jumpFrames = [[NSMutableArray alloc] init]; SKTextureAtlas *jumpAtlas = [SKTextureAtlas atlasNamed:@"jump"]; for (int i = 0; i < [runAtlas.textureNames count]; i++) { NSString *tempName = [NSString stringWithFormat:@"jump%.3d", i]; SKTexture *tempTexture = [jumpAtlas read more..

  • Page - 65

    Animating Sprites[ 56 ]Character statesIn order to correctly handle states, we will expand our character code to handle different states that can occur. Firstly, we need to identify the states, which are as follows:• Running state: This is the default state when the character is running on the ground• Jumping state: This is the state when we press a button to jump, but it should be limited so that we don't continue the jumping state when we are in the air• In air state: This is the read more..

  • Page - 66

    Chapter 4[ 57 ] break; case playerStateInAir: [self stopRunningAnimation]; break; case playerStateRunning: [self startRunningAnimation]; break; default: break; } _animationState = animationState;}This method is triggered every time we try to set self.animationState, and instead of the default implementation, it goes through this. We have a switch here that looks for what kind of animationState we read more..

  • Page - 67

    Animating Sprites[ 58 ]The next thing that needs to be done is the location where we change states. The place where everything changes is the update: method in ERGMyScene.m; find the line where we enumerate child nodes with the name player and replace the current implementation with this: [self enumerateChildNodesWithName:@"player" usingBlock:^(SKNode *node, BOOL *stop) { ERGPlayer *player = (ERGPlayer *)node; if (player.accelerating) { [player.physicsBody read more..

  • Page - 68

    Chapter 4[ 59 ]Let's check the course of the action:1. Add the following properties to ERGPlayer.h:@property (strong, nonatomic) NSMutableArray *shieldOnFrames;@property (strong, nonatomic) NSMutableArray *shieldOffFrames;@property (strong, nonatomic) SKSpriteNode *shield;@property (assign, nonatomic) BOOL shielded;2. The first two properties are arrays for animation frames, the shield node is added to a character sprite in order to show shield animations (we can't show it on the character read more..

  • Page - 69

    Animating Sprites[ 60 ] [self.shield removeActionForKey:@"shieldOn"]; [self.shield runAction:[SKAction animateWithTextures:self.shieldOffFrames timePerFrame:0.15 resize:YES restore:NO] withKey:@"shieldOff"]; } _shielded = shielded;}5. First, we look for a new value that we are presented with. If it is YES and we don't have the animation running, we start the shield on animation. It repeats itself since we want the shield to animate while it is on. If we read more..

  • Page - 70

    Chapter 4[ 61 ] for (int i = 0; i < [shieldOnAtlas.textureNames count]; i++) { NSString *tempName = [NSString stringWithFormat:@"shield%.3d", i]; SKTexture *tempTexture = [shieldOnAtlas textureNamed:tempName]; if (tempTexture) { [self.shieldOnFrames addObject:tempTexture]; } } self.shieldOffFrames = [[NSMutableArray alloc] init]; SKTextureAtlas *shieldOffAtlas = [SKTextureAtlas atlasNamed:@"deplete"]; for read more..

  • Page - 71

    Animating Sprites[ 62 ]Adding a parallax backgroundAs you may have noticed, we have huge grey windows in our background (see the screenshot in the Adding shield animations section), and it would be great to add a parallax background over it. We will do it the same way we did with the original background. We will add new sprite nodes and move them every frame.The things that need to be done to add a parallax background are as follows:1. Add parallax.png to images.xcassets in the Xcode project, read more..

  • Page - 72

    Chapter 4[ 63 ]6. In ERGBackground.m, write the method itself:+ (ERGBackground *)generateNewParallax{ ERGBackground *background = [[ERGBackground alloc] initWithImageNamed:@"parallax.png"]; background.anchorPoint = CGPointMake(0, 0); = parallaxName; background.position = CGPointMake(0, 0); background.zPosition = 4; return background;}7. Here, we create the new sprite node, set its position and anchor point for our convenience, and adjust its position read more..

  • Page - 73

    Animating Sprites[ 64 ]9. Here, we find a node with parallaxName, and we remove it if it is off the screen. If the current parallax layer is halfway done or so, we create a new parallax layer and set its position to where the last one ends, so that they interconnect flawlessly. The following screenshot shows the addition of parallax.png to Images.xcassets:Adding parallax.png to Images.xcassetsBuild and run the project, and you will see that the parallax background layer adds to the atmosphere read more..

  • Page - 74

    Chapter 4[ 65 ]What is parallax?Parallax is an effect that allows us to simulate depth on a two-dimensional screen. This effect can be seen when you travel by train or by car. Trees that are near you move fast, those that are at a distance move slowly, and things on the horizon barely move. When some objects move faster and other objects move slower, we get a feeling that there is depth to the scene. We use this effect to add polish to our game.SummaryIn this chapter, we have learned that read more..

  • Page - 75

    read more..

  • Page - 76

    Particle EffectsIn this chapter, we will be discussing particle effects. These are the effects that are created by utilizing particles, which are very small graphical entities. They are not sprites and are rendered very efficiently, and you can have thousands of particles on screen without any slowdown.Particle effects are used for various effects that could be hard to implement otherwise.This is why particle effects are often used to add polish and engagement to your game. There are different read more..

  • Page - 77

    Particle Effects[ 68 ]There are two ways to create the particle emitter, either from file or programmatically. We will look at both the methods.First particle effectHow can we apply particle effects to our project? The first thing that comes to mind is to add nice flames to our jetpack. In order to do that, we need to create a new particle effects file. To do this, we need to navigate to the File menu and then to New | New File. On the left-hand side table, click on Resource under the iOS read more..

  • Page - 78

    Chapter 5[ 69 ]After you have done that, two new files will appear in your project, jet.sks and spark.png. Click on the first one and you will see the particle effect in action, then select SKNode Inspector on the right-hand side of the screen. Make sure the Utilities pane is visible on the right-hand side (the top-right icon in the Xcode window). Next, click on the rightmost icon below the toolbar, which looks like a small cube. You will see Particle Editor, which is a built-in tool to read more..

  • Page - 79

    Particle Effects[ 70 ]Now you will see the Emitter Node properties. Many of them are cryptic, but try playing with them and you will see that they are not that scary. Let's discuss some of them:• Birthrate: This is the rate at which the emitter generates particles. The greater the number here, the more intense the effect feels. Try to keep this as low as possible to achieve the same effect for a good frame rate.• Lifetime: This defines how long a particle will live. This indirectly affects read more..

  • Page - 80

    Chapter 5[ 71 ]After that, add the following lines to the init method of ERGPlayer.m: self.engineEmitter = [NSKeyedUnarchiver unarchiveObjectWithFile: [[NSBundle mainBundle] pathForResource:@"jet" ofType:@"sks"]]; self.engineEmitter.position = CGPointMake(-12, 18); = @"jetEmitter"; [self addChild:self.engineEmitter]; self.engineEmitter.hidden = YES;In the first line, we unarchive read more..

  • Page - 81

    Particle Effects[ 72 ]Advanced physicsNow that we have added the jetpack effect, we should add core gameplay elements. We will add enemies and power-ups to our game. But we will need to handle collisions somehow. That's where, once again, Sprite Kit and its sophisticated physics engine will save us.If you remember how we handled collisions before by setting collisionBitMasks, the game checks if two things have the same collision bitmasks and handles their collision. This was the way that worked read more..

  • Page - 82

    Chapter 5[ 73 ]Bitmasks in Sprite Kit are 32 bit, the same as integers, and they work by setting individual bits in an integer. Thus, there are only 32 possible masks, and you should use them carefully, since mistakes here lead to a lot of confusion.As bitmasks use each individual bit, you should use these numbers for masks: 1, 2, 4, 8, 16, 32, and so on.We will need to create new masks in the Common.h file and add the following code to it:const static int playerBitmask = 1;const static int read more..

  • Page - 83

    Particle Effects[ 74 ]We override the init method to add the new setup method that creates a new emitter and a new physics body. We set contactBitMask to playerBitmask, since we want to be notified when a player sprite is colliding with the enemy sprite, and we don't want enemies to collide with each other. We set categoryBitMask in order to identify the object, collisionBitMask to zero since we don't want our engine to handle collision for us, and we will do it manually. We also set read more..

  • Page - 84

    Chapter 5[ 75 ]This method is straightforward, but for the arc4random() function that returns a random number, and if we perform a modulo operation on it with certain numbers, we will get a random number from 0 to the previous number of that number. This is useful, since we want our enemies to spawn somewhat randomly. They spawn off screen. We will need the same method to spawn power-ups:- (ERGPowerup *) spawnPowerup{ ERGPowerup *temp = [[ERGPowerup alloc] init]; = read more..

  • Page - 85

    Particle Effects[ 76 ]The preceding code will move enemies at the same speed as the background is moved, and will move the enemy to a somewhat random position in front of the screen once it goes off screen. This way we will always use only a certain amount of enemies and won't create any new ones. Re-using things is a good practice, since it saves us memory and processor time. Next, we need to add some constants that handle the number of enemies that spawn and power-ups that can spawn.We will read more..

  • Page - 86

    Chapter 5[ 77 ]• Speed: 100 with 100 range• Acceleration: X at 0 and Y at -50• Scale: 0.1 with 0.1 range and 1 speed• Rotation: At zero and blue colorThis makes a nice yellow ball that looks dangerous enough for enemies and the blue flame for power-ups. In order to use collisions and collision handling, we need to change the masks in ERGPlayer.m and the old values to the following ones: self.physicsBody.contactTestBitMask = shieldPowerupBitmask | enemyBitmask; read more..

  • Page - 87

    Particle Effects[ 78 ]The preceding method is provided with the contact that has two properties in it, bodyA and bodyB. But these bodies are somewhat randomly selected and we need to check their type before we do anything. Here we check if we picked up the power-up on which we set the shielded property on our player to YES, and if we touch the enemy, we will call the takeDamage method on the player.We will need to modify ERGPlayer.m by first removing self.shielded = YES and self.shielded = NO read more..

  • Page - 88

    Chapter 5[ 79 ]Our Game Over sceneFirst, we create a new scene as usual. Next, we create a transition object. There are many kinds of transitions with many different effects. On the third line, we ask view to present a new scene. This ends our scene lifecycle. Scenes do not get saved in memory; on each transition the old scheme is destroyed, and if you want to use it again, you have to make it all over, as shown in the preceding screenshot.There are many different transition types that you can read more..

  • Page - 89

    Particle Effects[ 80 ] node.position = CGPointMake(self.size.width / 2, self.size.height / 2); node.fontSize = 35; node.color = [UIColor whiteColor]; [self addChild:node]; } return self;}- (void) didMoveToView:(SKView *)view{ [super didMoveToView:view]; UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(newGame)]; [view addGestureRecognizer:tapper];}- (void) newGame{ ERGMyScene *newScene = read more..

  • Page - 90

    Adding Game ControllersIn this chapter, we are going to discuss a new feature available in iOS 7—game controllers. Apple allowed video streaming from iOS devices to TV a long time ago, but the lack of hardware controller support left many players underwhelmed. Game controllers allow you to focus on the gameplay rather than controls, and if you are using your iPhone or iPad as a controller, you don't receive any physical feedback. This is one of the major drawbacks of touchscreen gaming—you read more..

  • Page - 91

    Adding Game Controllers[ 82 ]Native game controllersSupport for native game controllers first appeared in iOS 7. What are the advantages of native controllers? Here are some of them:• A universal API for every controller out there: You will need to write the code only once to support a myriad of different controllers by different manufacturers.• An easy-to-use API written and supported by Apple engineers: You know that your code will work on the latest versions of iOS and will generally be read more..

  • Page - 92

    Chapter 6[ 83 ]L2 shoulder button/triggerR2 shoulder button/triggerLED arrayJoysticksL2L1R1YXABR2L1 shoulder buttonR1 shoulder buttonDifferent controller typesApple does not necessarily require a game controller to play a game—there should always be a way to play your game via touchscreen. Game controllers enhance your user's experience, but do not force them to do so.Wired controllers are automatically discovered, but their wireless counterparts require a one-time setup and can be used freely read more..

  • Page - 93

    Adding Game Controllers[ 84 ]There are two ways to receive data from the controller, which are as follows:• By reading the properties directly• By assigning a handler (block) to each button to be executed on button pressThe following is a sample method to read inputs if you want to read them at arbitrary times:- (void) readControlInputs{ GCGamepad *gamepad = self.myController.gamepad; if (gamepad.buttonA.isPressed) [self jumpCharacter]; if (gamepad.buttonB.isPressed) read more..

  • Page - 94

    Chapter 6[ 85 ]Picking the positions of the thumbstick or the directional pad is a little more complex. Usually, you get x and y values and you can work from there: GCControllerDirectionPadValueChangedHandler dpadMoveHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { if (yValue > 0) { player.accelerating = YES; } else { player.accelerating = NO; } }; In this block, we check the y value, and if it is higher then 0 read more..

  • Page - 95

    Adding Game Controllers[ 86 ]Here, we set our property to hold a pointer to the player object. At the end of initWithSize:, we will add the code to handle controller discovery and setup, and create a pauseLabel, as shown in the following code: [self configureGameControllers]; self.pauseLabel = [[SKLabelNode alloc] initWithFontNamed:@"Chalkduster"]; self.pauseLabel.fontSize = 55; self.pauseLabel.color = [UIColor whiteColor]; self.pauseLabel.position = read more..

  • Page - 96

    Chapter 6[ 87 ] [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gameControllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil]; [self configureConnectedGameControllers]; [GCController startWirelessControllerDiscoveryWithCompletionHandler:^{ // we don't use any code here since when new controllers are found we will get notifications }];}The first thing that we do is subscribe for notifications related to the game read more..

  • Page - 97

    Adding Game Controllers[ 88 ]Most of the logic happens in the following method, where we set up actual button handlers:- (void)setupController:(GCController *)controller forPlayer:(ERGPlayer *)player{ GCControllerDirectionPadValueChangedHandler dpadMoveHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { if (yValue > 0) { player.accelerating = YES; } else { player.accelerating = NO; } }; if read more..

  • Page - 98

    Chapter 6[ 89 ] controller.extendedGamepad.buttonB.valueChangedHandler = jumpButtonHandler; } controller.controllerPausedHandler = ^(GCController *controller) { [self togglePause]; }; }At the beginning of this method, we create a handler for the directional pad and thumbsticks—if the player presses the up button on the pad or moves the thumbstick up, we will have the Y value going up from zero. Thus, we start jumping by setting the accelerating property to read more..

  • Page - 99

    Adding Game Controllers[ 90 ]Handling controller notificationsAnother thing that we would want to handle is new controllers. We need to do something when a controller connects or disconnects.We can create a complex interface for that, but for our project, simple alerts will do.The easy part is that when the controller disconnects, we won't get any new input, so we don't need to do anything; we just show an alert and are done with it:- (void)gameControllerDidDisconnect:(NSNotification read more..

  • Page - 100

    Chapter 6[ 91 ]We create the alert view as before, but here we set its delegate to our scene. The following is the delegate method:-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex == 1) { [self configureConnectedGameControllers]; }}When you press a button in the alert view, and if it has the delegate set, it will call this method on its delegate. The button's index starts at zero, and zero is the cancel button that is always read more..

  • Page - 101

    Adding Game Controllers[ 92 ]After this, we need to create a new method to set up the playback sound. Add this new method to ERGMyScene.m:- (void) setupMusic{ NSString *musicPath = [[NSBundle mainBundle] pathForResource:@"Kick_Shock" ofType:@"mp3"]; self.musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicPath] error:NULL]; self.musicPlayer.numberOfLoops = -1; self.musicPlayer.volume = 1.0; [self.musicPlayer play];}In the read more..

  • Page - 102

    Chapter 6[ 93 ]Why haven't we used this action to play background music? It is used for playing short sounds, as somehow removing this action does nothing. It is unclear if it is a bug or a feature, but it is present in the previous version of Sprite Kit. The music just keeps on playing.As we handle shield effects in Player.m, it is a good place to add playback sound. We will change the setShielded: method by adding music actions to it. Replace your method with the following:- (void) read more..

  • Page - 103

    Adding Game Controllers[ 94 ]To fix this, add the @import AVFoundation; statement and add the following code to your AppDelegate.m file:- (void)applicationWillResignActive:(UIApplication *)application{ // prevent audio crash [[AVAudioSession sharedInstance] setActive:NO error:nil];}- (void)applicationWillEnterForeground:(UIApplication *)application{ // resume audio [[AVAudioSession sharedInstance] setActive:YES error:nil];}This code handles AVAudioSession and prevents your read more..

  • Page - 104

    Publishing to the iTunes App StoreIn this chapter, we will discuss how to prepare your application for the App Store, what steps need to be taken, and the logistics of the process. You will learn how to register yourself as an Apple developer and post your application on the App Store.Registering as a developerIn order to be able to get your applications published on the App Store, you need to be registered as a developer with Apple. There is another added benefit of being a registered read more..

  • Page - 105

    Publishing to the iTunes App Store[ 96 ]3. After accepting the agreement, Apple will enquire you about your role as a developer or designer and what platforms you are planning to develop for.4. You will gain access to a limited number of resources as a developer, such as videos and documentation, different guides, and other things.5. The next thing that you should do is join the iOS Developer program at There are huge benefits to this. You will get read more..

  • Page - 106

    Chapter 7[ 97 ]Adding your Apple ID to XcodeAfter this, you will be able to use all the features available to registered developers.Bundle IDBundle ID is a unique identifier that allows Apple to uniquely identify your application among all others. It is used for the following purposes:• To enter in the Xcode project• To enter in iTunes Connect (a platform to configure distribution of your applications)• App ID• iCloud container ID• Other services like Game Center or in-app purchases read more..

  • Page - 107

    Publishing to the iTunes App Store[ 98 ]In order to change a bundle ID of an already existing application, select it in the project navigator, click on General present in the top menu, and if needed, open the disclosure triangle near Identity. There you will have the bundle ID as shown in the following screenshot. The usual format for the bundle ID is com.<company>.<project>, and this helps to keep your ID unique.Changing the bundle IDOccasionally, you will need to change your bundle read more..

  • Page - 108

    Chapter 7[ 99 ]Now, all you need to do is click on Use for development in Organizer when your device is connected and build the application. Organizer is an instrument within Xcode that helps you with various tasks such as adding more devices to your profile and handling crash logs. To access it, navigate to Window | Organizer in the top menu.If there are some issues, Xcode will propose to fix them as displayed in the following screenshot. Usually, clicking on the Fix Issue button will read more..

  • Page - 109

    Publishing to the iTunes App Store[ 100 ]2. Add app icons by performing the following steps:1. Open Images.xcassets in the project navigator.2. Select AppIcon.3. Add icons from resources of this chapter 58.png, 80.png, and 120.png respectively and drop them to the icon places, as shown in the following screenshot. Since our application is iPhone-only, we only need three icons. If we made an iPad version, we would have to add many more icons.Adding icons to the projectManaging applications in read more..

  • Page - 110

    Chapter 7[ 101 ]Before registering the application in the App Store, you might have to fill some legal paperwork, such as accepting agreements with Apple about various distribution issues and providing Apple with information of your bank account and tax. This is available in iTunes Connect in the Contracts, Tax and Banking tab. You won't be able to distribute without accepting those agreements.In order to register an application in iTunes Connect, perform the following steps:1. Log in to iTunes read more..

  • Page - 111

    Publishing to the iTunes App Store[ 102 ]When you are done registering your application in iTunes Connect, you will see the Waiting for Upload status in your Application Details page. If it is of some other state, fix the issues that prevent the ready state, such as missing screenshots or text.Now you will need to build the application for distribution. In order to do that, perform the following steps:1. Make sure you have distribution certificates. To check this, navigate to Xcode in the top read more..

  • Page - 112

    Chapter 7[ 103 ]Archiving your application3. The Organizer should open with details about your application, as shown in the following screenshot. You can click on Validate… there to check if everything is right, and on Distribute… as soon as you want to upload it for review. Xcode will prompt you for your Apple ID and password, and if you have your application set up in iTunes Connect, it will be uploaded for review. You can also use the Distribute… button to create a .IPA file of your read more..

  • Page - 113

    Publishing to the iTunes App Store[ 104 ]Life after uploadingYour application can have several states, which are as follows:• Waiting for upload: This is the state after you have registered your application in iTunes Connect but have not uploaded the binary yet.• Waiting for review: This is the state in iTunes Connect after uploading your application.• In review: This is the state when your application is currently in review. It takes any amount of time from minutes to days, depending on read more..

  • Page - 114

    IndexAaccelerometerabout 38-42advantages 38actions, Sprite Kit projectabout 18types 18affectedByGravity property 43animationabout 49, 50adding, to Sprite Kit project 51-55API, iOS 7 7, 8applicationbuilding, for distribution 102, 103managing, in iTunes Connect 100, 101preparing, for App Store 99, 100registering, in iTunes Connect 101, 102states, after uploading 104App Storeapplication, preparing for 99, 100Bbackground imageadding, to Sprite Kit project 22-26background musicadding read more..

  • Page - 115

    [ 106 ]basic concepts 82-85extended form-fitting controller 82extended wireless controller 82native game controllers 82notifications, handling 90, 91standard form-fitting controller 82using, in Sprite Kit project 85-89game controller support 8, 11, 12game developmentCocos2d 9framework 8, 9OpenGL 9third-party libraries 9UIKit 9game loop 19-22gamesdeveloping, for iOS 7 8gesture recognizersabout 36, 37using 36, 37Iinfinite scrollingadding 29, 30iOS 7about 5API 7, 8features 5, read more..

  • Page - 116

    [ 107 ]score labeladding 30, 31shield animationsadding 58-61SKEffectNode 17SKEmitterNode 17SKLabelNode 17SKNode 17SKShapeNode 17SKSpriteNode 17sound effectsadding 91-93Sprite Kitabout 8, 10advantages 10, 11Sprite Kit physicsabout 72-78bitmasks 72Sprite Kit projectabout 13-15actions 18anatomy 15animation, adding 51-55background image, adding 22-26background music, adding 91-93character, moving with actions 28character state, handling 56-58game controllers, using 85-89game read more..

  • Page - 117

    read more..

  • Page - 118

    Thank you for buying iOS 7 Game DevelopmentAbout Packt PublishingPackt, pronounced 'packed', published its first book "Mastering phpMyAdmin for Effective MySQL Management" in April 2004 and subsequently continued to specialize in publishing highly focused books on specific technologies and solutions.Our books and publications share the experiences of your fellow IT professionals in adapting and customizing today's systems, applications, and frameworks. Our solution based books give read more..

  • Page - 119

    Unity iOS Game Development Beginner's GuideISBN: 978-1-84969-040-9 Paperback: 314 pagesDevelop iOS games from concept to cash flow using Unity1. Dive straight into game development with no previous Unity or iOS experience2. Work through the entire lifecycle of developing games for iOS3. Add multiplayer, input controls, debugging, in app and micro payments to your game4. Implement the different business models that will enable you to make money on iOS gamesApplication Development read more..

  • Page - 120

    Learning Windows 8 Game DevelopmentISBN: 978-1-84969-744-6 Paperback: 244 pagesLearn how to develop exciting tablet and PC games for Windows 8 using practical, hands-on examples1. Use cutting-edge technologies like DirectX to make awesome games2. Discover tools that will make game development easier3. Bring your game to the latest touch-enabled PCs and tablets Learning ShiVa3D Game DevelopmentISBN: 978-1-84969-350-9 Paperback: 166 pagesGet a grip on ShiVa3D mobile game read more..

Write Your Review