





















































In this article by Bhanu Birani, author of the book iOS Game Programming Cookbook, you will learn about the SpriteKit game framework and about the physics simulation.
(For more resources related to this topic, see here.)
With the release of iOS 7.0, Apple has introduced its own native 2D game framework called SpriteKit. SpriteKit is a great 2D game engine, which has support for sprite, animations, filters, masking, and most important is the physics engine to provide a real-world simulation for the game.
Apple provides a sample game to get started with the SpriteKit called Adventure Game. The download URL for this example project is http://bit.ly/Rqaeda.
This sample project provides a glimpse of the capability of this framework. However, the project is complicated to understand and for learning you just want to make something simple. To have a deeper understanding of SpriteKit-based games, we will be building a bunch of mini games in this book.
To get started with iOS game development, you have the following prerequisites for SpriteKit:
If all the above requisites are fulfilled, then you are ready to go with the iOS game development. So let's start with game development using iOS native game framework.
Let's start building the AntKilling game. Perform the following steps to create your new SpriteKit project:
The following are the observations of the starter project:
Now we can look into the project for more detail arrangements of the starter project. The following are the observations:
We all like games that have realistic effects and actions. In this article we will learn about the ways to make our games more realistic. Have you ever wondered how to provide realistic effect to game objects? It is physics that provides a realistic effect to the games and their characters. In this article, we will learn how to use physics in our games.
While developing the game using SpriteKit, you will need to change the world of your game frequently. The world is the main object in the game that holds all the other game objects and physics simulations. We can also update the gravity of the gaming world according to our need. The default world gravity is 9.8, which is also the earth's gravity, World gravity makes all bodies fall down to the ground as soon as they are created.
More about SpriteKit can be explored using the following link:
The first task is to create the world and then add bodies to it, which can interact according to the principles of physics. You can create game objects in the form of sprites and associate physics bodies to them. You can also set various properties of the object to specify its behavior.
In this section, we will learn about the basic components that are used to develop games. We will also learn how to set game configurations, including the world settings such as gravity and boundary.
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
Currently we have set the gravity of the scene to 0, which means the bodies will be in a state of free fall. They will not experience any force due to gravity in the world.
// 1 Create a physics body that borders the screen
SKPhysicsBody* gameBorderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
// 2 Set physicsBody of scene to gameBorderBody
self.physicsBody = gameBorderBody;
// 3 Set the friction of that physicsBody to 0
self.physicsBody.friction = 0.0f;
In the first line of code we are initializing a SKPhysicsBody object. This object is used to add the physics simulation to any SKSpriteNode. We have created the gameBorderBody as a rectangle with the dimensions equal to the current scene frame.
Then we assign that physics object to the physicsBody of our current scene (every SKSpriteNode object has the physicsBody property through which we can associate physics bodies to any node).
After this we update the physicsBody.friction. This line of code updates the friction property of our world. The friction property defines the friction value of one physics body with another physics body. Here we have set this to 0, in order to make the objects move freely, without slowing down.
// 1
SKSpriteNode* gameObject = [SKSpriteNode spriteNodeWithImageNamed: @"object.png"];
gameObject.name = @"game_object";
gameObject.position = CGPointMake(self.frame.size.width/3, self.frame.size.height/3);
[self addChild:gameObject];
// 2
gameObject.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:gameObject.frame.size.width/2];
// 3
gameObject.physicsBody.friction = 0.0f;
We are already familiar with the first few lines of code wherein we are creating the sprite reference and then adding it to the scene. Now in the next line of code, we are associating a physics body with that sprite. We are initializing the circular physics body with radius and associating it with the sprite object.
Then we can update various other properties of the physics body such as friction, restitution, linear damping, and so on.
[gameObject.physicsBody applyForce:CGVectorMake(10.0f, -10.0f)];
In the code we are applying force in the bottom-right corner of the world. To provide the direction coordinates we have used CGVectorMake, which accepts the vector coordinates of the physics world.
[gameObject.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)];
SKSpriteNode* box = [[SKSpriteNode alloc] initWithImageNamed: @"box.png"];
box.name = @"box_object";
box.position = CGPointMake(CGRectGetMidX(self.frame), box.frame.size.height * 0.6f);
[self addChild:box];
box.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:box.frame.size];
box.physicsBody.friction = 0.4f;
// make physicsBody static
box.physicsBody.dynamic = NO;
So all the code is the same except one special property, which is dynamic. By default this property is set to YES, which means that all the physics bodies will be dynamic by default and can be converted to static after setting this Boolean to NO. Static bodies do not react to any force or impulse. Simply put, dynamic physics bodies can move while the static physics bodies cannot .
From this section onwards, we will develop a mini game that will have a dynamic moving body and a static body. The basic concept of the game will be to create an infinite bouncing ball with a moving paddle that will be used to give direction to the ball.
To develop a mini game using the physics engine, start by creating a new project. Open Xcode and go to File | New | Project and then navigate to iOS | Application | SpriteKit Game. In the pop-up screen, provide the Product Name as PhysicsSimulation, navigate to Devices | iPhone and click on Next as shown in the following screenshot:
Click on Next and save the project on your hard drive.
Once the project is saved, you should be able to see something similar to the following screenshot:
In the project settings page, just uncheck the Portrait from Device Orientation section as we are supporting only landscape mode for this game.
Graphics and games cannot be separated for long; you will also need some graphics for this game. Download the graphics folder, drag it and import it into the project. Make sure that the Copy items into destination group's folder (if needed) is checked and then click on Finish button. It should be something similar to the following screenshot:
Now your project template is ready for a physics-based mini game. We need to update the game template project to get started with code game logic. Take the following steps to integrate the basic physics object in the game.
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { SKSpriteNode* background = [SKSpriteNode spriteNodeWithImageNamed:@"bg.png"]; background.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); [self addChild:background]; } }
This initWithSize method creates an blank scene of the specified size. The code written inside the init function allows you to add the background image at the center of the screen in your game.
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
}
To ensure that the view hierarchy is properly laid out, we have implemented the viewWillLayoutSubviews method. It does not work perfectly in viewDidLayoutSubviews method because the size of the scene is not known at that time.
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
This line of code will set the gravity of the world to 0, which means there will be no gravity.
// 1 Create a physics body that borders the screen
SKPhysicsBody* gameborderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
// 2 Set physicsBody of scene to borderBody
self.physicsBody = gameborderBody;
// 3 Set the friction of that physicsBody to 0
self.physicsBody.friction = 0.0f;
In the first line, we are are creating an edge-based physics boundary object, with a screen size frame. This type of a physics body does not have any mass or volume and also remains unaffected by force and impulses. Then we associate the object with the physics body of the scene. In the last line we set the friction of the body to 0, for a seamless interaction between objects and the boundary surface. The final file should look something like the following screenshot:
// 1
SKSpriteNode* circlularObject = [SKSpriteNode spriteNodeWithImageNamed: @"ball.png"];
circlularObject.name = ballCategoryName;
circlularObject.position = CGPointMake(self.frame.size.width/3, self.frame.size.height/3);
[self addChild:circlularObject];
// 2
circlularObject.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:circlularObject.frame.size.width/2];
// 3
circlularObject.physicsBody.friction = 0.0f;
// 4
circlularObject.physicsBody.restitution = 1.0f;
// 5
circlularObject.physicsBody.linearDamping = 0.0f;
// 6
circlularObject.physicsBody.allowsRotation = NO;
Here we have created the sprite and then we have added it to the scene. Then in the later steps we associate the circular physics body with the sprite object. Finally, we alter the properties of that physics body.
[circlularObject.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)];
This will apply the force on the physics body, which in turn will move the associated ball sprite as well.
There are several properties used while creating physics bodies to define their behavior in the physics world. The following is a detailed description of the properties used in the preceding code:
You can read about all these properties in detail at Apple's developer documentation: https://developer.apple.com/library/IOs/documentation/SpriteKit/Reference/SKPhysicsBody_Ref/index.html.
In this article, you have learned about the SpriteKit game framework, how to create a simple game using SpriteKit framework, physics simulation, and also how to integrate physics engine with games.
Further resources on this subject: