cocos2d-x学习日志(17) --新手向导

来源:互联网 发布:ubuntu开发软件 编辑:程序博客网 时间:2024/06/16 09:06
    新手引导:为了让第一次进入游戏的玩家能更加轻松容易的了解游戏功能。

    如图:





实现思路:


  1.采用遮罩的形式突出引导重点,同时屏蔽其它功能。

  2.在遮罩添加解说UI及相应动画


  如图:




  注:光亮区域即是可触碰区域。


具体实现:


1.CCClipingNode

  为了实现遮罩功能,我们选择一个模板切割图片的节点-- CCClipingNode.它的继承关系如下:





  • 首先它是一个节点,继承于CCNode,所以它可以像普通节点一样放入CCLayer,CCScene,CCNode中。
  • 作为节点,它就可以用作容器,承载其他节点和精灵。我把它叫底板。
  • 如果想要对一个节点进行裁剪,那需要给出裁剪的部分,这个裁剪区域,我把它叫模版。  

  所以CCClipingNode裁剪节点在组成上=底板+模版,而在显示上=底板+模版.


  如图:




2. CCClipingNode API:




注:

  getStencil:返回一个节点对象,这个对象就是之前提到的“裁减模板”。

  setStencil:设置“裁减模板”。

  getAlphaThreshold::这种裁减是可以改变裁减的透明度的,修改这个透明度就是通过设置这个阈值。

  setAlphaThreshold:获得这个透明度阈值。

  isInverted:之前说过的剪刀剪形状的例子,剪完形状以后,是显示被剪掉的部分,还是显示剩余的部分呢,默认isInverted值是false,是显示被剪掉的部分,设置为true则是显示剩余的部分。这个函数获得这个值。

  setInverted:设置isInverted值。


3.CCDrawNode

      为了绘制相应图形,使用CCDrawNode类,它的继承关系如下:





4. CCDrawNodeAPI:



      注释:

      drawDot:绘制点,参数给出坐标位置。

      drawSegment:绘制片断,给出起始点,结束点,半径等参数。

      drawPolygon:绘制矩形,可以分别给出填充颜色和边框颜色,还可以设置边框宽度。


实现代码:


1)绘制矩形区域:

RectangleLayer.h

#ifndef __RECTANGLELAYER_LAYER__#define __RECTANGLELAYER_LAYER__ #include "cocos2d.h"USING_NS_CC;class RectangleLayer:public cocos2d::CCLayer{public:static RectangleLayer* create(const char *pszFileName,CCPoint pos,CCRect rect, int pType);virtual bool initWithFile(const char *pszFilename,CCPoint pos,CCRect rect, int pType);virtual bool init();RectangleLayer(void);virtual ~RectangleLayer(void);virtual void registerWithTouchDispatcher();void refreshRect(CCPoint pos,CCRect rect, int pType);  bool ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ); CCString* getGuideMsgByType(int pType);  void setGuideVisible(bool isVisible);  CREATE_FUNC(RectangleLayer);private:CCSprite* mCircle;  CCSprite* pHand;CCDrawNode *mStencil;  CCRect m_obRect;  CCDictionary* m_pMsgDictionary; };#endif
RectangleLayer.cpp

