「cocos2d-x」瓦片地图学习(1)(2)

「cocos2d-x」之直角瓦片地图学习(1)

cocos2d-x支持直角(90度)瓦片地图和斜角(45度)瓦片地图,直角瓦片地图用于2d游戏的地图,斜角瓦片地图给大脑形成3d的幻觉,所以常用于3d游戏的地图。

本文只将常用的直角瓦片地图。

基本概念

直角瓦片地图可以用Tiled Map Editor制作,同时tiled生成的TMX格式的地图也是cocos2d推荐的地图格式。

地图集(tiles sets)

  • 被嵌套的瓦片地图不被支持(如 使用瓦片素材组与其他图片)
  • 仅支持封装瓦片地图组(仅有瓦片素材组被导入地图文件)
  • 每个Layer最多支持1套瓦片素材组。

    地图层(tiles layer)

    • Tiles中Layer的数量没有上限。
    • 每一个Layer可以被CCTMXLayer类表示( 为CCSpriteSheet的子类)
    • 每一个单一的瓦片被CCSprite表示(父节点为CCTMXLayer)

      对象组 (Object Groups)

      • 瓦片地图支持对象组
      • 对象又称精灵,指在瓦片地图中不受瓦片图素限制的精灵,可以精确到像素

        坐标(Coordinates)

        64*32的Tiled瓦片地图文件的坐标系统为:

        • (0, 0): 左上角
        • (63, 31): 右下角(坐标下标从0开始)

          全局标识(GIDS)

          • 瓦片的GID是一个全局标识量,他的范围从正整数1开始,到瓦片地图中tile的总量
          • 如果你的地图中有5个不同的瓦片,那么:
          1. 瓦片0的GID为1
          2. 瓦片1的GID为2
          3. 瓦片3 的GID为3
          4. 以此类推
          5. 瓦片的GID 为 0 被用来表示此瓦片为空。

            代码示例:创建瓦片地图


             


                //创建一个瓦片
                CCTMXTiledMap *tiledmap = CCTMXTiledMap::create("awakenjoys.tmx");
                tiledmap->setPosition(ccp(0, 0));       //设置地图位置
                tiledmap->setAnchorPoint(ccp(0, 0));    //设置地图锚点
                this->addChild(tiledmap, 2);            //将地图加入Layer
                
                //瓦片地图的大小由瓦片图素格数量和瓦片尺寸组成
                CCSize MapSize = tiledmap->getMapSize();    //获取瓦片地图大小
                CCLog("Map size is width: %f, height:%f", MapSize.width, MapSize.height);
                
                CCSize  TiledSize = tiledmap->getTileSize();    //获取瓦片尺寸
                CCLog("tiled size is width: %f, height:%f", TiledSize.width, TiledSize.height);
                
                //默认瓦片地图是无抗锯齿的,需要为每个瓦片设置抗锯齿
                CCArray *pChildArray = tiledmap->getChildren();
                CCSpriteBatchNode* child = NULL;
                CCObject* pObject = NULL;
                
                //遍历瓦片,并设置抗锯齿属性
                CCARRAY_FOREACH(pChildArray, pObject)
                {
                    child = (CCSpriteBatchNode*)pObject;
                    if (!child)
                    {
                        break;
                    }
                    child->getTexture()->setAntiAliasTexParameters();
                }
                
                //指定坐标获取Tile
                CCTMXLayer *MapLayer = tiledmap->layerNamed("tiledlayer1");
                CCSprite *Tile = MapLayer->tileAt(ccp(5, 11));
                //为获取到的tile创建动作,方便我们查看效果
                CCBlink *BlinkAction = CCBlink::create(10, 20);    //10秒内闪烁20次
                Tile->runAction(BlinkAction);
                
                CCSprite *newTile = MapLayer->tileAt(ccp(5, 13));   //获取新坐标的精灵
                //newTile->setAnchorPoint(ccp(0.5f, 0.5f));
                CCRotateBy *RotateAction = CCRotateBy::create(10, 7200.0f);
                newTile->runAction(RotateAction);
                
                //获取指定坐标的GID
                unsigned int map_gid = MapLayer->tileGIDAt(ccp(5, 11));
                CCLog("%d", map_gid);
                
                //为指定的坐标设置新的GID
                MapLayer->setTileGID(100, ccp((float)5, (float)13));
                CCLog("%d", MapLayer->tileGIDAt(ccp(5, 13)));
                
                //删除指定坐标的tile
                MapLayer->removeTileAt(ccp(5, 12));
             
             

            「cocos2d-x」瓦片地图学习(2)之地图滚动及触摸事件处理

             

            cocos2d支持2种触摸事件处理机制:CCStandardTouchDelegate和CCTargetedTouchDelegate,分别用来处时单点触摸和多点触摸事件的处理。

            CCLayer被设计用来接收用户输入,它是CCNode的子类,与CCNode类相比,只是添加了触摸及重力计等用户输入事件的处理功能,用户输入事件默认是关闭的,以下是分别开启多点及单点触摸事件处理的方法:

            • 在CCLayer中可以用setTouchEnabled(true)会开启多点触摸功能,多点触摸也是CCLayer的默认模式。
            • 使用CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true); 可以开启CCLayer的单点触摸功能。

            在触摸功能开启后需要重写触摸事件处理方法,多点触摸事件的方法为:

            virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
            virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
            virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
            virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);
            

            单点触摸事件处理方法为:


                //重写单点触屏处理事件
                virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
                virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); 
                virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 
                virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);     //返回true则触摸点不再传递,false的话继续传递
            
                //void registerWithTouchDispatcher(void);
            

            void registerWithTouchDispatcher(void);可以设置触摸事件的优先级,如果针对层的触摸事件接收不了,可能是被其他层截取了,可以用以下方法设置优先级:


             void HelloWorld::registerWithTouchDispatcher(void)
             
             {
             
             CCDirector* pDirector = CCDirector::sharedDirector();
             
             pDirector->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority + 1, true);
             
             }
            

            触摸事件获取到的坐标系是以左上角为原点的,而openGL是以左下角为原点的,所以需要把获取到的坐标转换为openGL坐标系:


                //获取点在视图中的坐标(左上角为原点)
                CCPoint touchLocation = pTouch->getLocationInView();
                // 把点的坐标转换成OpenGL坐标(左下角为原点)
                touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
                // 把OpenGL的坐标转换成CCLayer的坐标
                CCPoint local = convertToNodeSpace(touchLocation)
                // 大小为100x100,坐标为(0, 0)的矩形
            




            • 0
              点赞
            • 3
              收藏
              觉得还不错? 一键收藏
            • 0
              评论
            评论
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

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

            抵扣说明:

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

            余额充值