Dynamic Layouts with SpriteBuilder & Cocos2D 3.x - Pt 1
Project: Dynamic Layouts with SpriteBuilder and Cocos2D 3.x
Project: Dynamic Layouts with SpriteBuilder and Cocos2D 3.x
Cocos2D 3 comes with a completely new positioning system that provides many different position types. This new system helps us to define layouts relative to the screen size and support multiple device sizes out of the box.
This tutorial will walk you through the different options and give you examples of how to use the new positioning types in SpriteBuilder. This is the structure of this tutorial:
I'll first give you brief overview of the different options, then we will use them in practical examples. Here are the different parameters that give you fine grained control over your layouts:
Position type: can be individually chosen for vertical positioning and horizontal positioning. There are three options each:
Points: this is the default. Points are scaled by a UIScaleFactor. In case you built a tablet version of your game the points will be scaled by this factor. The default UIScaleFactor for tablet is 2.0.That means positions are doubled on a tablet.
Size type: can be individually chosen for width and height. There is a total of 5 different options:
Points: again, this is the default value. The size is scaled by the UIScaleFactor.* UI Points: sizes are provided in absolute points. Sizes stay the same on all device types.
This indeed is a huge list of options! All the concepts will be a lot more comprehensible if we use them in some example layouts. Next we will take a brief look at Screen Modes, another layout feature provided by SpriteBuilder.
SpriteBuilder has two different Screen Modes:
The Screen Mode influences how your Scenes change when running on different devices. When you choose Flexible the scenes will resize to fill the screen of the current device type. Therefore when you express positions or sizes of Nodes in % of parent container they will change on different device types, depending on the screen size of the device.
When you choose the Fixed Screen Mode your scenes will always have the same size. Therefore positions and sizes of Nodes expressed in % of parent container will never change.
Here's a short illustration to make the concepts comprehensible, the size of the yellow block is expressed as 20% of parents width and height:
As you can see on the left side, using the flexible mode, the width of the yellow block changes on different device types. On a wider screen the block appears wider, too.
On the right side, using fixed mode the size of the block will stay the same on any screen size.
Along with these two screen sizes come two different representations in SpriteBuilder. Flexible will allow you to switch between different device types (3.5 inch phone, 4 inch phone, tablet) to get a preview of how sizes and positions change. Fixed will give you only one representation, highlighting safe and unsafe areas of the screen:
The safe area will be visible on any device type (phones & tablets). The unsafe area will only be visible on certain device types. On an iPhone 5 for example, the left and right edges of the unsafe area will be visible because the phone is long. On an iPad the top and bottom edges of the unsafe area will be visible because comparing the screen ratio it is higher than phones.
We will discuss how to use the fixed screen mode later on, however the basic concept is to keep all the relevant content in the safe area and add padding or larger background images to cover the unsafe area.
You now have learned about different options to scale up positions and sizes of Nodes for different device types. If you want control over wether Sprites are scaled up or not you need to understand the asset handling in SpriteBuilder in detail.
When using SpriteBuilder you by default provide 4x images to use in your game. From these 4x images SpriteBuilder derives all the smaller image sizes. Let's assume you have a character that has a size of 50x50 points on a iPhone screen, then the 4x image will have a resolution of 200x200 points.
The table below demonstrates the default image sizes used for the different device types in SpriteBuilder:
|Device||Default Image Type||Size on screen (points)||Resolution|
|iPhone||1x||50 x 50||50 x 50|
|iPhone Retina||2x||50 x 50||100 x 100|
|iPad||2x||100 x 100||100 x 100|
|iPad retina||4x||100 x 100||200 x 200|
This means that by default Sprites on the iPad appear double size than on the iPhone. The underlying assumption is that a tablet has more or less the double amount of screen space of a phone - so doubling the image size will lead to a similar representation of the game on phones and tablets.
You can see/change the default settings displayed in the table above when you select an image that is part of your SpriteBuilder project:
If you ever don't want your tablet version to scale images up, select 2x for the tablethd instead of 4x. Then all assets will have the same size on the screens of phones and tablets. We will be discussing this approach in the second part of the tutorial when we look at different ways to use/avoid upscaling on tablets.
We are going to get started with our first example in SpriteBuilder. Open SpriteBuilder and create a new project.
The most important goal we are trying to achieve when using the different layout and sizing options is to create a responsive user interface. When you create a game you should try to target as many device types as possible (3.5 inch iPhones, 4 inch iPhones, iPads, and thanks to Apportable a huge amount of Android devices). All of these devices come with different screen sizes. SpriteBuilder and the new positioning options can help you to define UIs that look good on all kind of devices. In SpriteBuilder's top bar you can open Document -> Resolution and choose between different device types.
These options will give you a nice preview of how your interface will change depending on the screen size of the device it is running on.
Now lets take a look at our first simple layout challenge. Assume we want a Node that:
If you worked with this feature of SpriteBuilder before you might know that we need to modify the anchor point and the reference corner to achieve this position. Add a Color Node to your MainScene.ccb and apply the necessary positioning and sizing options:
You need to change three options to make the node stick in the top right corner:
Now you can switch between the different resolution types and see that the Node is always placed in the top right corner.
A common and fairly simple layout challenge. We want a Node that:
Add a second Color Node to MainScene.ccb:
You need to chose the following options to place and size the Node as described:
This layout is a little more tricky: You have two Nodes that shall use the entire screen size, one has a fixed size and the other one shall use the rest of the available space. Luckily SpriteBuilder reduces the complexity of this problem.
Remove the two Nodes you created for the earlier examples. Now create a new Color Node and add it to the left part of the screen:
Set the position to (0,0). Set the height to be 100% of parent container, and set the the width to 150.
Now add the second Node that shall resize to take the rest of the available screen size:
You need to set the Node up as following:
Now you can again switch between different device types and you will see the Nodes resizing correctly.
In very rare cases all of the layout options aren't enough.
If you want to provide a universal game, but for a part of your game need individual CCB files for phones and tablets you can accomplish this manually by loading different CCB files in code.
You could be creating a Gameplay-phone.ccb and a Gameplay-tablet.ccb and check the device type in code before loading either of the two. However, for most types of games we do not recommend this approach - it comes with a large maintenance overhead. That's why we will not discuss this option in detail and only mention it to complete the list of different options.
Well done! While this is only the tip of the layout iceberg part 1 of this tutorial should give you a good idea about the different options you have to solve layout challenges and achieve compatibility for a lot of different device types. Spend some time using all of them and experimenting how they work together.
Now you can move on to part 2 and learn how to build a table compatible game with SpriteBuilder!
If you have feedback on this tutorial or find any mistakes, please open issues on the GitHub Repository or comment below.