Cocos2d-x 2.x、3.x读书摘要(2016-6-25 07:18)

20170326添加:
尽量使用最新的类,因为被遗弃的类一般都有功能和性能上的缺陷,所以不建议使用。
对于EditBox类,在2.2.6版本之前,在iOS 8上,如果单击输入,键盘弹出时,会发生界面偏移错误,出现黑色背景部分。关闭键盘时,界面偏移不回来了。
引擎3.5/2.2.6解决了这个Bug。
2.2.6版本中修复了iPhone6和iPhone6 Plus的一些BUG,支持苹果的64位架构。
对于游戏中用到文字的部分,尽量使用Label类和ui命名空间下Text类型的类来实现,LabelTTF等2.x中的类都被遗弃了。


TableView控件即表格控件
// 创建一个TableView对象,并返回其指针
m_table = TableView::create(this, cocos2d::Size(SCREEN_WIDTH, 604));
// 设置表格委托,pDelegate参数表示指向委托对象的指针 
m_table->setDelegate(this);
// 设置滚动方向
m_table->setDirection(TableView::Direction::VERTICAL);
// 设置网格垂直填充顺序,TOP_DOWN代表从上到下排列,BOTTOM_UP代表从下到上排列
m_table->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
this->addChild(m_table, 0);
// 加载数据刷新表格绘制
m_table->reloadData();

表格控件涉及3个非常重要的辅助类:
TableViewCell类为表格行对象类
TableViewDataSource类为表格数据源类
TableViewDelegate类为表格的委托类

//用来响应表格触摸事件的方法,table参数为指向表格对象的指针,cell参数为指向行对象的指针
void LotteryKindScrollView::tableCellTouched(TableView* table, TableViewCell* cell)
{
 // getIdx得到此TableViewCell对象对应的行索引
        int tag = cell->getIdx();
 //if (tag < 0) return; 
 //
 //pCell = cell;
}
// 返回表格总行数,table参数为指向表格对象的指针
ssize_t LotteryKindScrollView::numberOfCellsInTableView(TableView *table)
{
 int result = m_Count / 4;
 int tempLast = m_Count % 4; //除4有余数,则加1
 if (tempLast != 0) result ++;
 return result;
}

// 返回给定表格的行对象尺寸,table参数为指向表格对象的指针
cocos2d::Size LotteryKindScrollView::cellSizeForTable(TableView *table)
{
 cocos2d::Size size = cocos2d::Size(SCREEN_WIDTH, 201); //高度定死
 return size;
}

// 返回表格每一行内容,table参数为指向表格对象的指针,idx参数为行对象的索引值
TableViewCell* LotteryKindScrollView::tableCellAtIndex(TableView *table, ssize_t idx)
{
 TableViewCell* cell = new TableViewCell();

 if(m_Data.size() < 1) return cell;

 for(int i = 0 ; i < 4 ; i ++)
 {  
  int data_index = idx * 4 + i + 1;
  if (data_index > m_Count) break;
  int kindId = m_Data.at(data_index - 1); 
  string nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();

  if(data_index > 18)
  {   
   nameStr = String::createWithFormat("%s%02d_2.png",m_name.c_str(),data_index)->getCString();
  } 

  if (m_Count < 9) //游戏为4个,这里用9作参考
  {
   nameStr = String::createWithFormat("%s%02d_2.png",m_name.c_str(),data_index)->getCString();
   if(data_index == 1)
   nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();
   if(data_index == 2)
   nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();
   if(data_index == 4)
   nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();
   if(data_index == 3)
    nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();
   if(data_index == 5)
    nameStr = String::createWithFormat("%s%02d.png",m_name.c_str(),data_index)->getCString();
  } 

  Sprite *kindSprite = Sprite::createWithSpriteFrame(spriteFrame(nameStr));
  kindSprite->setPosition(Vec2(SCREEN_WIDTH * (i * 2 + 1) / 8, 100));
  kindSprite->setTag(LOTTERY_KIND_SPRITE_TAG+kindId);
  cell->addChild(kindSprite);  
 }

 return cell;
}

//辅助类——编辑文本框的委托类EditBoxDelegate
class KongJianLayer : public Layer,public EditBoxDelegate

{
//开始编辑回调方法
virtual void editBoxEditingDidBegin(EditBox* editBox);
//结束编辑回调方法
virtual void editBoxEditingDidEnd(EditBox* editBox);
//内容变化回调方法
virtual void editBoxTextChanged(EditBox* editBox,const std::string& text);
//编辑返回回调方法
virtual void editBoxReturn(EditBox* editBox);
CREATE_FUNC(KongJianLayer);
EditBox* m_peditAccount;
EditBox* m_peditPW;

};
 static EditBox* create(EditBoxDelegate* pDelegate, CCRect rcEditBox, const char *file, const char *PlaceHolder, int MaxLength,
  const char* pFontName="微软雅黑", int fontSize=20,
  //5种回显模式
  EditBox::InputFlag inputFlag=EditBox::InputFlag::PASSWORD,//密码模式
  EditBox::InputFlag inputFlag=EditBox::InputFlag::SENSITIVE,//敏感数据模式
  EditBox::InputFlag inputFlag=EditBox::InputFlag::INITIAL_CAPS_WORD,//单词首字母大写模式
  EditBox::InputFlag inputFlag=EditBox::InputFlag::INITIAL_CAPS_SENTENCE,//句子首字母大写模式
  EditBox::InputFlag inputFlag=EditBox::InputFlag::INITIAL_CAPS_ALL_CHARACTERS,//所有字母大写模式
  //7种输入模式
  EditBox::InputMode inputMode=EditBox::InputMode::ANY,//任何类型
  EditBox::InputMode inputMode=EditBox::InputMode::EMAIL_ADDRESS,//email地址类型
  EditBox::InputMode inputMode=EditBox::InputMode::NUMERIC,//数字类型
  EditBox::InputMode inputMode=EditBox::InputMode::PHONE_NUMBER,//电话号码类型
  EditBox::InputMode inputMode=EditBox::InputMode::URL,//URL类型
  EditBox::InputMode inputMode=EditBox::InputMode::DECIMAL,//小数类型
  EditBox::InputMode inputMode=EditBox::InputMode::SINGLELINE,//单行输入类型
  EditBox::KeyboardReturnType returnType=EditBox::KeyboardReturnType::Default)
 {
  CCEditBox *pEditBox = CCEditBox::create(rcEditBox.size, CCScale9Sprite::create( file ));
  pEditBox->setPosition(CCPoint(rcEditBox.getMinX(), rcEditBox.getMinY()));
  //setFont设置编辑文本框显示文本所采用的字体样式和字体尺寸,pFontName参数为目标样式字体文件路径,fontSize表示字体尺寸值
  //setFontName设置字体样式;setFontSize设置字体尺寸
  pEditBox->setFont(pFontName, fontSize);
  pEditBox->setPlaceholderFont(pFontName, fontSize);
  //setFontColor设置编辑文本框显示文本颜色
  pEditBox->setFontColor(ccBLACK);
  //setPlaceHolder设置输入为空时编辑文本框的显示内容
  pEditBox->setPlaceHolder(PlaceHolder);
  //setPlaceholderFontColor设置输入为空时编辑文本框显示内容的颜色
  pEditBox->setPlaceholderFontColor(ccWHITE);
  //setMaxLength设置编辑文本框输入文本最大长度,MaxLength参数为输入文本的最大长度
  pEditBox->setMaxLength(MaxLength);
  //setReturnType设置此文本编辑控件的返回类型,returnType参数为要设置的返回类型
  pEditBox->setReturnType(returnType);
  //setInputFlag设置输入回显模式,inputFlag参数为要设置的回显模式
  pEditBox->setInputFlag(inputFlag);
  //setInputMode设置编辑文本框的输入模式,inputMode参数为要设置的输入模式
  pEditBox->setInputMode(inputMode);
  //setDelegate设置编辑文本框的委托,pDelegate表示指向委托对象的指针
  pEditBox->setDelegate(pDelegate);
  return pEditBox;
 }

chap22 GUI框架概述
Cocos2d-x引擎自带的基础UI控件Menu、MenuItem、Label、TextFieldTTF等,以及2.x本意欲一统GUI框架的CCControlXXX系列控件。它们都没能形成系统的UI框架,直到CocosStudio的出现,以CocosStudio为基础的

Widget系列UI控件才逐渐形成了系统的UI框架。

在旧版本引擎当中,不存在动画帧的类AnimationFrame。
精灵帧缓冲类的函数
addSpriteFramesWithFile通过plist文件来添加精灵帧
addSpriteFramesWithFile通过plist文件和纹理图片的名字来添加精灵帧
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pic_show.plist","pic_show.png");
SpriteFrameCache::getInstance()->removeSpriteFramesFromFile("pic_show.plist");
3.3 百分比动作特效
百分比动作的实现类
ProgressTo(从初始百分比为0%开始的动作)和ProgressFromTo这两个类都直接继承了ActionInterval类
duration参数表示动作持续的时间
percent参数表示目标百分比
reverse方法表示获取当前动作的逆动作,并返回其指针
fromPercentage表示初始百分比
toPercentage表示目标百分比
与普通动作不同,百分比动作不应该直接被精灵等可见物体执行,而是需要将希望执行这些动作的精灵包裹进ProgressTimer对象来执行。
//sp参数表示指向其他包裹的精灵对象的指针
Sprite* sp=Sprite::createWithSpriteFrame(spriteFrame((i==2||i==3||i==6||i==7)?texture_name::s_cd_bg_other_h:texture_name::s_cd_bg_other_v));
//创建ProgressTimer对象,返回其指针
m_pCountDown[i]=ProgressTimer::create(sp);
m_pCountDown[i]->setPosition(ccp(myConfig.m_CountDownPos[i][0],myConfig.m_CountDownPos[i][1]));
//设置工作模式,RADIAL代表半径模式,BAR代表水平/垂直模式
m_pCountDown[i]->setType(ProgressTimer::Type::RADIAL);
//设置动作是否逆序执行,true为逆序执行,false为非逆序执行 
m_pCountDown[i]->setReverseDirection(true);
m_pCountDown[i]->setVisible(true);
addChild(m_pCountDown[i],2);
CCLOG("m_pCountDown Pos%d=\"%f,%f\" ",i,m_pCountDown[i]->getPositionX(),m_pCountDown[i]->getPositionY());
if (iViewID == MY_VIEW_CHAIR_ID)
{
m_pCountDown[iViewID]->runAction(CCSequence::create(CCShow::create(),ProgressFromTo::create(45,95,5),CCHide::create(),CCCallFunc::create(this,callfunc_selector(DZPKLayer::selfTimeOut)),NULL));
}
else
{
m_pCountDown[iViewID]->runAction(CCSequence::create(CCShow::create(),ProgressFromTo::create(45,95,5),CCHide::create(),NULL));
}

OpenGL坐标系是指以屏幕左下角为原点的坐标系
屏幕坐标系是指以屏幕左上角为原点的坐标系
//getLocation获取触控点在OpenGL坐标系中的当前坐标
bool LotteryKindScrollView::onTouchBegan(Touch *pTouch, Event *pEvent)
{
    if(pTouch->getLocation().y > 150 + 604 || pTouch->getLocation().y < 150)
       return false; 
    start_pos = pTouch->getLocation();
    return true;
}
//getLocationInView获取触控点在屏幕坐标系中的当前坐标
void Player::ccTouchesBegan(CCSet* touches, CCEvent* event)
{
 if ( !m_MySelf )
  return;

 CCSetIterator iter = touches->begin();
 for(; iter != touches->end(); iter++)
 {
  CCTouch* pTouch = (CCTouch*)*iter;
  EmitGun(CCDirector::sharedDirector()->convertToGL( pTouch->getLocationInView() ));
 }
}

Vec2类一些常用的求距离与夹角的方法  
//getDistance获取自身与另一个Vec2对象所代表的二维向量坐标点之间的距离
Vec2 pos = pTouch->getLocation(); 
if(pos.getDistance(start_pos) > 10) return;


 

20170322问题:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
解决方法:
schedule_selector声明的回调函数要带一个float参数
20170305添加:
7.1.1按钮类ControlButton
示例:测试按钮——ControlButtonTest 
// 背景
CCScale9Sprite *pBackground;
// 确定
CCControlButton *pSubmit;
// 取消
CCControlButton *pCancel;
// 关闭
CCControlButton *pClose;
// 按钮的标题字
Label *titlebutton;
// 按钮的标题字
Scale9Sprite *pBackground=Scale9Sprite::create("button.png");
// 创建按钮对象
ControlButton *pSubmit=ControlButton::create(titlebutton,pBackground);
// 背景九宫格
 void backgroundWithSpriteFrameName(const char *pszSpriteFrameName);
 void backgroundWithFile(const char *file);
 
 // 按钮九宫格
 // 从帧名加载
 void buttonSubmitWithSpriteFrameName(const char *pszSpriteFrameName);
 void buttonCancelWithSpriteFrameName(const char *pszSpriteFrameName);
 void buttonCloseWithSpriteFrameName(const char *pszSpriteFrameName);
 // 从文件加载
 void buttonSubmitWithFile(const char *file,const char *text=0,const char *fontName="微软雅黑",int fontSize=12);
 void buttonCancelWithFile(const char *file,const char *text=0,const char *fontName="微软雅黑",int fontSize=12);
 void buttonCloseWithFile(const char *file,const char *text=0,const char *fontName="微软雅黑",int fontSize=12);
 // 从文件加载并均分,实现四态按钮
 void buttonSubmitWithFileCell(const char *file,int cell,bool Hor=true);
 void buttonCancelWithFileCell(const char *file,int cell,bool Hor=true);
 void buttonCloseWithFileCell(const char *file,int cell,bool Hor=true);

适配功能函数
// 获得设计分辨率大小
 winSize = CCDirector::sharedDirector()->getWinSize();
void DZPKLayer::dzpk_ToPortrait()
{
#if (CC_TARGET_PLATFORM ==CC_PLATFORM_WIN32)
 GLView* eglView = Director::getInstance()->getOpenGLView(); 
 eglView->setViewName("QiXing");
 eglView->setFrameSize(WINDOW_WIDTH,WINDOW_HEIGHT);
 eglView->setDesignResolutionSize(SCREEN_WIDTH, SCREEN_HEIGHT, kResolutionExactFit);
#endif
 //切换竖屏代码
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 GLView *pEGLView = Director::getInstance()->getOpenGLView();
        // 获得屏幕分辨率大小
 cocos2d::Size frameSize = pEGLView->getFrameSize();
 JniMethodInfo minfo;
 if( JniHelper::getStaticMethodInfo(minfo,"org.cocos2dx.cpp.AppActivity","changedActivityOrientation","(I)V") )
 {
  minfo.env->CallStaticVoidMethod(minfo.classID,minfo.methodID,2);
 }
 pEGLView->setFrameSize(frameSize.height,frameSize.width);
        // 设置设计分辨率和适配方式
 pEGLView->setDesignResolutionSize(SCREEN_WIDTH, SCREEN_HEIGHT,kResolutionExactFit);
#endif
}

void DZPKLayer::dzpk_ToLandscape()
{
#if (CC_TARGET_PLATFORM ==CC_PLATFORM_WIN32)
 MyConfig::Instance().LoadData("xml/MyConfig.xml");
 GLView* eglView = Director::getInstance()->getOpenGLView();
 eglView->setViewName("dzpk");
 eglView->setFrameSize(SCREEN_HEIGHT*0.8,SCREEN_WIDTH*0.8);
 eglView->setDesignResolutionSize(SCREEN_HEIGHT,SCREEN_WIDTH,kResolutionExactFit);
#endif
 //切换横屏代码
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 GLView *pEGLView = Director::getInstance()->getOpenGLView();
        // 获得屏幕分辨率大小
 cocos2d::Size frameSize = pEGLView->getFrameSize();
 JniMethodInfo minfo;
 if( JniHelper::getStaticMethodInfo(minfo,"org.cocos2dx.cpp.AppActivity","changedActivityOrientation","(I)V") )
 {
  minfo.env->CallStaticVoidMethod(minfo.classID,minfo.methodID,1);
 }
 pEGLView->setFrameSize(frameSize.height,frameSize.width);
        // 设置设计分辨率和适配方式
 pEGLView->setDesignResolutionSize(SCREEN_HEIGHT,SCREEN_WIDTH,kResolutionExactFit);
#endif
}

chap11数据结构和常用类
deprecated文件夹
CCDeprecated.h对这些废弃类重新做了类型定义
整数类型封装类、整型数的封装
__Integer/Integer/CCInteger
继承自Ref,Clonable
使用create创建对象,使用getValue获取值
例如:
NotificationCenter::sharedNotificationCenter()->postNotification(MSG_UI_ANS_GAMELINK,Integer::create(1));

typedef __Array Array;
typedef __Array CCArray;
__Array多继承自Ref,Clonable
removeObjectAtIndex函数删除元素
getRandomObject函数获得一个随机元素对象
containsObject函数判断是否包含某个对象
void DZPKLayer::updateActionName(Object* obj)
{
 __Array *arr=(__Array *)obj;
 // count函数获得数组中的元素个数
 if(arr->count()>=2)
 {
  // getObjectAtIndex函数根据索引获得某个元素对象
  int iViewID=((Integer *)arr->getObjectAtIndex(0))->getValue();
  const char* szName=((__String *)arr->getObjectAtIndex(1))->getCString();
  m_pPlayerInfoManager->updateActionName(iViewID,szName);
 }
}
string str=String::createWithFormat("胜利:手牌数=%d,公共牌数=%d,牌型=%d",bTempCount1,bTempCount2,ct)->getCString();
MyNSString::GBKToUTF8(str);

// 静态函数create创建一个数组对象  
__Array *arr=__Array::create();

// addObject添加元素 
arr->addObject(Integer::create(wWinnerID));
arr->addObject(String::create(str));
NotificationCenter::getInstance()->postNotification("updateActionName",arr);


字典CCDictionary\__Dictionary\Dictionary是一个键值对容器,键不可以重复,值可以重复
//创建
  CCDictionary *dictionary = CCDictionary::create();
//添加
  dictionary->setObject(CCInteger::create(dwUserID), "dwUserID");
  dictionary->setObject(CCInteger::create(wFaceID), "wFaceID");
  dictionary->setObject(CCInteger::create(cbGender), "cbGender");
  dictionary->setObject(CCInteger::create(cbMemberOrder), "cbMemberOrder");
  dictionary->setObject(CCInteger::create(lScore), "lScore");
  dictionary->setObject(CCInteger::create(lWinCount), "lWinCount");
  dictionary->setObject(CCInteger::create(lLostCount), "lLostCount");
  dictionary->setObject(CCInteger::create(lDrawCount), "lDrawCount");
  dictionary->setObject(CCInteger::create(lFleeCount), "lFleeCount");
  dictionary->setObject(CCInteger::create(lWinCount+lLostCount+lDrawCount+lFleeCount), "lTotalCount");
  dictionary->setObject(CCInteger::create(lExperience), "lExperience");
  dictionary->setObject(CCString::create(szNickName), "szNickName");
 
CCDictionary *dic = (CCDictionary *)friendData->objectAtIndex(i);
//根据键获得值 
DWORD userID = ((CCInteger *)dic->objectForKey("dwUserID"))->getValue();

3.5.6 SpriteBatchNode精灵表单类
如果能尽量减少OpenGL ES的调用,游戏的运行就会变得非常顺畅。
SpriteBatchNode的前身是旧版本中的SpriteSheet,也就是俗称的精灵表单。
使用SpriteBatchNode类时需要注意两个问题:
SpriteBatchNode类只能接受精灵对象成为其子节点。粒子、标签以及图层都不能成为SpriteBatchNode类的子节点。
所有的精灵对象必须使用同一张纹理图片,并且最好不要对这些精灵对象使用一些混合效果。
3.0版本之后推荐直接使用Sprite,不需要再将Sprite作为子节点添加到SpriteBatchNode中。

示例:测试SpriteFrameCacheTest精灵帧缓存类
SpriteFrameCacheTest
cocos2d-x-3.2/test/cpp-tests/Resources/animations
本例我们选择使用grossini-aliases.plist和grossini-aliases.png
cocos2d-x-3.2/test/cpp-tests/Resources/Images
grossini_dance_01.png到grossini_dance_14.png
如果开发者没有先使用addSpriteFramesWithFile函数添加精灵帧缓存,之后的操作都会提示找不到对应的.png文件。
//3.x
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("dzpk.plist","dzpk.png");
//2.x
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("dzpk.plist");
CCString *pBatchName=CCString::createWithFormat("dzpk.png");
cocos2d::CCSpriteBatchNode * s_dzpk= CCSpriteBatchNode::create(pBatchName->getCString());

