Cocos2d中各种坐标位置关系

转自:http://blog.csdn.net/liuhongwei123888/article/details/6684279 


先看一段代码:

[cpp]  view plain copy
  1. -(id) init  
  2. {  
  3.     // always call "super" init  
  4.     // Apple recommends to re-assign "self" with the "super" return value  
  5.     if( (self=[super init])) {  
  6.         CCTMXTiledMap *gameWorld = [CCTMXTiledMap tiledMapWithTMXFile:@"PositionText.tmx"];  
  7.         [self addChild:gameWorld];  
  8.         CGSize winSize = [[CCDirector sharedDirector] winSize];  
  9.         CCLOG(@"gameWorld.mapSize.width:%.2f  gameWorld.mapSize.height:%.2f",gameWorld.mapSize.width, gameWorld.mapSize.height);  
  10.         CCLOG(@"gameWorld.tileSize.width: %.2f  gameWorld.tileSize.height:%.2f", gameWorld.tileSize.width, gameWorld.tileSize.height);  
  11.         CCLOG(@"winSize.width:%.2f  winSize.height:%.2f", winSize.width, winSize.height);  
  12.           
  13.         CCSprite *pointSprite = [CCSprite spriteWithFile:@"point.png"];  
  14.         [gameWorld addChild:pointSprite z:2 tag:1];  
  15.         pointSprite.position = ccp(20,20);  
  16.         pointSprite.anchorPoint = ccp(0.5, 0.5);  
  17.           
  18.           
  19.         CCSprite *rectSprite = [CCSprite spriteWithFile:@"myrect.png"];  
  20.         [gameWorld addChild:rectSprite z:1 tag:1];  
  21.         rectSprite.position = ccp(20,20);  
  22.         rectSprite.anchorPoint = ccp(0.5, 0.5);       
  23.     }  
  24.     return self;  
  25. }  

1、加载地图:

[cpp]  view plain copy
  1. CCTMXTiledMap *gameWorld = [CCTMXTiledMap tiledMapWithTMXFile:@"PositionText.tmx"];  
2、获取手机屏幕大小(320,480)
[cpp]  view plain copy
  1. CGSize winSize = [[CCDirector sharedDirector] winSize];  
3、地图格子数:
[cpp]  view plain copy
  1. gameWorld.mapSize (10,10)       

4、地图格子大小: 

[cpp]  view plain copy
  1. gameWorld.tileSize    (20,20)  
5、整个地图大小:

     gameWorld.mapSize * gameWorld.tileSize;

     当然这里所说的是地图格子是个正方形,非正方形也容易啦。

6、anchor属性

     1) 添加一个精灵,这个精灵是个像素为1*1的红色图片,设置坐标为20,20,即在地图的第一个格子的右上角,设置anchorPoint为(0.5, 0.5)

     2) 再添加一个精灵,这个精灵是个像素为20*20的蓝色图片,设置坐标为20,20,即在地图的第一个格子的右上角,同样设置anchorPoint为(0.5, 0.5)

         运行效果是矩形精灵的中心和在点精灵的位置,即矩形精灵的锚点为第一个格子的右上角(20,20)坐标 处

     去掉两个精灵的anchorPoint属性

          运行效果和上面相同

     设置rectSprite的anchorPoint为ccp(0,0)

          运行效果是矩形精灵的左下角与点精灵重合。
     设置rectSprite的anchorPoint为ccp(1,1)

          运行效果是矩形精灵的右上角与点精灵重合。

     同理设置ccp(0.5, 1) , ccp(1, 0.5)等

     由上面可以得出:

         1)anchorPoint属性默认为ccp(0.5, 0.5)

         2)当设置(0,0)时是以左下角为锚点

         3)当设置(1, 1)时是以右上角角为锚点

         4)由此可以自己推论到底该把锚点设置在哪里

    Cocos2D使用的是OpenGL坐标系

    OpenGL坐标系:原点在左下角, X轴向右,Y轴向上

    IPhone屏幕坐标系:原点在左上角,X轴向右,Y轴向下

   很简单的判断方法:由于Cocos2D的坐标系的原点在左下角。所以精灵内部坐标原点也是左下角,即当anchorPoint为(0, 0)时即以左下角为锚点,为(1,1)时就以右上角为锚点,当然(0.5, 0.5)就是以精灵中心为锚点了。由此可以推算出-2,-3....    2, 3....   等值时精灵锚点坐标。


7、坐标转换

    

[cpp]  view plain copy
  1. -(id) init  
  2. {  
  3.     // always call "super" init  
  4.     // Apple recommends to re-assign "self" with the "super" return value  
  5.     if( (self=[super init])) {  
  6.         CCTMXTiledMap *gameWorld = [CCTMXTiledMap tiledMapWithTMXFile:@"PositionText.tmx"];  
  7.         [self addChild:gameWorld];  
  8.         CGSize winSize = [[CCDirector sharedDirector] winSize];  
  9.         CCLOG(@"gameWorld.mapSize.width:%.2f  gameWorld.mapSize.height:%.2f",gameWorld.mapSize.width, gameWorld.mapSize.height);  
  10.         CCLOG(@"gameWorld.tileSize.width: %.2f  gameWorld.tileSize.height:%.2f", gameWorld.tileSize.width, gameWorld.tileSize.height);  
  11.         CCLOG(@"winSize.width:%.2f  winSize.height:%.2f", winSize.width, winSize.height);  
  12.           
  13.         CCSprite *pointSprite = [CCSprite spriteWithFile:@"point.png"];  
  14.         [gameWorld addChild:pointSprite z:2 tag:1];  
  15.         pointSprite.position = ccp(20,20);  
  16.         //pointSprite.anchorPoint = ccp(0.5, 0.5);  
  17.           
  18.           
  19.         CCSprite *rectSprite = [CCSprite spriteWithFile:@"myrect.png"];  
  20.         [gameWorld addChild:rectSprite z:1 tag:1];  
  21.         rectSprite.position = ccp(40,40);  
  22.         rectSprite.anchorPoint = ccp(2, 2);   
  23.           
  24.         [self setIsTouchEnabled:YES];  
  25.     }  
  26.     return self;  
  27. }  
  28.   
  29. - (void) registerWithTouchDispatcher {  
  30.     [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN + 1 swallowsTouches:YES];  
  31. }  
  32.   
  33. - (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {  
  34.     CGPoint point = [touch locationInView: [touch view]];  
  35.     CCLOG(@"Screen coordX: %.2f coordY: %.2f", point.x, point.y);  
  36.       
  37.     point = [[CCDirector sharedDirector] convertToGL: point];  
  38.     CCLOG(@"OpenGL coordX: %.2f coordY: %.2f", point.x, point.y);  
  39.   
  40.     point = [self convertToNodeSpace: point];  
  41.     CCLOG(@"CCNode1 coordX: %.2f coordY: %.2f", point.x, point.y);  
  42.   
  43.     point = [self convertTouchToNodeSpace: touch];  
  44.     CCLOG(@"CCNode2 coordX: %.2f coordY: %.2f", point.x, point.y);  
  45.           
  46.         point = [[CCDirector sharedDirector] convertToUI:point];  
  47.         CCLOG(@"UIView coordX: %.2f coordY: %.2f", point.x, point.y);  
  48.          
  49.         point = [rectSprite convertTouchToNodeSpaceAR:touch];  
  50.         CCLOG(@"TouchAR coordX: %.2f coordY: %.2f", point.x, point.y);  
  51.         return YES; CCNode  
  52. }  
  53.   
  54. - (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent*)event {  
  55.       
  56. }  
  57.   
  58. - (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent*)event {  
  59.       
  60. }  

     上面的代码添加了UIView的事件处理。由于屏幕和Cocos2D采用不同的坐标系,所以我们需要进行坐标转换。

     1)首先获取屏幕坐标

     2)将屏幕坐标转换为OpenGL的坐标

     3)将OpenGL的坐标转换为Cocos2D的坐标。

     从运行结果可以看出Node1和Node2打印出的坐标相同。因为Cocos2D给我们写了covertTouchToNodeSpace方法,可以看看它的源码:

[cpp]  view plain copy
  1. - (CGPoint)convertTouchToNodeSpace:(UITouch *)touch  
  2. {  
  3.     CGPoint point = [touch locationInView: [touch view]];  
  4.     point = [[CCDirector sharedDirector] convertToGL: point];  
  5.     return [self convertToNodeSpace:point];  
  6. }  
     至于为什么OpenGL和Node1输出既然相同,为什么还要使用convertToNodeSpace,由于能力有限,希望大牛们能给告诉我答案。

    UIView输出的是将Cocos2D坐标转换为屏幕即quartz坐标。

   4) convertTouchToNodeSpaceAR是将触摸点转换为相对于rectSprite的坐标


8、判断触摸点是否在制定的精灵上

    

