Cocos2d各种视图转换情况分析在本文介绍的内容,关于cocos2d下的屏幕旋转,大家都熟悉在cocos2d里,如果要设置为横屏的话,只要在attachView之前调用以下函数就可以了。
- [[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
但在实际开发中,我们往往还会有以下一些问题 自动屏幕旋转处理 在cocos2d里加入UIView cocos2d attach的不是NSWindow而是其他Subview 遇到这些问题,你会发现事情并不像你预料的那么简单直接。要解决这些问题,我们先要了解一下iPhone的屏幕旋转到底是如何处理的。
首先,iPhone上的每个View代表一个图层,每个图层有它的坐标系统。拿iPhone为例,在竖屏状态下UIView的坐标系是高480宽320的系统。而在横屏状态下,如果已经处理好屏幕旋转的情况下,它的坐标系统就应该是高320宽480. 这个大家在使用UIViewController的时候,得到的结果是显而易见的。但当你直接自己创建一个UIView并加入到NSWindow下,你会发现不管竖屏横屏,这个view还是竖屏的状态。
如果你获取一下NSWindow或者您自己View的bounds,你会得到320x480二不是480 x 320. 这是怎么回事呢?仔细想一下我们就明白了。UIViewController提供了一个方法可以让我们告诉它是否选择其管理的UIView,而NSWindow或者UIApplication都没有提供类似的方法。也就是说屏幕的旋转处理是需要View的控制者通过监听设备旋转事件来自行处理的,而UIViewController就提供了类似的实现,从而使你不需要对view进行任何操作也能随屏幕旋转。
而如果你是自己创建View而没有附着于任何ViewController的话,你就需要自己监听屏幕旋转事件了。那怎么实现View的旋转呢?每个UIView都有一个transform属性,这个属性决定了对View的默认坐标系统所做的坐标转换,所以实际上transform其实就是一个三维矩阵,用于换算一个点在前后两个坐标系的坐标(因为opengl是一个三维系统,所以是三维坐标)。默认坐标系是以View的中心为原点,View的宽为横轴,高为纵轴。
当然这个系统是以它的superView为参照系的。如果superView的坐标系是竖屏坐标,则该view的默认坐标系就是竖屏坐标,如果superView的坐标系是横屏坐标,则该view的默认坐标系就是横屏坐标。以下就以对NSWindow的一个subview所做的坐标转换来看一下怎么通过设置transform来改变View的视图朝向(之所以选择NSWindow的subview,是因为NSWindow在系统中是一直不会做transform的,如果你拿一个UIViewController的view的subview来做transform,以下代码就不准确了)。
- CGFloat radian = 0;
- CGRect bounds; switch ([UIApplication sharedApplication].statusBarOrientation)
- {
- case UIInterfaceOrientationPortrait: break;
- case UIInterfaceOrientationPortraitUpsideDown: radian = PI;
- break; case UIInterfaceOrientationLandscapeLeft: radian = -PI/2;
- bounds.size = CGSizeMake(480, 320);
- break;
- case UIInterfaceOrientationLandscapeRight:
- radian = PI/2;
- bounds.size = CGSizeMake(480, 320);
- break;
- default: break;
- }
- //设置transform变量,以当前view的center为中心
- //CGAffineTransformMakeRotation可以生成对当前坐标系做旋转处理的transform矩阵,
- //旋转角度是逆时针的radion,其中radion是该角度的弧度值。
- CGAffineTransform transform = CGAffineTransformMakeRotation(radian);
- _contentView.transform = transform; //重新设置view的大小
- _contentView.bounds = bounds;
现在我们再回来看前面提到的cocos2d的几个问题。
1、自动旋转处理 默认的cocos2d程序都是把cocos2d 的openglview attache到NSWindow里,这种情况下你就需要自己监听UIDeviceOrientationDidChangeNotification事件, 在设备旋转情况下来重新配置cocos2d。(不要监听UIApplicationDidChangeStatusBarOrientationNotification或者UIApplication的相应delegate, setDeviceOrientation:CCDeviceOrientationLandscapeLeft本身会触发这些事件)。
在监听处理函数里一般需要做以下事情,
- [[CCDirector sharedDirector] detach]; //重新设置设备旋转方向
- [[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
- //重新attach到view [[CCDirector sharedDirector] attachInView:NSWindow];
- //重新布局当前的scene
- //这里没有现成的方法,你可以自己实现。
如果你的程序是把cocos2d openglview附着到某个ViewController的view里的话,情况就不一样了. 因为ViewController是支持自动屏幕旋转的。如果你让ViewController来处理屏幕旋转(比如你还要显示navigation bar),你就不能调用[[CCDirector sharedDirector] setDeviceOrientation:...]方法了。
原因大家可以自己想想。***你需要做的就是处理屏幕旋转时scene的重新布局。所以代码就简化为如此,
- [[CCDirector sharedDirector] detach]; //重新attach到view
- [[CCDirector sharedDirector] attachInView:NSWindow]; //重新布局当前的scene
- //这里没有现成的方法,你可以自己实现。
2、在cocos2d里加入UIView 这种情况和在NSWindow里加入UIView很类似,如果你是自己创建的view,则需要自己设置view的坐标转换。如果你的view被viewcontroller管理着,则不需要自行处理。
3、cocos2d attach的不是NSWindow而是其他Subview 这种情况在1里面其实已经提到了,如果你要附着的View是被UIViewController管理并且你允许该Controller做屏幕旋转处理,你则不能调用[[CCDirector sharedDirector] setDeviceOrientation:...]方法,否则你会发现视图多旋转了一次。
小结:关于Cocos2d各种视图转换情况分析的内容介绍完了,希望通过本文的学习能对你有所帮助!