3.6.1 cocos2d::Vector<T>
设计者们将cocos2d::Vector<T>设计为cocos2d::CCArray的替代品。存入容器的对象必须是cocos2d::Ref或其派生类。当容器被释放时,它所保存的所有元素都会被释放一次引用。
使用现代的C++,本地存储对象比堆存储对象要好。所以不要使用new操作来申请cocos2d::Vector<T>的堆对象,要使用栈对象。cocos2d::Vector<T>并不是cocos2d::Ref的子类,所以不要像使用其他Cocos2d类一样使用retain/release和引用计数内存管理。Vector<Vector<>>也是非法的。

4.8示例:测试函数回调动作——CallFuncActionTest 
函数回调动作包括如下几种:
CallFunc:不包含参数
CallFuncN:参数表示要调用动作的节点对象
__CCCallFuncND和__CCCallFuncO在3.0当中已经弃用了,使用CallFuncN代替。
由于从Cocos2d-x 3.0开始支持最新的C++ 11语法,因而,CallFuncActionTest的init函数中的回调方法可以使用更加简单的方式实现。
有关C++ 11新特性的知识请参考《C++ Prime中文版(第5版)》或官网文档。

3.0后新的回调接口,由四个CC_CALLBACK取代。
CC_CALLBACK的差别就在于后面的数字,0就代表回调是没有参数的函数,1就是有1个参数,2就是有2个参数,3就是有3个参数。
示例:测试菜单——MenuTest
③精灵菜单项的使用
//3.x
 Sprite *CloseNormal=Sprite::createWithSpriteFrame(spriteFrame("CloseNormal.png"));//正常状态
 Sprite *CloseSelected=Sprite::createWithSpriteFrame(spriteFrame("CloseSelected.png"));//选择状态
 [=]以传值的方式传入所有变量,值不可以被修改
//重置
MenuItemSprite *pCloseItemSprite1 = MenuItemSprite::create(pCloseNormalButton1,pCloseSelectButton1,[=](Ref* ){
 reset(NULL);
});
MenuItemSprite* CloseItem = MenuItemSprite::create(CloseNormal,CloseSelected,CC_CALLBACK_1(DZPKLayer::menuCloseCallback, this));
 CloseItem->setAnchorPoint(ccp(0.5,0.5));
 CloseItem->setTag(ExitTag);
 CloseItem->setPosition(ccp(m_WinSize.width*0.5,m_WinSize.height*0.35));
 Menu* menu = Menu::create(CloseItem,NULL);
 menu->setAnchorPoint(ccp(0,0));
 menu->setPosition(Point::ZERO);
 menu->setZOrder(-1801);
 //menu->setTouchPriority(-1801);
 addChild(menu,100);
void DZPKLayer::menuCloseCallback( Object* obj )
{
 int tag = dynamic_cast<CCNode*>(obj)->getTag();
 switch (tag)
 {
 case ExitTag:
  {
   CCLOG("exit================================");
   DZPKLayer::ExitDZPK();
  }
  break;
 default:
  break;
 }
}
//2.x
CCSprite *sendItemNormalImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendSend1.png"));
CCSprite *sendItemSelectedImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendSend2.png"));
CCSprite *deleteItemNormalImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendDelete1.png"));
CCSprite *deleteItemSelectedImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendDelete2.png"));
CCSprite *chatItemNormalImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendChat1.png"));
CCSprite *chatItemSelectedImage = CCSprite::createWithSpriteFrame(spriteFrame("Button_FriendChat2.png"));
CCMenuItemSprite *sendItem = CCMenuItemSprite::create(sendItemNormalImage,sendItemSelectedImage,this,menu_selector(BankerListLayer::sendButton));
CCMenuItemSprite *deleteItem = CCMenuItemSprite::create(deleteItemNormalImage,deleteItemSelectedImage,this,menu_selector(BankerListLayer::deleteButton));
CCMenuItemSprite *chatItem = CCMenuItemSprite::create(chatItemNormalImage,chatItemSelectedImage,this,menu_selector(BankerListLayer::chatButton));
myFriendOperaMenu = CCMenu::create(sendItem,deleteItem,chatItem,NULL); 
myFriendOperaMenu->setPosition(ccp(555, 42)); 
myFriendOperaMenu->alignItemsHorizontallyWithPadding(4);
this->addChild(myFriendOperaMenu,2);
void BankerListLayer::chatButton(cocos2d::CCObject *obj)

}

P109
Sprite * Start1 = Sprite::createWithSpriteFrame(spriteFrame(texture_name::s_start_button1));
Sprite * Start2 = Sprite::createWithSpriteFrame(spriteFrame(texture_name::s_start_button2));
MenuItemSprite *StartItem = MenuItemSprite::create(Start1,Start2,CC_CALLBACK_1(DZPKLayer::menuResumeCallback, this));
StartItem->setTag(StartTag);
// 菜单中关闭按钮
auto *LeaveItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(DZPKLayer::menuCloseCallback, this));
LeaveItem->setTag(CloseTag);
// 菜单
auto m_StartClose= Menu::create(StartItem,LeaveItem,NULL);
m_StartClose->setPosition(ccp(0,0));//Vec2::ZERO 
addChild(m_StartClose,0);
  
// 使用png图片创建一个精灵
auto exit_1 = Sprite::create("CloseNormal.png");

附录 Cocos2d-x中常用的宏
Cocos2d-x中提供了很多宏来完成一些特定的功能,它们在很大程度上方便了开发者。
1、与节点创建相关的宏
2、与平台相关的宏
3、与命名空间相关的宏
4、与节点属性相关的宏
5、与内存管理相关的宏
使用delete操作符删除一个C++对象p,如果p为NULL,则不进行操作
CC_SAFE_DELETE(tabLayer);
6、与日志相关的宏
7、与调试相关的宏
8、与转换相关的宏