#include "RectangleLayer.h"USING_NS_CC;RectangleLayer::RectangleLayer(){}RectangleLayer::~RectangleLayer(){}RectangleLayer* RectangleLayer::create(const char *pszFileName,CCPoint pos,CCRect rect, int pType)  {RectangleLayer *pobGuideLayer = new RectangleLayer();if (pobGuideLayer && pobGuideLayer->initWithFile(pszFileName,pos,rect,pType)){pobGuideLayer->autorelease();return pobGuideLayer;}CC_SAFE_DELETE(pobGuideLayer);return NULL;}bool RectangleLayer::init(){if (!CCLayer::init()){return false;}return true;}bool RectangleLayer::initWithFile(const char *pszFileName,CCPoint pos,CCRect rect, int pType){if (!CCLayer::init()){return false;}m_obRect = rect; setTouchEnabled(true);//创建cliper对象CCClippingNode* pClip = CCClippingNode::create();pClip->setInverted(true);addChild(pClip);mCircle=CCSprite::create(pszFileName);  mCircle->setPosition(pos); mCircle->setAnchorPoint(ccp(-0.5f,0.5f));mCircle->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f),  CCScaleTo::create(0.125f, 1))));  addChild(mCircle);  //加入灰色的底板CCLayerColor* pColor = CCLayerColor::create(ccc4(0,0,0,180));pClip->addChild(pColor);mStencil = CCDrawNode::create();static ccColor4F green = {0,1,0,1};float width = m_obRect.size.width;float height = m_obRect.size.height;float x = pos.x;float y = pos.y;static CCPoint rect1[4] = {ccp(0,height),ccp(width,height),ccp(width,0),ccp(0,0)};mStencil->drawPolygon(rect1,4,green,0,green);mStencil->setPosition(pos);pClip->setStencil(mStencil);mStencil->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f),  CCScaleTo::create(0.125f, 1))));return true;}void RectangleLayer::registerWithTouchDispatcher()  {  //使用-128和CCMenu优先级相同,并且吞掉事件true//  CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -130, true);  CCLayer::registerWithTouchDispatcher();  }  void RectangleLayer::refreshRect(CCPoint pos,CCRect rect, int pType)  {  float fRadius=mCircle->getContentSize().width;  float scale = rect.size.width/fRadius;  mCircle->setScale(scale);  mCircle->setPosition(pos);  mStencil->setPosition(pos);  mStencil->setScale(scale);   //设置触碰区域float x = pos.x;float y = pos.y;float width = mCircle->getContentSize().width *scale;float height = mCircle->getContentSize().height * scale;m_obRect = CCRectMake(x, y, width, height);}  bool RectangleLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent )  {  //得到触摸位置  CCPoint touchPoint = pTouch->getLocation();  //判断点是否在矩形CCRect m_obRect1 = m_obRect中  if (m_obRect.containsPoint(touchPoint))  {  //CCPoint pos = ccp(m_obRect.getMidX(),m_obRect.getMidY());CCPoint pos = pTouch->getLocation();//这里要转化为UI坐标系(左上角为0,0点)pos = CCDirector::sharedDirector()->convertToUI(pos);//设置触摸信息pTouch->setTouchInfo(pTouch->getID(),pos.x,pos.y);CCLog("helloWorld");//removeFromParent();   //触发后移除return false;  } return true;  }  //是否显示void RectangleLayer::setGuideVisible(bool isVisible)  {  this->setVisible(isVisible);  setTouchEnabled(isVisible);  }  //获取文字信息CCString* RectangleLayer::getGuideMsgByType(int pType)  {  char typeStr[10];  sprintf(typeStr, "%d", pType);  CCString* msg = (CCString*)m_pMsgDictionary->objectForKey(typeStr);  return msg;  }  
在HelloWorldScene.cpp 的init方法添加代码:

CCRect m_obRect=CCRectMake(  100,  160,  100,  100);  CCPoint dstPoint = mCircle->getPosition(); CCPoint newPoint = ccp(100,160);RectangleLayer *myGuideLayer = RectangleLayer::create("hand.png",newPoint,m_obRect,0);//myGuideLayer->refreshRect(newPoint1,m_obRect1, 0);addChild(myGuideLayer);
运行效果:




2)绘制圆形区域:

      因实现原理和以上类似,只需要更改下代码即可:

RoundnessLayer.cpp

