It so happened that I had to port the game with ios. The framework did not have to choose, they became Cocos2d. Before the use of the framework, I had a chance to read reviews about it and they were alarming. But as always hoping for the best. And so, this story will be about your experience in porting and using this framework. This post will be useful to those who are eyeing Cocos2s-android.
The thought of how it should be
In my humble opinion, the architecture of any game should be designed according to the least platform dependent scheme. For example, using Cocos2dx you can write a cross-platform graphical part of the game (in C ++) and then with minimal effort connect it to a project on any OS that supports this language (Android, Symbian, Meego, Bada, I don’t know about IOS, but I also think ). Of course, you will have to face the features of the OS, but efforts will be less than rewriting code from one language to another and encounter differences in the framework port.
')
As it was
And it was all very different. The code was on Obj-C, I had to port on Android to Java (then I didn’t even know about at least hope in the form of NDK from the crystax
habrauser ). On the Internet you can find two Cocos2d-iphone ports for Android:
- Cocos2d-android Hmm, I really do not say anything about this project. Build from January 2010. Perhaps all!
- Cocos2d-android-1 This project claims on its page that the project in paragraph 1 is developing too slowly, so the author decided to create his own. As I understood it, the project code.google.com/p/cocos2d-android was forked, and based on it, the version with the prefix "-1" is being sawn. Therefore, this project was chosen for work.
A little bit about the architecture of the game and framework
The framework operates with layers and scenes. Honestly, I still do not understand what the difference is between them. Is that the logic: the scene may include several layers. Let's leave this question for the comments of experts on this framework.
I admit, I have never had a chance to develop games. There was only a fan-project and it was swept as much as 3D. Therefore, I cannot comment on the chosen architecture.
The game consisted of a set of layers. Control and transitions between layers managed one scene. The whole game was based on the principle of singleton. There is one object that stores in memory all game settings and downloaded data about levels. Level data is stored in xml. Each time at each launch, this file is parsed and a singleton is created, which stores all this and access to which is always available. There is only one activit in the project, which contains a slightly glided GLSurfaceView view:
public class MainActivity extends Activity { private CCGLSurfaceView mGLSurfaceView; public static float SCREEN_WIDTH = 480; public static float SCREEN_HEIGHT = 320; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mGLSurfaceView = new CCGLSurfaceView(this); CCDirector director = CCDirector.sharedDirector(); director.attachInView(mGLSurfaceView); director.setDeviceOrientation(CCDirector.kCCDeviceOrientationLandscapeLeft); SCREEN_WIDTH = director.winSize().width; SCREEN_HEIGHT = director.winSize().height; CCDirector.sharedDirector().getActivity().setContentView(mGLSurfaceView); CCDirector.sharedDirector().setDisplayFPS(true); CCDirector.sharedDirector().setAnimationInterval(1.0f / 60); CCScene scene = CCScene.node(); IntroScene intro = new IntroScene(); scene.addChild( intro ); CCDirector.sharedDirector().runWithScene(scene); } @Override public void onPause(){ super.onPause(); CCDirector.sharedDirector().onPause(); } @Override public void onResume() { super.onResume(); CCDirector.sharedDirector().onResume(); } @Override public void onDestroy() { super.onDestroy(); CCDirector.sharedDirector().end(); } @Override public void onBackPressed(){
As a whole, a typical architecture for an android application and nothing unusual, but Cocos2d handlers are added to callbacks. It should be noted that when using 32-bit images with a gradient, the gradient begins to float. Attempts to fix it did not lead to anything. The standard way for android (when overriding the onAttachedToWindow activation method and specifying the desired color palette) did not help. All distorted and flew sizes and colors. 8-bit pictures didn't help either. Hmm, such things.
Problems in the port framework that got out
The first trabl was described in the paragraph above, and here all the rest.
The layer is not displayed on the screen. In the practice of using this framework, there is such a scheme for creating a scene:
public class MainScene extends CCLayer { public MainScene(){
So, in the version of the framework for ios, the signed line is and works great. I found a solution in the form of creating a new instance of the scene, but not the fact that it is correct.
Moving on.
There was a need to create a custom view, which will turn over the game levels beautifully. In the IOS version, this is implemented simply: the class is inherited from the UIScrollView and added on top of the graphics drawing view (GLSurfaceView). GLSurfaceView has an addView () method.
There is no such method in the port for android, and in general, perhaps, you cannot add your view in any way. This should be remembered.
Sound. When using SoundEngine, IllegalStateException is constantly popping up, which is really caught. This is probably all. No, this is gut! The tree of objects of exceptions is created, it rushes, is intercepted. Yes, what is the performance of the game, what are you talking about?
White stripe instead of a picture in a layer. The game used custom dialogs that were a layer added on top of another layer. Nothing unusual. In addition, sometimes, instead of pictures with menu buttons, a white bar popped up. Code one to one as in the ios version. Well, it would show up on weak devices, but this thing also shows up on top models. In issues on GoogleCode, there is a problem with the garbage collector. It seems to me that this refers to it, because when comparing the appearance of this error, a line appeared with the collection of objects by the garbage collector. Either my hands are crooked (which is quite likely), or the port does not take into account the peculiarities of the Android architecture.
The names of the methods and classes of the framework. That's what surprised me so much is the naming of classes and methods in the port. This fun is simple. The main classes are named the same as in the IOS version, but for example, the class of working with sound is called differently (SoundEngine instead of SimpleAudioEngine). The methods lost their prefixes, not all of course, but many. Sit and guess it or not. You watch source codes and you understand, losing time. A strange decision was chosen by the author, IMHO.
The _rotate field or any other class field. Nothing special: an angle value is assigned to the field of the inherited class. Everything is identical to the ios version, but the sprite flew out of the playing field. A few hours were spent on debag and other whistles. As it turned out, such assignments should be avoided. Properties were replaced with setters and it all worked. The magic of porting and more!
The operation of the algorithm. Very important point. The logic of the movement of the main character was implemented using an accelerometer. Pretty standard reception. But there was a serious bug that interfered with the correct passage of the level. The bottom line is: Cocos2d by tick updates the game data, graphics, and more. To do this, you need to write a method in the class: public void update (float delta). And here once again came the difference in the architecture of the two operating systems. Because of the delays associated with garbage collection (and it was frequent, because many objects, many textures), the delta was huge and ruined the entire algorithm, which simply led to terrible consequences. Experimentally, the required delta was chosen for the correct operation of the algorithm, and if it is larger, then it was simply truncated to the desired one.
Conclusion
Of the highlights, that's all. But it should also be added that not all classes are ported to Android, and many already ported ones contain stubs. In my opinion, this framework is far from the best candidate for developing games for Android. There are more successful candidates. Although, how many people - so many opinions.
May the force be with you!
UPDAt the request of the workers, I specify the FREE frameworks to which attention should be paid. But there are many others. Simply these contain more materials on StackOverflow and on the Internet as a whole.
About AndEngine I remember already there was a series of tutorials on Habré. So the most useful information will help find Google and habrapoisk.