命名空间宏
宏|作用|同等作用的C++语句
USING_NS_CC|定义cocos2d命名空间
USING_NS_CC_EXT|定义cocos2d::extension命名空间

2.3.2断言宏CCAssert的使用
cond是断言表达式,msg是错误提示信息。
if (NULL == s_AllBullet)
  CCAssert(0, "请先调用 CBulletManage::Init(...) 函数!");
2.3.3数组遍历宏CCARRAY_FOREACH、CCARRAY_FOREACH_REVERSE
声明在CCArray.h中
__array__为需要遍历的数组,__object__为Object对象
 CCSprite *pChild = NULL;
 CCObject* pObj = NULL;
 CCARRAY_FOREACH(getChildren(), pObj)
 {
  //在程序里要对该Object进行强制类型转换
                pChild = (CCSprite*)pObj;
  pChild->setVisible( true );
 }
2.3.5对象创建方法宏CREATE_FUNC的使用
CREATE_FUNC自动生成一个默认的静态create方法。
CREATE_FUNC(CLogin);

即生成一个方法:static CLogin* create();

4.5使用编辑框制作用户登录界面
Cocos2d-x使用EditBox添加编辑框,EditBox继承自ControlButton。
(1)创建一个编辑框对象m_peditAccount,用来输入姓名
cocos2d::extension::CCEditBox * m_peditAccount;
cocos2d::extension::CCEditBox * m_peditPW;
(10)给输入框添加事件代理,事件代理函数在EditBoxDelegate中定义,所以自己定义的类要继承EditBoxDelegate。其中包括4个处理函数。

class CLogin : public cocos2d::CCLayer, cocos2d::extension::CCEditBoxDelegate

editBoxReturn:当按键盘的完成键时触发
virtual void editBoxReturn(cocos2d::extension::CCEditBox* editBox);

附录A 实例代码清单说明
代码清单|实例说明
2-2|Cocos2d-x基本数据类型的使用方式,比如String、Array、Point、Size、Rect、Dictionary、Bool
2-3|Cocos2d-x常用宏定义的使用方法,比如随机数宏,角度转换宏,两值交换宏,数组遍历宏,字典遍历宏,属性定义宏
2-4|锚点的使用方式,节点坐标和世界坐标的相互转换
3-1-2|从场景中移除Node节点
3-2-2|使用Camera缩放、旋转节点
3-4-2|使用Scene创建一个战斗场景

3-4-3|多个场景相互切换的方式
3-5-2|Layer、layerColor的使用方式
4-1|1、使用LabelBMFont显示文本,获取单个字并设置样式;2、使用LabelTTF显示文本并对文本设置样式;3、使用LabelAtlas在场景中显示自定义字体。
4-2|介绍6种菜单项的区别和使用方式,在游戏中添加菜单并设置单击菜单后的回调函数
4-2-2|使用菜单制作游戏菜单功能
4-3-1|在游戏中使用ScrollView显示多页内容,监听ScrollView的滚动和缩放事件
4-3-3|通过制作一个简单背包讲解如何使用TableView,设置TableView大小、方向、渲染顺序、数据源。自定义单元格TableViewCell
4-3-4|当TableView里添加菜单时,如何区分处理是点击菜单还是滑动TableView
4-5|通过制作一个用户登录界面讲解编辑框的使用方式,包括设置编辑框的显示形式、输入内容,注册4种事件的代理函数
5-2|瞬时动作举例
5-3|延时动作举例,如移动、跳跃、旋转、缩放、倾斜变形、曲线运动等。把简单动作联合起来,实现按顺序播放动作、同时播放动作、逆向播放动作、重复播放动作等
6-2|介绍Cocos2d-x对背景音乐和音效的处理方法,主要内容包括播放、停止、暂停、恢复等操作
8-2|通过三个例子讲解Cocos2d-x中的屏幕触摸事件
8-3|使用多点触摸实现缩放图片

8-4-1|把键盘输入事件显示在屏幕中,讲解了如何使用Cocos2d-x的键盘事件
9-1|使用UserDefault存储修改数据

