Developing a game of endless racing for iOS using Cocos2D-iphone
Today I want to tell you about creating a game for iOS based on Cocos2D on the example of the recently released game “Bee Races” (eng. - Bee Race). The gameplay does not contain anything difficult - it is essentially an endless runner in which you need to collect points and dodge obstacles. Only instead of a red-haired girl or a treasure hunt - a two-dimensional bee flies here. For those interested, please under the cat (Achtung! Minen und a lot of abbreviations). The main sections to consider:
Cocos2d-iphone is a free 2D iOS engine that uses OpenGL for hardware accelerated graphics and supports Chipmunk or Box2D as physics engines. Actually, why do we need an engine? In order to avoid the need to write a sprite uploader (in particular from sprites), correctly start / stop animation, game timers, physics engine. Well, the main thing is hardware acceleration of graphics, if you create a game, albeit with simple graphics, based on Cocoa Touch components, then after the N-th number of game elements, you will actively get the bullet-time effect to the place and out of place, or The game generally honors in Bose. Cocos2D stores all the sprites in the cache, duplicates of one sprite are relatively light, because Sprite stores a link to the frame, but not the graphics itself. At the same time rendering the sprite in OpenGL buffer is a faster operation than rendering the Cocoa element in the tree of other graphic elements. As for physical objects - they are not directly related to sprites, so if you want a sprite, for example a flower, to contain a corresponding physical polygon, then you need to write a heir to SpriteFlower. But a more flexible system - a flower can add not one but several polygons, besides, you can even choose which of the physics engines to use. Now that we have understood all the unimaginable subtleties, have read the promised introduction to Cocos2D, let's get down to some specifics. ')
2. Use Cocos2D at the same time as StoryBoard
After all the praises of Cocos2D, it looks a bit illogical. However, in reality, for static windows it is much easier to use Interface Builder and Storyboard mechanisms. Firstly, you can mouse all these pictures, and secondly, the Storyboard software interface itself is too convenient not to use it. And yes, I know that there is cocosbuilder.com How it looks in Interface Builder: All the windows here are described in the Storyboard, and the main window of the game simply contains the Cocos2D scene as the background, and the HUD is placed on top, also made on the basis of standard elements. Pay attention to what the screen looks like - the white background is Cocos2D, which will load the necessary graphics at the start of the game, and the indicator of lives, strings, etc. is done using the builder's interface. I will not increase the already large article with a description of how this is done, I’ll just provide a link from where I copied the code and drew inspiration. Github.com/tinytimgames/CCViewController
3. Brief description of the gameplay and project structure
The gameplay is as follows - the bee hangs motionless, and according to the theory of relativity, the field rushes forward, carrying various dangers in the form of spiders and poisonous plants, as well as various buns in the form of dandelions and dandelion seeds. In Cocos2D, in fact, there is a camera object that can follow the player, but in practice it turned out to be easier to move the CCLayer on which the game world is located. Management is the simplest - tapnul on the screen, the bee flew down, tapnul again - up. Nevertheless, it turned out that the players intuitively want to make a slide and therefore, at the beginning, it is not quite convenient. The generation of the world is not uniform, but in portions according to a simple algorithm. The game has three special layers for filling with objects. During the start of the game, all three are filled with objects. Then one of the layers is taken and filled with objects for a certain length. After some time, the next section is filled, but in the second layer, and then the third. When the bee flies from the second to the third section, the first layer is cleared, and then the fourth section starts to fill in, and so on. It would have been possible to manage with two layers, but then it would have been more difficult to deal with the effect when an object that had flown from one area to another disappears (in my case such objects are only the flying seeds of an oduvan). This is due to the fact that objects are removed in one fell swoop, and not coordinatewise. The project uses the Chipmunk physics engine. I took it for two reasons. Firstly, it seems to be more simple, and secondly, I already dealt with Box2D when I used AndEngine, but I wanted something new. The engine is needed only to determine the collision of a bee with game objects, physics, as in evil birds, no.
4. We buy tools and what to do if a toad is choking
In the development of kazualki the main thing is not to dwell. I can confidently say that the main killer of Angry Birds could only be perfectionism. But even if it is not possible to make a superframe with the base class MyObject, which can be edited by a specially designed editor, this does not mean that you cannot automate many things. First of all, greatly simplifies the life of Linux-way. For example, the artist drops me in high resolution pictures in dropbox. I have a script that converts them to a lower resolution (mogrify, aha) + adds –hd version (@ 2x depending on the situation). Using Cocos2D with Interface builder is also primarily a time optimization. It can also be very useful to TexturePacker , which will pack all the sprites into one spriteshit and thus reduce the amount of memory consumed, unless you can even manage to make all the sprites in size multiples of two. TexturePacker paid, but it is worth it. With sprititshit easier in the sense that adding a new sprite, there is no need to add new files to the project. The main difficulty for 2D physics is to create a polygon using pictures, which will be loaded with a physics engine. Manually it is impossible to do this, so you need to use some kind of tool. There are various types of offers to make a vector structure using Inkspace, but I personally wrote the AndengineVertexHelper utility code.google.com/p/andengine-vertex-helper/downloads/list for this purpose . It took about one day to do it, but this thing turned out to be very useful. By default, the program is a template for code generation engine Andengine, details here www.andengine.org/forums/features/vertex-helper-t1370.html Change the template to
<real>%.5f</real><real>%.5f</real>
and get the formatting in plist.
Next, create a plist file with object descriptions:
Expand example
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plistversion="1.0"><dict><key>bee0</key><dict><key>vertices</key><array><real>-0.41786</real><real>-0.14844</real><real>-0.40714</real><real>0.07031</real><real>-0.03929</real><real>0.14453</real><real>0.27143</real><real>0.15625</real><real>0.46071</real><real>-0.02344</real><real>0.45714</real><real>-0.29688</real><real>0.26786</real><real>-0.46484</real><real>0.02143</real><real>-0.46094</real><real>-0.29643</real><real>-0.31250</real></array></dict>
To visually test the conformity of sprites and their physical representations, I strongly advise you to use this thing: github.com/nubbel/CPDebugLayer It will look much clearer: For another game, I wrote a custom map editor (I used the same PyQt) and I can say that this time has returned many times. Summarizing this section, I want to say - automate your work, even simple scripts will save you a lot of time, and most importantly, you will be busy with programming this time.
5. Than does not smell the application or connect in-app billing
By collecting in the game oduvany, the player actually gets in-game money. They can be spent on new characters. By and large, the characters do not differ by anything except the appearance - they are neither more agile nor anything else. However, where there is progress, there is a cheat. The game has the opportunity to buy dowan for real money. Since the characters are almost the same, then there is no server check for the validity of the purchase.
6. We socialize. We connect GameCenter and create a multiplayer version for two players
For the socialization of the application, I added two leaderboards - a counter for the distance traveled and the number of points scored. Although I am genuinely interested, does anyone use this at all? A more useful feature of the game center is the ability to create a multiplayer game. I did not do it in vain for the portionality of the card generation - so that the buffer is filled with a sufficient number of objects “for the future” if there are problems with the network. One of the players will be the server, the other - the client. To determine who is who, at the beginning of the game a random number is transmitted along with other meta-information about the player. The one who has it more is the server. And although the size of the buffer with objects is large enough to smooth out the unevenness of the network, the delay can lead to the fact that one player is far ahead of the other. In this case, the opponent will be shown by an arrow, i.e. its height will be displayed. The second player’s sprite was also immobile, however, its position was periodically corrected taking into account the information transmitted by it and the current position of the “world” position. Ideally (with instant network transmission), the player would “move” evenly, without transferring too much information. However, in practice, this update caused side effects - the player twitched, because even small delays between updates were noticeable. Therefore, the update was made not instant, but in the form of a tween animation in half a second. In practice, it looks as if the bee is slowing down or accelerating smoothly.
7. What did Akela miss
Following the development, some problems surfaced: 1. The aforementioned control problem - tap is not intuitive in this game.
2. The graphics stumble a bit each restart of the overall layer. Moreover, if the action is looped like repeatForever, then there is practically no such problem:
Expand example
-(void) infiniteMove{ id actionBy = [CCMoveBy actionWithDuration: BUFFER_DURATION position: ccp(-BUFFER_LENGTH, 0)]; id actionCallFunc = [CCCallFunc actionWithTarget:self selector:@selector(requestFillingNextBuffer)]; id actionSequence = [CCSequence actions: actionBy, actionCallFunc, nil]; id repeateForever = [CCRepeatForever actionWithAction:actionSequence]; [self.bufferContainer runAction:repeateForever]; }
But I made the movement gradually accelerate, so each cycle creates a new action. This causes the graphics to stumble a bit:
In other matters, when I tested "on cats", none of the subjects complained about it, but if you look closely, you can see.
3. Using Game Center for multiplayer, on the one hand, eliminated the need for authorization, and also made it possible to make the game without a server part (using only the Eagle Peer-to-Peer), but on the other hand, it made it impossible to write a bot. But this game is unlikely to gain as many users as there are always several people online. A bot in this regard is a wonderful solution - a man defeats AI, thinking that he is fighting a real person, and even the simplest game seems to be several times more interesting.
8. And finally, the publication.
In fact, there was nothing in the publication. Unless four days could not understand why the application with the status ready for sale is not visible in iTunes. It turned out that I just forgot to change the date of “Rights and Pricing -> Availability Date”, which I had already in July of this year.
I hope it was interesting to read and someone learned something useful for themselves.