Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

SpriteKit Framework and Physics Simulation

Save for later
  • 15 min read
  • 24 Mar 2015

article-image

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.)

Getting started with the SpriteKit game framework

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.

Getting ready

To get started with iOS game development, you have the following prerequisites for SpriteKit:

  • You will need the Xcode 5.x
  • The targeted device family should be iOS 7.0+
  • You should be running OS X 10.8.X or later

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.

How to do it...

Let's start building the AntKilling game. Perform the following steps to create your new SpriteKit project:

  1. Start your Xcode. Navigate to File | New | Project....

    spritekit-framework-and-physics-simulation-img-0

  2. Then from the prompt window, navigate to iOS | Application | SpriteKit Game and click on Next. spritekit-framework-and-physics-simulation-img-1
  3. Fill all the project details in the prompt window and provide AntKilling as the project name with your Organization Name, device as iPhone, and Class Prefix as AK. Click on Next.

    spritekit-framework-and-physics-simulation-img-2

  4. Select a location on the drive to save the project and click on Create.
  5. Then build the sample project to check the output of the sample project. Once you build and run the project with the play button, you should see the following on your device:

    spritekit-framework-and-physics-simulation-img-3

How it works...

The following are the observations of the starter project:

  1. As you have seen, the sample project of SpriteKit plays a label with a background color.
  2. SpriteKit works on the concept of scenes, which can be understood as the layers or the screens of the game. There can be multiple scenes working at the same time; for example, there can be a gameplay scene, hud scene, and the score scene running at the same time in the game.

Now we can look into the project for more detail arrangements of the starter project. The following are the observations:

  1. In the main directory, you already have one scene created by default called AKMyScene.
  2. Now click on AKMyScene.m to explore the code to add the label on the screen. You should see something similar to the following screenshot:

    spritekit-framework-and-physics-simulation-img-4

  3. Now we will be updating this file with our code to create our AntKilling game in the next sections.
  4. We have to fulfill a few prerequisites to get started with the code, such as locking the orientation to landscape as we want a landscape orientation game.
  5. To change the orientation of the game, navigate to AntKilling project settings | TARGETS | General. You should see something similar to the following screenshot:

    spritekit-framework-and-physics-simulation-img-5

  6. Now in the General tab, uncheck Portrait from the device orientation so that the final settings should look similar to the following screenshot:

    spritekit-framework-and-physics-simulation-img-6

  7. Now build and run the project. You should be able to see the app running in landscape orientation.

    spritekit-framework-and-physics-simulation-img-7

  8. The bottom-right corner of the screen shows the number of nodes with the frame rate.

Introduction to physics simulation

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:

https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Physics/Physics.html

Getting ready

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.

How to do it...

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.

  1. The initial step is to apply the gravity to the scene. Every scene has a physics world associated with it. We can update the gravity of the physics world in our scene using the following line of code:
    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.

  2. In several games we also need to set a boundary to the games. Usually, the bounds of the view can serve as the bounds for our physics world. The following code will help us to set up the boundary for our game, which will be as per the bounds of our game scene:
    // 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.

    Unlock access to the largest independent learning library in Tech for FREE!
    Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
    Renews at AU $19.99/month. Cancel anytime
  3. Every game object is inherited from the SKSpriteNode class, which allows the physics body to hold on to the node. Let us take an example and create a game object using the following code:
    // 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.

  4. The physics body properties also allow you to apply force. To apply force you need to provide the direction where you want to apply force.
    [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.

  5. You can also apply impulse instead of force. Impulse can be defined as a force that acts for a specific interval of time and is equal to the change in linear momentum produced over that interval.
    [gameObject.physicsBody applyImpulse:CGVectorMake(10.0f,   -10.0f)];
  6. While creating games, we frequently use static objects. To create a rectangular static object we can use the following code:
    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 .

Integrating physics engine with games

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.

Getting ready...

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:

spritekit-framework-and-physics-simulation-img-8

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:

spritekit-framework-and-physics-simulation-img-9

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:

spritekit-framework-and-physics-simulation-img-10

How to do it...

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.

  1. Open the file GameScene.m .This class creates a scene that will be plugged into the games. Remove all code from this class and just add the following function:
    -(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.

  2. Now when you compile and run the code, you will observe that the background image is not placed correctly on the scene. To resolve this, open GameViewController.m. Remove all code from this file and add the following function;
    -(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.

  3. Now compile and run the app. You should be able to see the background image correctly. It will look something similar to the following screenshot:
    spritekit-framework-and-physics-simulation-img-11
  4. So now that we have the background image in place, let us add gravity to the world. Open GameScene.m and add the following line of code at the end of the initWithSize method:
    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.

  5. Now as we have removed the gravity to make the object fall freely, it's important to create a boundary around the world, which will hold all the objects of the world and prevent them to go off the screen. Add the following line of code to add the invisible boundary around the screen to hold the physics objects:
    // 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:

    spritekit-framework-and-physics-simulation-img-12

  6. Now we have our surface ready to hold the physics world objects. Let us create a new physics world object using the following line of code:
    // 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.

  7. Now compile and run the application; you should be able to see the circular ball on the screen as shown in screenshot below:

    spritekit-framework-and-physics-simulation-img-13

  8. The circular ball is added to the screen, but it does nothing. So it's time to add some action in the code. Add the following line of code at the end of the initWithSize method:
    [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.

  9. Now compile and run the project. You should be able to see the ball moving and then collide with the boundary and bounce back, as there is no friction between the boundary and the ball. So now we have the infinite bouncing ball in the game.
    spritekit-framework-and-physics-simulation-img-14

How it works…

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:

  • Restitution property defines the bounciness of an object. Setting the restitution to 1.0f, means that the ball collision will be perfectly elastic with any object. This means that the ball will bounce back with a force equal to the impact.
  • Linear Damping property allows the simulation of fluid or air friction. This is accomplished by reducing the linear velocity of the body. In our case, we do not want the ball to slow down while moving and hence we have set the restitution to 0.0f.

There's more…

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.

Summary

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.

Resources for Article:


Further resources on this subject: