zoukankan      html  css  js  c++  java
  • 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文件的方式来实现。

  • 相关阅读:
    C#Table转成json工具
    设置npm注册表配置为淘宝镜像
    总结js面向对象调用的几种模式
    gitHub初使用
    对象的防篡改
    offsetWidth clientWidth scrollWidth的区别
    js中的new操作符
    setTimeot与setInterval定时器
    事件捕获 事件冒泡和事件委托
    一个页面从输入URL到加载完成,发生什么事
  • 原文地址:https://www.cnblogs.com/qboy/p/2481942.html
Copyright © 2011-2022 走看看