20170219添加:
http://www.docin.com/p-1489599279.html
Cocos2d-x学习之路(个人总结)
一、精灵篇
1、创建精灵的三种方法
1.1使用指定图片创建一个Sprite:
auto sprite=Sprite::create("2.png");
1.2使用矩形创建一个Sprite:
auto sprite=Sprite::create("2.png",Rect(0,0,40,40));
1.3使用精灵表单(Sprite Sheet)创建一个Sprite:
加载一个精灵表单
auto framecache=SpriteFrameCache::getInstance();
framecache->addSpriteFramesWithFile("sprite.plist");
auto sprite=Sprite::createWithSpriteFrameName("2.png");
this->addChild(sprite);
2、锚点和位置(颜色和透明度不受锚点影响)
2.1锚点
sprite->setAnchorPoint(Vec2(0.5,0.5));
2.2受锚点影响的精灵属性
位置
缩放
倾斜
角度:角度增加,顺时针旋转;角度减少,逆时针旋转
2.3不受锚点影响的精灵属性
颜色:Color3B对象代表RGB颜色值,即0~255之间的值,预定义颜色,如Color3B::White,Color3B:Red
透明度:取值范围(0~255),默认值为255(不透明)
二、动作篇
1、动作概念
随时间改变Node的属性
By和To的区别:
By相对于节点是相对的
To相对于节点是绝对的
2、基本动作及其如何执行动作
移动
旋转
缩放
淡入淡出
色调
跳跃
减速
贝塞尔曲线
3、序列动作及其如何执行动作
Sequence:序列对象可以是:动作对象、函数(CallFunc对象)、甚至另一序列
4、三种回调函数
1、callback()
2、callback(Node* sender)
3、callback(Node* sender,long date)
注意:两个对象同时调用一个动作的时候会失败,此时另外一个对象应该调用动作的clone();使用回调函数的时候,传入回调方法的时候记得没用括号,每个回调函数必须传入一个this参数。
三、计时器篇
1、原理介绍:
为游戏提供定时事件和定时调用服务
所有Node对象都知道如何调度和取消调度事件
2、三种计时器
2.1默认调度器:scheduleUpdate()
例如:下面这句的作用是通过默认调度器在主线程里执行网络回调NetEngine::NetManager::getInstance().OnUpdate(dt);
bool uiRoot::OnCreate(long nGuiW, long nGuiH)
{
scheduleUpdate();
return TRUE;
}
取消方法:
unscheduleUpdate()停止调度器
2.2单次调度器:scheduleOnce(SEL_SCHEDULE selector,float delay)
取消方法:
unschedule(SEL_SCHEDULE selector,float delay)
2.3自定义调度器:schedule(SEL_SCHEDULE selector,float interval,unsigned int repeat,float delay)
取消方法:
unschedule(SEL_SCHEDULE selector,float delay)

 

20161217添加:
Xcode8.2+Cocos2d-x 3.10精灵创建不了的bug:


 

// add "HelloWorld" splash screen"

    auto sprite =Sprite::create("HelloWorld.png");
  {

gl.supports_vertex_array_object: true

cocos2d.x.version: cocos2d-x-3.10

gl.vendor: Apple Inc.

gl.supports_PVRTC: true

gl.renderer: Apple Software Renderer

cocos2d.x.compiled_with_profiler: false

gl.max_texture_size: 4096

gl.supports_ETC1: false

gl.supports_BGRA8888: false

cocos2d.x.build_type: DEBUG

gl.supports_discard_framebuffer: true

gl.supports_NPOT: true

gl.supports_ATITC: false

gl.max_samples_allowed: 4

gl.max_texture_units: 8

cocos2d.x.compiled_with_gl_state_cache: true

gl.supports_S3TC: false

gl.version: OpenGL ES 2.0 APPLE-13.0.7

}

 

 

libpng error: CgBI: unhandled critical chunk

libpng error: CgBI: unhandled critical chunk

libpng error: CgBI: unhandled critical chunk

(lldb) 

解决方法:

加载图片资源出现libpng error: CgBI: unhandled critical chunk 

设置Remove Text Metadata From PNG Files = NO.就可以正常显示了 


20170104问题:DELL 14英寸笔记本+Win8.1+OS X虚拟机+Xcode7.0.1+Cocos2d-x 3.10下iPhone 6s Plus的模拟器太大了,在显示器上看不全
解决方法:command+1,2,3,4,5调大小,虚拟机下command+4比较合适


20161008添加:
2.x——>3.x
1、 CCControlEvent改为cocos2d::extension::Control::EventType、CCControlEventTouchUpInside改为Control::EventType::TOUCH_UP_INSIDE、CCControlEventTouchDown改为Control::EventType::TOUCH_DOWN
2、 CCPointZero改为Vec2::ZERO或Point::ZERO
3、去掉CC:
CCControlButton、CCScale9Sprite
4、CCArray改为Vector<SpriteFrame*>,addObject改为pushBack
5、ccBLACK改为Color3B::BLACK
6、CCControlStateNormal改为Control::State::NORMAL
7、kCCRepeatForever改为kRepeatForever
8、menu_selector改为 CC_CALLBACK_1、callfunc_selector改为CC_CALLBACK_0
9、kCCAttributeNamePosition改为GLProgram::ATTRIBUTE_NAME_POSITION
10、去掉CCTargetedTouchDelegate
11、注释掉visit、keyBackClicked、registerWithTouchDispatcher、ccTouchBegan改为onTouchBegan
12、CCCallFunc::create(this,callfunc_selector(DZPKLayer::selfTimeOut))改为使用lambda表达式或者其他函数对象。这里,DZPKLayer::selfTimeOut的函数体没有使用DZPKLayer的成员变量和其它成员函数。注:lambda表达式内部也可以使用DZPKLayer的其他成员。
13、#include "AssetsManager/AssetsManager.h"改为#include "assets-manager/AssetsManager.h"、AssetsManager::kNoNewVersion改为AssetsManager::ErrorCode::NO_NEW_VERSION、AssetsManager::kNetwork改为AssetsManager::ErrorCode::NETWORK。
14、CCScrollViewDirection改为cocos2d::extension::ScrollView::Direction、kCCScrollViewDirectionVertical改为ScrollView::Direction::VERTICAL。