#include "RoundnessLayer.h"USING_NS_CC;RoundnessLayer::RoundnessLayer(){}RoundnessLayer::~RoundnessLayer(){}RoundnessLayer* RoundnessLayer::create(const char *pszFileName,CCPoint pos,CCRect rect, int pType)  {RoundnessLayer *pobGuideLayer = new RoundnessLayer();if (pobGuideLayer && pobGuideLayer->initWithFile(pszFileName,pos,rect,pType)){pobGuideLayer->autorelease();return pobGuideLayer;}CC_SAFE_DELETE(pobGuideLayer);return NULL;}bool RoundnessLayer::init(){if (!CCLayer::init()){return false;}return true;}bool RoundnessLayer::initWithFile(const char *pszFileName,CCPoint pos,CCRect rect, int pType){if (!CCLayer::init()){return false;}m_obRect = rect; setTouchEnabled(true);CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();//创建裁减节点类CCClippingNode* pClip = CCClippingNode::create();pClip->setInverted(true);addChild(pClip);//遮罩层CCLayerColor* pColor = CCLayerColor::create(ccc4(0,0,0,180));pClip->addChild(pColor);mCircle=CCSprite::create(pszFileName);  float fRadius = rect.size.width/2;//圆的半径  mCircle->setPosition(pos);  mCircle->setAnchorPoint(ccp(-0.5f,0.5f));mCircle->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f),  CCScaleTo::create(0.125f, 1))));  addChild(mCircle);  //绘制圆形区域  static ccColor4F green = {1, 1, 1, 1};//顶点颜色,这里我们没有实质上没有绘制,所以看不出颜色  const int nCount=100;//圆形其实可以看做正多边形,我们这里用正100边型来模拟园  const float coef = 2.0f * (float)M_PI/nCount;//计算每两个相邻顶点与中心的夹角  static CCPoint circle[nCount];//顶点数组  for(unsigned int i = 0;i <nCount; i++) {  float rads = i*coef;//弧度  circle[i].x = fRadius * cosf(rads);//对应顶点的x  circle[i].y = fRadius * sinf(rads);//对应顶点的y  }  //绘制矩形,可以分别给出填充颜色和边框颜色,还可以设置边框宽度mStencil=CCDrawNode::create();  mStencil->drawPolygon(circle, nCount, green, 0, green);//绘制这个多边形!  //动起来  mStencil->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f),  CCScaleTo::create(0.125f, 1)))); float x = pos.x + rect.size.width/2;float y = pos.y + rect.size.width/2;mStencil->setPosition(ccp(x,y));  //设这模板  pClip->setStencil(mStencil);  //CCLayerColor* layer1 = CCLayerColor::create(ccc4(192, 0, 0, 25), rect.size.width, rect.size.height);//layer1->setPosition(pos);//addChild(layer1);return true;}void RoundnessLayer::registerWithTouchDispatcher()  {  //使用-128和CCMenu优先级相同,并且吞掉事件true//  CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -130, true);  CCLayer::registerWithTouchDispatcher();  }  void RoundnessLayer::refreshRect(CCPoint pos,CCRect rect, int pType)  {  //调整大小float fRadius=mCircle->getContentSize().width*0.5;  float scale = rect.size.width/fRadius;  //调整光亮区坐标float x = pos.x + rect.size.width/2;float y = pos.y + rect.size.width/2;mCircle->setScale(scale);  mCircle->setPosition(pos);  mStencil->setPosition(ccp(x, y));  mStencil->setScale(scale);  //设置触碰区域float rectX = pos.x;float rectY = pos.y;float width = mCircle->getContentSize().width *scale;float height = mCircle->getContentSize().height * scale;m_obRect = CCRectMake(rectX, rectY, width, height);}  bool RoundnessLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent )  {  //得到触摸位置  CCPoint touchPoint = pTouch->getLocation();  //判断点是否在矩形CCRect m_obRect1 = m_obRect中  if (m_obRect.containsPoint(touchPoint))  {  CCPoint pos = ccp(m_obRect.getMidX(),m_obRect.getMidY());//这里要转化为UI坐标系(左上角为0,0点)pos = CCDirector::sharedDirector()->convertToUI(pos);//设置触摸信息pTouch->setTouchInfo(pTouch->getID(),pos.x,pos.y);CCLog("helloWorld");return false;  } CCLog("no");return true;  }  void RoundnessLayer::setGuideVisible(bool isVisible)  {  this->setVisible(isVisible);  setTouchEnabled(isVisible);  }  CCString* RoundnessLayer::getGuideMsgByType(int pType)  {  char typeStr[10];  sprintf(typeStr, "%d", pType);  CCString* msg = (CCString*)m_pMsgDictionary->objectForKey(typeStr);  return msg;  }  
运行效果:




      有关解说UI及动画的话,就按自己的项目要求贴到遮罩层上,就OK了。

      若想让真机正常显示,稍微更改接口参数:

for iOS:  in AppController replace the gl-view creation with:

 EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]                                     pixelFormat: kEAGLColorFormatRGBA8                                     depthFormat: GL_DEPTH24_STENCIL8_OES                              preserveBackbuffer: NO                                      sharegroup: nil                                   multiSampling: NO                                 numberOfSamples: 0];

for Android:  in game activity:

 public Cocos2dxGLSurfaceView onCreateView() {        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);        glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);        return glSurfaceView;    }

引用博客:

      http://bbs.9ria.com/thread-182383-1-1.html

      http://blog.csdn.net/jackystudio/article/details/17160973

0 0