cocos2diphone中兼容iphone/ipad的问题

http://www.cocoachina.com/bbs/read.php?tid=102013

【qboy原创】【2012年5月3日】
    我们知道在IOS开发中,要兼容iphone/ipad,只要把开发的版本设置为universal版就可以了,但是设置是比较简单,而里面的素材的大小和位置却是比较难控制的。原因是iphone与ipad的比例是不统一的,iphone是(480*320/960*640)3:2的屏,而ipad的屏幕是(1024*768,New ipad是2048*1536)4:3的屏。
在cocos2d-iphone中有一个很重要的方法ccp,这个方法是用于创建CGPoint。为了让IOS游戏的资源最小,我们开发了Universal版本,让其共用一套资源。由于在IOS中的高清屏(Retina960*640)比普通版本(480*320)大两倍。为了更加接近真实,我们在Ipad中采用iphone中的Retina版本素材。现在介绍一下我们的思路:
1、对ccp方法的扩展
    由于在前期开发的过程中并没有考虑Universal版本,在2.0的时候要扩展,所以以前的位置很多采用的是ccp,位置用的是iphone版本,有些是写的数字,所以要对这个方法进行扩展。我们定义了另外一个方法fcccf,这个方法可以根据系统的设备返回真实位置,传入的参数为在iphone上的X,Y轴。
#define IsPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)//定义是否是Ipad的宏
#define fcccf(__x__,__y__) GetPointbyPhoneXandY(__x__,__y__)//为了与ccp用法一致
/*
     * 传入Iphone位置
     */
    CG_INLINE CGPoint GetPointbyPhoneXandY(CGFloat x,CGFloat y){
        CGPoint p;
        if (IsPad) {
            //p=ccp((x+16)*2, (y+32)*2);
            p=ccp(x/0.46875, y/0.41667);
        }
        else{
            p=ccp(x, y);
        }
        return p;
    }
2、重写cocos2d-iphone中的一些基类方法
    我们知道在cocos2d-iphone中如果传入普通素材路径而又支持Retina版本的话,cocos2d-iphone会自动识别为Retina版本素材,其原则是(1)png,jpg图片在后缀前加@2x,例如icon.png和icon@2x.png,(2)对于plist文件和pvr.ccz文件(图片压缩处理)的文件则加“-hd”,例如KeyButton.plist与KeyButton-hd.plist。跟踪到我们可以发现其实在组织资源实,cocos2d-iphone把资源的文件名已经再处理一遍,基于这种思路。我们也可以在ipad中对文件名进行处理。
cocos2d-iphone中主要的基类有CCSprite和CCLayer,我们重写一个基类命名为FCBaseSprite:CCSprite,重写+(id)spriteWithFile:(NSString *)filename、+(id)spriteWithSpriteFrameName:(NSString*)spriteFrameName等方法。另外再扩展一个方法就是对于一些背景性质的精灵可能需要拉升,再对以上两个方法重载。则FCBaseSprite定义如下:
@interface FCBaseSprite : CCSprite {
    
}
+(id)spriteWithFile:(NSString *)filename stretch:(bool)isstretch;
+ (id)spriteWithSpriteFrameName:(NSString *)spriteFrameName stretch:(bool)isstretch;
@end
实现分别是:
/*
*stretch是否按照Ipad版进行变形
*/
+(id)spriteWithFile:(NSString *)filename stretch:(bool)isstretch {
    filename=[filename getDoubleImageFilename];
    CCNode* n= [super spriteWithFile:filename];//[[[self alloc] initWithFile:filename] autorelease];
    if (isstretch&&IsPad) {
        n.scaleX=1024.0/960;
        n.scaleY=768.0/640;
    }
    return n;
}
/*
*stretch是否按照Ipad版进行变形
*/
+ (id)spriteWithSpriteFrameName:(NSString *)spriteFrameName stretch:(bool)isstretch
{
    CCSpriteFrame *frame = [[FCBaseCCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:spriteFrameName];
    
    NSAssert1(frame!=nil, @"Invalid spriteFrameName: %@", spriteFrameName);
    
    CCNode *n=[super spriteWithSpriteFrame:frame];
    if (IsPad && isstretch) {
        n.scaleX=1024.0/960;
        n.scaleY=768.0/640;
    }
    return n;
}
getDoubleImageFilename方法是我们对NSString类型的方法一个扩展,即为了获取真实的资源文件名
方法如下:
#define Retina2x @"@2x"
#define Retinahd @"-hd"

- (NSString*)getDoubleImageFilename {
    if (IsPad) {
        NSString* filenamenoExt= [self stringByDeletingPathExtension];
        NSString* extension = [self pathExtension];
        
        //NSString *extension = [path pathExtension];

        if (![filenamenoExt hasSuffix:Retina2x]) {
//            if ([self retainCount]>0) {
//                [self release];
//            }
            self = [NSString stringWithFormat:@"%@%@.%@",filenamenoExt,Retina2x,extension];
            //NSLOG(@"new plist=%@",*plist_p);
        }
    }
    return self;
}

以上是我开发过程中的一部分,请各位大虾批评指出。

关于SDK的兼容问题,我想可以采用一个ViewController对应两个XIB文件的方式来实现。

原文地址:https://www.cnblogs.com/qboy/p/2481942.html