[cpp]  view plain copy
  1. - (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {  
  2.     CGPoint point = [touch locationInView: [touch view]];  
  3.     CCLOG(@"Screen coordX: %.2f coordY: %.2f", point.x, point.y);  
  4.       
  5.     point = [[CCDirector sharedDirector] convertToGL: point];  
  6.     CCLOG(@"OpenGL coordX: %.2f coordY: %.2f", point.x, point.y);  
  7.   
  8.     point = [self convertToNodeSpace: point];  
  9.     CCLOG(@"CCNode1 coordX: %.2f coordY: %.2f", point.x, point.y);  
  10.   
  11.     point = [self convertTouchToNodeSpace: touch];  
  12.     CCLOG(@"CCNode2 coordX: %.2f coordY: %.2f", point.x, point.y);  
  13.       
  14.     //point = [[CCDirector sharedDirector] convertToUI:point];  
  15.     //CCLOG(@"UIView coordX: %.2f coordY: %.2f", point.x, point.y);  
  16.     CCLOG(@"%d", rectSprite.textureRect.size.width);  
  17.       
  18.     CGRect rect = [rectSprite textureRect];  
  19.     rect = CGRectMake(0, 0, rect.size.width, rect.size.height);  
  20.     CCLOG(@"orgX: %.2f  orgY: %.2f  width:%.2f  height: %.2f",rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);  
  21.       
  22.     point = [rectSprite convertTouchToNodeSpaceAR:touch];  
  23.     CCLOG(@"TouchAR coordX: %.2f coordY: %.2f", point.x, point.y);  
  24.     if(CGRectContainsPoint(rect, point)) {  
  25.         CCLOG(@"You touched in the rectSprite");  
  26.     }  
  27.     return YES;   
  28. }  

9、获取触摸的是哪个tile,并改变该tile.

[cpp]  view plain copy
  1. CCSprite *rectSprite;  
  2. CCTMXTiledMap *gameWorld;  
  3. int speed = 10;  
  4. -(id) init  
  5. {  
  6.     // always call "super" init  
  7.     // Apple recommends to re-assign "self" with the "super" return value  
  8.     if( (self=[super init])) {  
  9.         gameWorld = [CCTMXTiledMap tiledMapWithTMXFile:@"PositionText.tmx"];  
  10.         [self addChild:gameWorld];  
  11.         CGSize winSize = [[CCDirector sharedDirector] winSize];  
  12.         CCLOG(@"gameWorld.mapSize.width:%.2f  gameWorld.mapSize.height:%.2f",gameWorld.mapSize.width, gameWorld.mapSize.height);  
  13.         CCLOG(@"gameWorld.tileSize.width: %.2f  gameWorld.tileSize.height:%.2f", gameWorld.tileSize.width, gameWorld.tileSize.height);  
  14.         CCLOG(@"winSize.width:%.2f  winSize.height:%.2f", winSize.width, winSize.height);  
  15.           
  16.         CCSprite *pointSprite = [CCSprite spriteWithFile:@"point.png"];  
  17.         [gameWorld addChild:pointSprite z:2 tag:1];  
  18.         pointSprite.position = ccp(20,20);  
  19.         pointSprite.anchorPoint = ccp(0.5, 0.5);  
  20.           
  21.           
  22.         rectSprite = [CCSprite spriteWithFile:@"myrect.png"];  
  23.         [gameWorld addChild:rectSprite z:0 tag: 3];  
  24.         rectSprite.position = ccp(40, 40);  
  25.         rectSprite.anchorPoint = ccp(0, 0);  
  26.                   
  27.         [self setIsTouchEnabled:YES];  
  28.     }  
  29.     return self;  
  30. }  
  31.   
  32. - (void) registerWithTouchDispatcher {  
  33.     [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN + 1 swallowsTouches:YES];  
  34. }  
  35.   
  36. - (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {  
  37.     CGPoint point = [touch locationInView: [touch view]];  
  38.     point = [self convertTouchToNodeSpace: touch];  
  39.     CCLOG(@"CCNode2 coordX: %.2f coordY: %.2f", point.x, point.y);  
  40.   
  41.     CGPoint tilePos = [self tilePosition:point];  
  42.     if(tilePos.x == -1 || tilePos.y == -1) return NO;  
  43.     CCTMXLayer *ly = [gameWorld layerNamed:@"Layer 0"];  
  44.     if([ly tileGIDAt:tilePos] != 3) {  
  45.         [ly setTileGID:0 at: tilePos];  
  46.     }  
  47.     return YES;   
  48. }  
  49.   
  50. - (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent*)event {  
  51.       
  52. }  
  53.   
  54. - (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent*)event {  
  55.       
  56. }  
  57.   
  58.   
  59. - (CGPoint) tilePosition:(CGPoint)pos {  
  60.     CGPoint point;  
  61.     CCTMXLayer *ly = [gameWorld layerNamed:@"Layer 0"];  
  62.     if(ly== nil) {  
  63.         CCLOG(@"Error: Layer not found!");  
  64.         return ccp(-1, -1);  
  65.     }  
  66.     CGSize layerSize = [ly layerSize];  
  67.     CGSize tileSize = [gameWorld tileSize];  
  68.     int x = pos.x / tileSize.width;  
  69.     int y = layerSize.height - pos.y / tileSize.height;  
  70.     if((x >= 0) && (x < layerSize.width) && (y >= 0) && (y < layerSize.height)) {  
  71.         point = ccp(x, y);  
  72.     } else {  
  73.         point = ccp(-1, -1);  
  74.     }  
  75.     if(point.x < 0) return ccp(-1, -1);  
  76.     if(point.y < 0) return ccp(-1, -1);  
  77.     if(point.x >= layerSize.width) return ccp(-1, -1);  
  78.     if(point.y >= layerSize.height) return ccp(-1, -1);  
  79.     CCLOG(@"%d, %d", x, y);  
  80.     return point;  
  81. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值