Yesterday I shipped our first ‘android’ app using cocos2dx, and I thought I’d leave a little brief on our experience using cocos2dx, java, android, eclipse, coming from Apple’s ecosystem.
First kudos to the cocos2dx team, it’s a very impressive project which requires a lot of hard work to take all the platforms into consideration. Also it makes me happy that C*+ is still the most viable language around regardless of how many billions of dollars Sun tries to convince people java is usable. .
Second here’s a link to our app on google play:
Here is the original on iTunes:
So a little background the app was originally created for my niece as something to draw with. The original iOS app release took me about 3 weeks of time, . I used cocos2d and objc for it. Then I decided to test doing some of it on cocos2dx, within 4 hours I had the basics of one of the games up on the screen, it was pretty impressive. All in all it took a total of 3 weeks to complete learning cocos2dx, jni, android.
A couple major things that had to be redone, on iOS I could have static backgrounds, iPhone, iPhone Retina , iPad, . That’s really just 2 different resolutions, then I have zwoptex sheets to do the 2x graphics. Android, on the other hand is a different beast. There are so many permutations of devices it’s impossible to use static images. So I had to dynamically generate the backgrounds and the game fields depending on the screen size. To limit the huge number of options, I just supported minimum 800 width , this still left me with according to google, 1154 supported devices. This fragmentation is bewildering.
I found out 1 week into developing that you can’t use the emulator for some openGL calls , as it would crash it. So I had to pick up a device. As my main market for iOS was tablets, I picked up a cheap android tablet which was 1024x600. I then would use the emulator to test WXVGA 480x800. The dynamic drawing worked in the cases I tried, but it was a very painful exercise in shifting pixels left and right for about two whole days. Especially as this is ad-based so the ad banners appear different sizes on different devices. , so there had to be cropping etc. I could have taken the logic further to support different sprite sheets, etc but we’ll see how the app does first. I attempted to try to use sprite sheets in the /res folders for hdpi, ldpi, etc, but it didn’t work for some reason, and I didn’t want to waste too much more time chasing it.
A couple things our app does that required some JNI. We have pop up messages, we save screenshots to your device, and we open web pages. All these things are easy on iOS, on android a bit different. When I started I was on cocos2dx .7 I believe, and had written my own notification center, and didn’t have any clue on JNI. Mid project I updated to 0.13b and found using JNI was now only an hour long process versus two days my first time. Saving images was that first thing I implemented and it was painful, trying to figure out the connections from android, java and c**. But once it all came together the later pieces were better. And using JNIHelper was much easier, making future additions a small feat.
Throughout the project I had to update our cocos2dx project a few times. Since cocos2x is a living source code, it was a painful exercise, but definitely one that was important, and I recommend people using the newer versions of the lib when starting out because of the many features coming into play. I just wish it was easier to patch when you’re mid project. As once you create your project your link to the git repo is lost. Could be something to look at in the future for myself.
Android has some major hardware issues with openGL, CCRenderTexture was a painful one. That first is what required a device as it would crash the emulator. On iOS I can call:
texture->begin(); sSprite->visit(); texture->end();
Every frame, as it was used for drawing . However on android you can’t as it’ll lock up the cpu and display trying to call that so often. I tried several things but this was something that was so easy and given to me from iOS I didn’t want to reinvent a wheel, so I came up with a couple other solutions, and finally settled on a type of back buffer. I would just draw sprites every time, then at a certain limit I would make a single call to texture~~>begin…texture~~>end, which wouldn’t slow down the device, then clear the temp sprites and start again. It gave the same visual effect, but it’s slightly less smooth on android in general . That was a big learning experience, but a good one after all. And I think some time spent with openGL by the right people could probably tweak out the performance on android later on.
Another hurdle was using eclipse, sometimes I had to debug code and use eclipse to get to the java side. During the last 2 weeks of only working on this project I had to install 3 versions of eclipse, update them each four times, install six android SDK/NDK’s and then try not to breath when I’d hit compile in fear I’d generate an AndroidManifest.xml.out file. Launching an emulator to test other screens would take about 8 minutes on an 8-core mac. On a large screen emulator it took 2 hours before crashing. . Luckily for me I was able to do 95% of all dev in XCode using the hybrid project setup. I think without that I could have never done this project. So thanks to racoon and all who put that information together.
Time will tell if the app has any success on android, if so I’ll definitely look at porting the rest of my apps over to cocos2dx. I really enjoyed doing the C*+, and cocos2dx made it really easy to translate from the original cocos2d lib. All in all excellent work by the team. I plan to be sticking around a bit more and hopefully contribute when I can.