参考文章地址:
迷雾效果实现原理:http://bbs.9ria.com/thread-157487-1-1.html
C++代码:FogLayer.h
#ifndef _FOG_LAYER_H_ #define _FOG_LAYER_H_ #include "cocos2d.h" USING_NS_CC; //迷雾层 class FogLayer :public CCNode{ public: //迷雾块图素信息封装类 class FogBlock:public CCObject{ CC_SYNTHESIZE(int,leftTop,LeftTop); CC_SYNTHESIZE(int,rightTop,RightTop); CC_SYNTHESIZE(int,leftButtom,LeftButtom); CC_SYNTHESIZE(int,rightButtom,RightButtom); int getTotal(){ return leftTop + rightTop + leftButtom + rightButtom; } }; private: //TileGID与图素关系数组(total - gid) CCArray* tileGids; //瓦片地图 CCTMXTiledMap* fogMap; //把cocos2d-x坐标转换为地图坐标 CCPoint convertGLToMap(CCPoint point); //根据地图坐标更新图素 void updateTiles(CCPoint mapPoint); //瓦片集合的图素信息(瓦片坐标点 - 瓦片图素信息) CCDictionary* fogBlocks; //根据地图坐标点获取迷雾块 FogBlock* getFogBlock(CCPoint mapPoint); //根据图素信息之和获取TileGID int getTileGID(int total); public: //创建一个迷雾层 CREATE_FUNC(FogLayer); //初始化 virtual bool init(); //触摸迷雾层 bool onTouch(CCPoint point); //释放资源 virtual void onExit(); }; #endif
C++代码:FogLayer.cpp
#include "FogLayer.h" bool FogLayer::init(){ do { fogBlocks = CCDictionary::create(); fogBlocks->retain(); tileGids = CCArray::createWithCapacity(16); tileGids->retain(); //建立图素与TileGID之间的关系 (total - gid) tileGids->addObject(CCInteger::create(1)); //0 -- 1 tileGids->addObject(CCInteger::create(5)); //1 -- 5 tileGids->addObject(CCInteger::create(9)); //2 -- 9 tileGids->addObject(CCInteger::create(13)); //3 -- 13 tileGids->addObject(CCInteger::create(2)); //4 -- 2 tileGids->addObject(CCInteger::create(6)); //5 -- 6 tileGids->addObject(CCInteger::create(10)); //6 -- 10 tileGids->addObject(CCInteger::create(14)); //7 -- 11 tileGids->addObject(CCInteger::create(3)); //8 -- 3 tileGids->addObject(CCInteger::create(7)); //9 -- 7 tileGids->addObject(CCInteger::create(11)); //10 -- 11 tileGids->addObject(CCInteger::create(15)); //11 -- 15 tileGids->addObject(CCInteger::create(4)); //12 -- 4 tileGids->addObject(CCInteger::create(8)); //13 -- 8 tileGids->addObject(CCInteger::create(12)); //14 -- 12 tileGids->addObject(CCInteger::create(16)); //15 -- 16 fogMap = CCTMXTiledMap::create("fog.tmx"); CC_BREAK_IF(!fogMap); //设置锚点为左上角 fogMap->setAnchorPoint(CCPoint(0,1)); //设置位置为左上角(UI坐标的原点) fogMap->setPosition(ccp(0,CCDirector::sharedDirector()->getVisibleSize().height)); this->addChild(fogMap); return true; } while (0); return false; } //把cocos2d-x坐标转换为地图坐标 CCPoint FogLayer::convertGLToMap(CCPoint point){ point = CCDirector::sharedDirector()->convertToUI(point); //float mapWidth = fogMap->getMapSize().width * fogMap->getTileSize().width; //float mapHeight = fogMap->getMapSize().height * fogMap->getTileSize().height; //CCLOG("mapWidth=%f mapHeight=%f",mapWidth,mapHeight); //x = 触摸点的宽度/瓦片宽度 int x = point.x/fogMap->getTileSize().width; //y = 触摸点的高度/瓦片高度 int y = point.y/fogMap->getTileSize().height; return ccp(x,y); } //根据图素信息之和获取TileGID int FogLayer::getTileGID(int total){ if (total >= 16) { return 0; } else{ return ((CCInteger*)tileGids->objectAtIndex(total))->getValue(); } } //触摸迷雾层 bool FogLayer::onTouch(CCPoint point){ //把cocos2d-x坐标转换为地图坐标 CCPoint mapPoint = convertGLToMap(point); CCLOG("map x=%f y=%f",mapPoint.x,mapPoint.y); //根据地图坐标更新图素 updateTiles(mapPoint); return false; } //根据地图坐标更新图素 void FogLayer::updateTiles(CCPoint mapPoint){ CCSize mapSize = fogMap->getMapSize(); CCTMXLayer* fogLayer = fogMap->layerNamed("fogLayer"); //边界判断 if (mapPoint.x > mapSize.width || mapPoint.x < 0 || mapPoint.y > mapSize.height || mapPoint.y <0) { CCLOG("mapPoint out of range x=%f y=%f",mapPoint.x,mapPoint.y); return; } //根据坐标点获取对应的迷雾块,并更新图素信息 FogBlock* fogBlock4 = getFogBlock(mapPoint); FogBlock* fogBlock8 = getFogBlock(ccp(mapPoint.x+1,mapPoint.y)); FogBlock* fogBlock1 = getFogBlock(ccp(mapPoint.x,mapPoint.y+1)); FogBlock* fogBlock2 = getFogBlock(ccp(mapPoint.x+1,mapPoint.y+1)); //旧的total int total4 = fogBlock4->getTotal(); int total8 = fogBlock8->getTotal(); int total1 = fogBlock1->getTotal(); int total2 = fogBlock2->getTotal(); //CCLOG("old total4=%d total8=%d total1=%d tota2=%d",total4,total8,total1,total2); fogBlock4->setRightButtom(4); fogBlock8->setLeftButtom(8); fogBlock1->setRightTop(1); fogBlock2->setLeftTop(2); //CCLOG("new total4=%d total8=%d total1=%d tota2=%d",fogBlock4->getTotal(),fogBlock8->getTotal(),fogBlock1->getTotal(),fogBlock2->getTotal()); //更新图素 if (total4 != fogBlock4->getTotal()) { fogLayer->setTileGID(getTileGID(fogBlock4->getTotal()),mapPoint); } if (total8 != fogBlock8->getTotal()) { fogLayer->setTileGID(getTileGID(fogBlock8->getTotal()),ccp(mapPoint.x+1,mapPoint.y)); } if (total1 != fogBlock1->getTotal()) { fogLayer->setTileGID(getTileGID(fogBlock1->getTotal()),ccp(mapPoint.x,mapPoint.y+1)); } if (total2 != fogBlock2->getTotal()) { fogLayer->setTileGID(getTileGID(fogBlock2->getTotal()),ccp(mapPoint.x+1,mapPoint.y+1)); } } //根据地图坐标点获取迷雾块 FogLayer::FogBlock* FogLayer::getFogBlock(CCPoint mapPoint){ const char* key = CCString::createWithFormat("%f%f",mapPoint.x,mapPoint.y)->getCString(); CCObject* fogBlock = fogBlocks->objectForKey(key); //如果没找到图素信息类 if (fogBlock) { return (FogBlock*)fogBlock; }else{ //创建一个新的图素信息类,并放到集合中 FogBlock* fog = new FogBlock; fog->autorelease(); //初始化 fog->setLeftTop(0); fog->setLeftButtom(0); fog->setRightTop(0); fog->setRightButtom(0); //添加到集合 fogBlocks->setObject(fog,key); return fog; } } //释放资源 void FogLayer::onExit(){ if (fogBlocks) { fogBlocks->release(); } if (tileGids && tileGids->count()>0) { tileGids->release(); } }
C++代码:HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" class HelloWorld : public cocos2d::CCLayer { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); /* 注册触摸监听 */ virtual void onEnter(); /* 注销触摸监听 */ virtual void onExit(); /* 手指按下 */ virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent); }; #endif // __HELLOWORLD_SCENE_H__
C++代码:HelloWorldScene.cpp
#include "HelloWorldScene.h" #include "FogLayer.h" USING_NS_CC; CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); ///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , origin.y + pCloseItem->getContentSize().height/2)); // create menu, it's an autorelease object CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24); // position the label on the center of the screen pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height)); // add the label as a child to this layer this->addChild(pLabel, 1); // add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("map.png"); // position the sprite on the center of the screen pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); // add the sprite as a child to this layer this->addChild(pSprite, 0); //添加迷雾层 this->addChild(FogLayer::create(),3,3); return true; } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif } /* 注册触摸监听 */ void HelloWorld::onEnter(){ CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,1,true); } /* 注销触摸监听 */ void HelloWorld::onExit(){ CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } /* 手指按下 */ bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ CCPoint uiPoint = CCDirector::sharedDirector()->convertToUI(pTouch->getLocation()); //调用迷雾层的的onTouch方法 FogLayer* fogLayer = (FogLayer*)this->getChildByTag(3); fogLayer->onTouch(pTouch->getLocation()); return true; }