views:

557

answers:

3

Hi all,

I'm trying to create a relatively simple game with 2D graphics which has somewhat complicated animations. I tried to develop the game with the basic Core Graphics and Core Animation libraries but the animation performance of the game objects is not satisfactory (i.e. jerky/delayed).

So, I am now looking into Cocos2D which looked very promising until I checked into the high resolution support for the iPhone 4. This doesn't seem to work very well at all, but then again, i've just started to look into it.

The one thing the documentation seems to say about the issue it so simply use the CCDirector to set the scale factor, which can be done like so:

if( [[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    [[CCDirector sharedDirector] setContentScaleFactor: [[UIScreen mainScreen] scale] ];
}

However, this doesn't give the behavior I expect. It simply doubles the amount of pixels to work with, meaning I have to take the 'double pixels factor' into account in all my code.

In the Core Graphics/Animation libraries the coordinate space we work with doesn't change. Behind the curtains it simply doubles everything to fill the iPhone 4 high res screen and uses the @2x images where available. This actually works very well and the game logic need not take the device's resolution into account. Cocos2D seems to have implemented this pretty badly, making me not want to go onboard the Cocos2D train.

I found some other topics on the subject but there were no real answers that didn't involve workarounds. Is this being fixed? Am I doing it wrong or is Cocos2D simply not high res ready? Are there any alternatives to Cocos2D which can give me what I need?

A: 

Cocos2D uses the UIImage methods imageWithContentsOfFile: and initWithContentsOfFile: which, despite what the documentation says, don't correctly return the @2x versions of images when on the iPhone 4.

This is a known bug and apparently Apple are working on it.

However, some people believe this is correct behaviour as it is passing a path to a specific file, rather than a name of a file and letting the system decide which one to use. In that case, I have proposed that the documentation be updated to reflect this fact if it is true. We'll see how Apple respond.

Jasarien
Thanks for your reply. I did indeed understand the same thing, but this is not the only problem I found. If cocos would only use low res instead of high res images on an iPhone4, the result would just be less crisp, but still in the same coordinate space as on a low res (3GS) iPhone. This is not the case. Instead of working with 320x480 in all my code, I'd have to work with both 320x480 and 640x960 depending on the resolution of the device. This I do not like :)
bouma
+3  A: 

Sorry for the shameless self-promotion but I guess it can help you out. I've written two small blog posts on high res in cocos2d recently and put them up on our website.

The first one goes into detail as to how to get cocos2d up and running including a proposed fix for how to implement the auto-loading behaviour of regular vs high-res images.

Additionally, there is a second post trying to go into some details on the difference between points and pixels. UIKit is entirely based on points which is why you do not have to re-work all your coordinates. In contrast to UIKit, cocos2d works based on pixels and is therefore resolution-dependent. You can provide cocos2d with the means to work with points rather than pixels through some rather simple conversions. I've implemented those as categories for CCDirector and CCNode to make them easy to work with. Obviously, the methods in these categories are not the only ones one should "pointify". Specifying sizes on CCLabel or any positions on CCMoveBy, for example, are pixel-based and thus would have to be reworked also ...

Have a look at the blog at: http://apptech.next-munich.com/ (I would've directly linked to the articles but as a new user I can only post a single link in an answer).

Hope this helps and gets you started!

Benjamin
Hi and thanks for your answer. Your self-promotion is appreciated as you have both answered my question and explained it simpler. Indeed, Cocos uses pixels where UIKit uses points which is the problem i ran into. The solution you describe is as simple as it is effective. The fact that such a solution is required makes me say that Cocos is not truly high-res ready, as it does not implement the point coordinate space like UIKit. Hopefully this will be implemented soon by Cocos2D. Non-the-less; you have answered my question and will thus receive the prize :)
bouma
I'm glad that I could help you out! I also think that cocos2d should gradually adopt the notion of point instead of pixel though I think this will be quite a big change as most likely every class in the framework will have to be touched. So don't expect any magic too soon :)
Benjamin
+1  A: 

I'm in the process of figuring out a pretty simple solution to this. My progress is posted here: http://www.cocos2d-iphone.org/forum/topic/8511#post-50361

Basically you scale your the texture source rects in CCSprite, but nothing else, that way you get to use your same 320x480 coordinate system(aka a points system), but you get high res graphics.

You should combine my technique with this with point #2 from Benjamin's blog here, so you don't get memory problems: http://apptech.next-munich.com/2010/07/high-res-using-cocos2d-on-ios-4.html

Matt Rix