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文件的方式来实现。