Environment: Cocos2d V2.x , Xcode 4.5.2 , MountainLion , SpriteHelper Pro 1.8.307 , LevelHelper Pro 1.4.989
目的:希望在游戏启动时能弹出一个输入框让用户输入信息。
参考:
http://stackoverflow.com/questions/13297750/how-to-get-user-input-using-cocos2d
http://blog.csdn.net/tskyfree/article/details/8292544
http://www.cocos2d-iphone.org/forums/topic/what-is-the-difference-between-converttoworldspacear-and-converttoworldspace
思考: 既然可以通过addView来添加UITextField,那不是实现起来简单了??
结果:可以实现,但是中间几个点会扰乱思维,导致可能出现的UITextField位置不对!!
步骤:
1. 利用Xcode创建一个cocos2d V2.x项目,不动文件以及代码,保持默认
2. 利用LevelHelper创建一个Level,放入一个Sprite
3.
//Xcode里HelloWorldLayer.m里实例化
LevelHelperLoader *loader=[ [ LevelHelperLoader alloc] initWithFileContent"@"myGameLevel"];
[loader addSpritesToLayer:self];
CCSprite* mysprite=[loader spriteWithUniquename:@"mySpriteName"]; //这个Sprite其实是辅助定位用的,不起实际作用。等会儿UITextField我会与它重合
//容易出错的地方....
CGPoint worldPositionInOpenGL=[mysprite.parent convertToWorldAR:mysprite.position];
CGPoint screenPositionInQuartz=[[CCDirector sharedDirector] convertToUI:worldpositionInOpenGL];
CGPoint upperLeftnOfMyTextField=CGPointMake( screenPositionInQuartz.x-mysprite.contentSize.width/2, screenPositionInQuartz.y-mysprite.contentSize.height/2 );
UITextField field=[ [UITextField alloc] initWithFrame:CGRectMake( upperLeftnOfMyTextField.x, upperLeftnOfMyTextField.y,
mysprite.contentSize.Width, mysprite.contentSize.Height)];
field.placeholder=@"ABCDEFG";
[ [CCDirector sharedDirector:view] addSubView:mytextfield];
容易出错的地方....
1. 动态生成的UITextField默认是看不见边框的,所以先给出placeholder,这样我们马上就能知道它的位置
2. UITextField的initWithFrame()里面头2个参数是指文本框的左上角X,Y值。Developer.Apple.com的官方文档没有详细说明,这是个小问题
3. CCSprite默认的anchorPoint是0.5,0.5即本地坐标系的原点在我的Sprite的中心
4. Sprite的Position是相对父坐标系的,不是屏幕坐标系,而我们在初始化UITextField时必须指定屏幕坐标。所以必须先使用convertToWorldSpace或convertToWorldSpaceAR转换到world space坐标系里
5. convertToWorldSpace是把(0,0)作为sprite的坐标原点的,所以我使用了converToWorldSpaceAR:mysprite.position
6. converToWorldSpaceXX是使用Sprite的parent来操作的,即[mysprite.parent converToworldSpace:mysprite.position]才是正确的。
根据某文说即使你是SpriteD,而它的parent是SpriteC,而C的parent是SpriteB,B的parent是SpriteA,我们转换SpriteD的position时不用担心SpriteB与SpriteA,最终SpriteD.position会转换到world space坐标系里。
用[mysprite convertToWorldSpace:mysprite.position]是不对的,很不幸的是cocos2d的官方文档也没对此说明。
7. world space其实是用的OpenGL坐标系的(屏幕左下角是原点,cocos2d也是用的这个坐标系),而UITextField用的是Quartz坐标系(屏幕左上角是原点。所有标准UIKit的控件都用这个坐标系)。 所以Quartz坐标要使用 CCDirector的convertToUI方法转换我们得到的world space中的坐标
不照上面做就会导致UITextField无法与Sprite左上角重合
开始时没理清楚OpenGL与Quartz的区别,结果位置偏了,折腾了一天
之后理清楚就正常了