With the release of iOS 7 and Xcode 5, now everybody has the possibility to develop 2D games with the Xcode integrated tools. Some would say that the App Store will be flooded by low quality games, because everybody can develop games easier now. Or that it will be an existential threat to projects like Cocos2d as their concepts have been adapted by Apple. But in general I think it is a great opportunity for everybody to bring their own ideas to life. This would only enrich the (app) world. If you create a new Sprite Kit game within Xcode 5, the whole thing looks very promising:
You’ll get a template with a project setup you can continue building on. The existing methods in the MyScene.m are easy to understand: what happens if a touch gesture is performed (
touchesBegan method), what happens every round if the game loop passes through (
update method), etc. Unfortunately with this template project you’ll get a scene with the wrong dimensions. This is a problem that should be solved right at the beginning of a project. If the dimensions of a scene and the grid system are edited later, the child nodes will be scaled accordingly. Because of this, the dimensions will not be the same as before and you have to start from the beginning with the positioning and scaling of your elements. A real torture if you have already completed graphics from the artwork.
In detail, the output of the bounds of the method
viewDidLoad will be in the portrait mode. Even if the the new Sprite Kit App is defined and displayed in landscape mode. The standard dimensions in landscape mode are 1024×768. But no matter how you’ll turn your device to change the orientation, the view will always say “I’m 768×1024″:
So the coordinates of the portrait mode will be used even if the landscape mode is displayed. It will be very hard to position new objects if the origin of a grid system is at the left bottom (0, 0) but not displayed in the visible region. So the coordinates that are available for setting and reading differ from how they will really be displayed. For example, to place a sprite on the displayed bottom left corner you have to set the position as 0 and 224.
sprite.position = CGPointMake(0, 224);
If you want to code properly it’s impossible to arrange with such values. Especially if there have to be positionings relatively to the view. As a temporary attempt at a solution, you can experiment with the scaling of the scene (
SKSceneScaleModeAspectFill, etc) or set fixed and reversed dimensions:
SKScene * scene = [MyScene sceneWithSize:CGSizeMake(786, 1024)];
But in the end this will not work, especially if you want to develop a Sprite Kit game for the iPhone and the iPad because there have to be individual solutions for every device. The positioning of your elements will become incomprehensible because the coordinates will never correspond to the relation of the width and the height of the view.
Instead of the initial
viewDidLoad method in the ViewController
viewWillLayoutSubviews should be used. With that the bound attributes will return the correct values:
// Configure the view.
SKView * skView = (SKView *)self.view;
//set the view only once, if the device orientation is
//rotating viewWillLayoutSubviews will be called again
if ( !skView.scene )
This is because at this moment when the system calls the
viewDidLoad method, no view is appended in the calling hierarchy. Therefore the size and the orientation of the view cannot be adjusted. If we step later into this hierarchy calls there will be all views available with their attributes such as size and orientation.
Now you can position all objects correctly and the display does not differ from the set coordinates in the code.
I’m looking forward to your comments or requests for new articles.