First experience developing a game on the Sprite Kit

After creating and laying out games on the Sprite Kit in the App Store, I would like to share my experience. I’ll talk a little about the creation of gameplay, as well as about attempts to contact publishers and impressions of the framework.

Idea

So, our goal was to come up with and create a game in one-tap endless genre. We are a team of three people: a programmer (he is the author of the article), a designer (he is the project manager) and an illustrator-animator. As in all games of this genre, the game process should be quite simple, controlled by one touch and at the same time should be addictive. After some thought, an idea was born, and after some time a certain prototype of the game.

So, a character jumps from one swinging platform to another. As you progress through the game is complicated by changing the parameters of the platforms. After landing on the next platform, the hero runs to its edge. After the jump, the visible area of ​​the game shifts.

Implementation

Started by creating a “swing”. Each of them consists of a holder (at the very top), a beam and a platform. All this is connected using two swivel joints ( SKPhysicsJointPin ). Then it was necessary to ensure that the hero stood on the platform and was not chatting from side to side. I tried several approaches. I tried to manually set the velocity of the object in the update method depending on the speed of the platform on which it stands (advised on stackoverflow), however, this led to an unpleasant effect of “delay”. The hero, as it were, did not keep up with his platform and moved a little late. Experiments with a change in the friction of the object also led to some unpleasant effects. As a result, the only way to fix the hero on the platform I found is to add SKPhysicsJointFixed . Before jumping, delete it and then add it again when necessary.

In order for the hero to jump, you need to assign him a certain impulse. The strength of the jump is regulated by the player. It depends on the duration of pressing. Here it was necessary to slightly increase the impulse if the platform moves backward at the moment of the jump, otherwise the hero took off almost vertically up and lands on the same platform.

The next task is to correctly fix the moment of landing and after landing again add joint , which will keep the hero on the platform. It turned out that just adding joint in the didBeginContact method was not enough , because, firstly, it is called when there is still some space between the objects and when a joint is added, the hero seemed to hang a few centimeters above the platform, and secondly, he can hit the platform from the side and in this case you do not need to do anything. I solved the first problem by adding a boolean variable that indicates that the contact was fixed and checking it in the next call to the didSimulatePhysics method . In this case, the junction is already added to didSimulatePhysicsand objects at this moment are close to each other. And in order to exclude cases when the hero strikes from the side, we check the relative position of the hero and the platform to make sure that the hero is on the platform.

After landing, the hero must run to the edge of the platform. Here the method of manually setting the velocity to the hero just worked . In the update method, we take the velocity of the platform on which it should run, add some positive x- value , and assign the received velocity to the hero. As a result, the hero moves around the platform. In this case, if there is a delay effect, then it is not visible and everything looks good. After reaching the edge of the platform, we add the fixing joint again.

The whole scene consists of separate nodes with different zPosition values , which eventually form layers: a layer for the hero and platforms, a layer for the background, a layer for interface elements. After the hero lands, the layers are shifted, while the background layer moves more slowly than the layer with the hero, to ensure the effect of the remoteness of the background. It turns out that the x coordinateeach subsequent “swing” increases inside one’s own node, and the node itself shifts to the left inside the scene. Here I came across different behaviors in different versions of iOS. In versions starting with iOS 7.1, the coordinates of the joints must always be converted to the coordinates of the scene, otherwise the objects connected by these joints start to behave very strange. And in versions prior to 7.1, this is not necessary, otherwise, again, objects begin to hang randomly in the air.

In general, what happened at this stage was already playable and was quite interesting.

Graphics

Meanwhile, the illustrator came up with and drew the main character.

Everyone really liked it and soon the main animations were created. So, I got all the necessary sequences for adding animations. We put each type of animation in a separate texture atlas and add it to the project. After starting the game, before the appearance of the game scene, load all the textures and save in separate arrays. We create methods for all animations, each of which “forces” the hero to delete all previous animations and adds the corresponding new one.

We worked separately on situations when the hero lands on the very edge of the platform. Made animations for such cases. And I had never before paid attention to how such situations are resolved in other games. After all, since the hero landed on the platform in some part, he should not fall anymore, but a simple landing here will look strange.

Then the background and textures for the plafthorm were created. The background was divided into three layers, each of which moves at a different speed. This adds even more volumetric effect. The platform and beam textures are made up of repeating patterns. Also added several animations (flashing stars, falling comets) that randomly appear on the background, in order to slightly diversify the appearance.

I found strange behavior when adding semi-transparent viewsUIView in the view of the SKView class . A translucent view is not displayed if it does not have any opaque child views. More precisely, when it is added, it appears for a very short time, and then disappears. That is, if you add a view with alpha = 0.5 to SKView without any child views, it will not be displayed. You must add at least one child view with alpha = 1 to it so that it displays normally.

We also added a bit of a competitive element, using the capabilities of the game center. During the game, the results of friends are pumped up and displayed. The result is shown directly on the platform, which one of the friends reached, in the form of a translucent shadow of the protagonist.

Impressions of the Sprite Kit

Before starting work on the game, I read all kinds of articles comparing various game frameworks. As the advantages of the Sprite Kit, it was always indicated that it is part of Cocoa and it is easiest to start using it for the first project. For me, this was a decisive factor when choosing a framework. The disadvantages of the Sprite Kit, noted in the articles, seemed to me insignificant for our project. As a result, the main drawback for me was that the refresh rate of physics in the Sprite Kit depends on fps. That is, at the moments when the FPS falls (for example, during the display of the game center banners), the stability of physics leaves much to be desired. It took a lot of time to catch and fix the bugs caused by this. Also, it was not possible to get rid of small delays when changing hero animations on older devices (up to iPhone 5). There is no experience with other frameworks, with the exception of a few lessons on Cocos2D, so there is nothing to compare with. But there are plans to rewrite the game on Cocos2D with Box2D and compare the results. Otherwise, everything is very convenient and simple. I think for games with very simple physics, or without it at all, the Sprite Kit is ideal if developed only for iOS.