火烈鸟网络科技编著的2.x开发教程、Cocos2d-x游戏开发技术精解这两本书,都是基于2.0.4版本讲解且于2013年6月份出版的。
Cocos2d-x高级开发教程——制作自己的《捕鱼达人》(王哲作序推荐)读书摘要(20130715、20150529、20151123、20160107、20160128、20160603)
2013年6月第1版
锚点指定了贴图上和所在节点原点(也就是设置位置的点)重合的点的位置。因此只有在CCNode类节点使用贴图的情况下,锚点才有意义。
2.3 C++中的Cocos2d-x内存管理
基于Cocos2d-iPhone的Objective-C风格的内存管理是Cocos2d-x的一个特色。把Objective-C的内存管理方式引入C++,使得游戏开发的内存管理下降了一个层次。
2.3.1复杂的内存管理
Boost库引入的智能指针从对象所有权传递的角度来解决内存管理问题。
2.3.2现有的智能内存管理技术
目前,主要有两种实现智能管理内存的技术,一是引用计数,一是垃圾回收。
引用计数是资源自我管理的一种机制,资源本身以引用计数为零来得知别人不再需要自己,从而把自己kill掉。
引用计数:它是一种很有效的机制,通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数。当对象增加一次引用时,计数器加1;当对象失去一次引用时,计数器减1;当引用计数为0时,标志着该对象的生命周期结束,自动触发对象的回收释放。引用计数解决了对象的生命周期管理问题,但堆碎片化和管理繁琐的问题依然存在。
垃圾回收:回收机制包括分代复制垃圾回收、标记垃圾回收和增量垃圾回收。
chap3游戏的基本元素
3.1CCDirector:大总管
在CCDirector中,我们定义了以下管理场景的方法:
启动游戏,并运行指定场景。 这个方法在主程序启动时第一次启动主场景时调用。      
三种切换场景的方法
暂停当前运行场景中的所有计时器和动作,场景仍然会显示在屏幕上。
恢复当前运行场景中被暂停的计时器和动作。
结束场景,同时退出应用。
3.2场景
场景只是层的容器,另一个作用是流程控制。
3.3层
层也扮演了容器的角色。
ZOrder值越大显示顺序越靠上。ZOrder的默认值是0。
捕鱼游戏场景大致由背景层、动作层、触摸层和菜单层组成。
层可以接受用户输入时间,包括触摸、加速度计和键盘输入等。

3.5.2节点的组织
前面我们已经接触了组织节点的基本方式:addChild方法。在介绍addChild方法时,我们是以向场景中添加层作为例子讲解的。而事实上,addChild是CCNode提供的方法,我们可以把任何的CCNode添加到另一个节点之中。
除了添加节点之外,CCNode还提供了一系列管理节点的方法,表3-3列出了这些方法。
表3-3 组织节点相关的方法
addChild|把child添加到当前节点之中
removeFromParentAndCleanup|把当前节点从其父节点中移除,如果cleanup为true,则执行clean方法
node->removeFromParentAndCleanup(true);
removeChild|从当前节点中移除child节点,如果cleanup为true,则调用child的clean方法
removeChild(node,true);
removeChildByTag|从当前节点中移除标号为tag的节点
removeChildByTag(tag_card_index);
removeAllChildrenWithCleanup|移除当前节点的所有子节点
this->removeAllChildrenWithCleanup(true);
getChildByTag|返回当前节点中标号为tag的节点
cleanup|停止此节点的全部动作与计时器

例子:RoomChip也是一个层,是主场景层的子节点
#include "RoomChip.h"
CCScene *scene=CCDirector::sharedDirector()->getRunningScene();
if (!scene->getChildByTag(10))
{   
return;
}
RoomChip *m_roomChip = dynamic_cast<RoomChip*>(scene->getChildByTag(10)->getChildByTag(3));

3.1.1CCNode类的成员数据
CCNode类的主要保护成员数据(子类可见,Protected关键字)如表3-2所示。
3.12CCNode类的函数
CCNode类的主要函数如表3-3所示。
函数名,返回类型,描述
getScale,浮点型,获得缩放系数
setScale,空,设置缩放系数
m_pCKPX_BTN->setOpacity(0);//255表示完全不透明,0表示完全透明

m_pCKPX_PIC = Sprite::createWithSpriteFrame(spriteFrame(texture_name::s_ol_bg_ckpx));
m_pCKPX_PIC->getTexture()->setAliasTexParameters();//图片放大时,不模糊但有锯齿
m_pCKPX_PIC->setScale(0);//整体缩放,s为比例,s=1表示原尺寸
m_pCKPX_PIC->setAnchorPoint(ccp(0,0));//(0,0)点代表左下点,(1,1)代表右上点
m_pCKPX_PIC->setPosition(ccp(myConfig.m_DZPKOperaLayerPos[1][0],myConfig.m_DZPKOperaLayerPos[1][1]));//xPos和yPos为相对于父节点锚点的位置
addChild(m_pCKPX_PIC);

3.1.3坐标系简介
通过前面的学习,大家会对CCNode类的属性和方法有所了解,但是可能有些名词会令你困惑,如OpenGL坐标系,世界坐标系,节点相对坐标系,仿射变换等。本节就来解决这些问题。
1.OpenGL坐标系
Cocos2D-x以OpenGL和OpenGL ES为基础,所以自然支持OpenGL坐标系。该坐标系原点在屏幕左下角,x轴向右,y轴向上。
屏幕坐标系使用的是不同的坐标系统,原点在屏幕左上角,x轴向下。iOS的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系。因此在Cocos2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值