一、节点类(Node)
任何要显示在屏幕上的的对象都是结点类,最常见的有场景(Scene),层(Layer),菜单(Menu)精灵(Sprite),菜单类是层的一个子类,层的初始化默认锚点是(0,0),精灵的默认锚点是(0.5,0.5)。一个层或一个精灵在它父类上的位置setposition()函数,其实指的是锚点的位置。并且node的旋转,缩放,平移各种action都是基于锚点来进行的。
二、导演类(Director)
Director类是cocos2D-x游戏引擎的核心,它用来创建并控制主屏幕的显示,游戏的开始,结束,暂停,都要调用Director类的方法,调用Director中方法的标准方式Director::getinstance()->函数名
导演类这几个方法比较重要
Scene* getRunningScene();获取现在正在运行的场景,注:导演类同一时间只能动行一个场景 void runWithScene(Scene *scene);通过传入参数场景进入导演主循环中
void replaceScene(Scene *scene);切换场景
void end();结束游戏
三、场景类
Scene有一个子类CCTransitionScene切换场景类,这个类有很多子类,也就是很多种切换场景的方法,之所有有这些类是因为当运行Director::getinstance()->repleaceScene()方法时(切换场景时),会存在一个内存"峰值",新场景还没有释放,旧场景已经进来了,这俩所占内存的总和就是这个“峰值”,这个时候手机就会出现卡的情况,而切换场景类就相当于一个读进度条的作用。
切换场景有很多类,也就是很多种形式,以下是一个翻页的例子
Scene *sce = HellowScene::create();
Director::getinstance()->replaceScene(CCTransitionPageTurn::create(1.0,sce,false));
四、布景层类(Layer)
布景层类不仅继承Node类,同时还继承CCTouchDelegate,CCAcceleromelerDelegate,和CCKeypadDelegate,所以它还负责输入,触摸,以及加速传感器功能。
CCLayerColor类,一般可以做为蒙板来用,它可以设置rbga值,3.0版本以前可以通过设置它的触摸级比按钮的触摸级高来防止蒙板穿透问题,但是3.0之后就不行了。我们可以
Layer *cover = LayerColor::create(ccc4(130,130,130,200));
cover->setContentSize(CCSizeMake(800,480));
cover->setPosition(0,0);
this->addChild(cover);
auto callback = [](Touch * ,Event *)
{
return true;
};
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = callback;
listener->setSwallowTouches(true);//不往下传播
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,cover);
这样可以防止穿透问题的发生。只是添加了一个事件监听器,设置这个事件监听器吞噬触摸,在onTouchBegan回调函数返回了true.
CCScrollView在cocos的扩展库里面,用的时候要引用#include "cocos-ext.h"头文件,以及加入USING_NS_CC_EXT;命名空间。如果要使用cocosstudio导出的JSON、或者使用Extension扩展库,libCocosStudio,libExtension,libGUI都要手动添加。下面以libExtension库的添加为例
第一步,在"解决方案"中右击,选择"添加"->"现有项目",在弹出的对话框中找到“cocos2d\extensions\proj.win32\libExtensions.vcxproj”,点击确认。
第二步,对你的项目右键,选择“引用...”。在弹出的属性页中点选下面的“添加新引用”。在弹出的子级对话框中勾选我们刚才刚加入的三个lib项目,点击确定,这样就完成添加项目对库的引用。
第三步,为你的项目添加包含目录。
$(EngineRoot)
$(EngineRoot)cocos
$(EngineRoot)cocos\editor-support
项目->属性->c/c++常规->附加包含路径
一个简单的Scroll类调用的小例子:
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
CCNode *pContainer = Layer::create();
pContainer->setContentSize(CCSizeMake(800,960));
CCSprite *spr = Sprite::create("Guide_Light_New.png");
spr->setPosition(400,240);
pContainer->addChild(spr);
ScrollView *scrolls = ScrollView::create(CCSizeMake(800,240),pContainer);
scrolls->setDirection(ScrollView::Direction::VERTICAL);
this->addChild(scrolls);
return true;
}
CCMenu类,只要注意这个类是Layer的一个子类,是一个层,它上面可以放好多MenuItem。
Control类及其子类,ControlSlider类这儿就写一个例子
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
ControlSlider *slider = ControlSlider::create("bossxt.png","bossxt1.png","vip1.png");
slider->setMinimumValue(0.0f);
slider->setMaximumValue(100.0f);
slider->setPosition(400,240);
slider->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::sliderCallback),Control::EventType::VALUE_CHANGED);
this->addChild(slider);
label = Label::create("0","",25);
label->setPosition(400,120);
this->addChild(label);
return true;
}
void HelloWorld::sliderCallback(cocos2d::Object *sender, Control::EventType controlEvent)
{
auto slide_control = (ControlSlider*)sender;//通过回调参数sender 获得ControlSlider
int current_value = slide_control->getValue();//获取slide当前的值
char str[32];
sprintf(str,"%d",current_value);
label->setString(str);
}
五、精灵类Sprite
精灵类可以用一张图片,或一张图片的一部分来定义,Sprite和它的子类可以作为精灵批处理类的子项。
Sprite类
纹理贴图集是将我们需要的部分图片放在一张大小固定的图片,可以节约内存。因为 OpenGL 机制会把单张图处理成相应大小的长宽都是 2 的 n 次方的图片,所以把图片放在一起可以节约空间。
贴图类CCTexture2D,贴图类CCTexture2D是OpenGL的概念,在OpenGL中称图片为贴图,在Cocos2dx中是图片对象的意思,可以通过它创建精灵对象。它直接继承于Ref类
精灵批处理类CCSpriteBatchNode,当要处理俩张或俩张以上的相同精灵时,如果逐个渲染,每一次渲染都会调用OpenGL函数,因为当系统在屏幕上渲染一张贴图的时候,图形处理硬件必须首先准备渲
染,然后渲染图形,最后完成渲染以后的清理工作。以上是每次渲染固定的开销,这样帧率就会下降 15% 左右或者更多。如果将所有需要渲染的同一张贴图只进行一次准备,一次渲染,一次清理就可以解决这个问题了。这时可以使用 CCSpriteBatchNode 类来批处理这些精灵,比如游戏屏幕中的***等就可以这样做。用它作为父层来创建子精灵,并且使用它来管理精灵类,这样可以提高程序的效率。(***等一次出现很多的相同精灵),这里需要说明的是,加入 CCSpriteBatchNode 类的精灵类越多,提高效率的效果就越明显。可以把CCSpriteBatchNode 类理解为CCLayer 类,只不过CCSpriteBatchNode类只接受CCSprite 类和它的子类。
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
CCSpriteBatchNode *batch = CCSpriteBatchNode::create("info_prop9.png");
batch->setPosition(0,0);
this->addChild(batch);//默认锚点是0,0,CCSpriteBatchNode相当于一个层,只是它里面只能放精灵
for (int i = 0; i < 100; i++)
{
int x = CCRANDOM_0_1()*700+50;
int y = CCRANDOM_0_1()*380+50;//CCRANDOM_0_1()这个宏是产生0-1之间的随机数
CCSprite *spr = Sprite::createWithTexture(batch->getTexture());
spr->setPosition(x,y);
batch->addChild(spr);
}
return true;
}
精灵帧类 CCSpriteFrame,精灵帧的概念是相对于动画而产生的。一个精灵是固定的节点,它可以拥有许多精灵帧(CCSpriteFrame) ,在它们之间切换就形成了动画。
精灵帧缓存类 CCSpriteFrameCache 用来存储精灵帧,提前缓存起来有助于提高程序的效率CCSpriteFrameCache是一个单例模式,不属于某个精灵,是所有精灵共享使用的。
六、摄像机类 CCCamera
所有节点都拥有一个摄像机类 CCCamera。只有通过摄像机类,节点才会被渲染出来。当节点发生缩放旋转和位置变化的时候,都需要覆盖 CCCamera 类,让这个节点通过CCCamera 类重新渲染。
可以通过 Sprite *spr = Sprite::create("aaa.png");
CCCamera *came = spr->getCamera();来获得属于该节点的摄像机,然后做一些操作,比如came->setEyeXYZ(0, 0, m_z);通过设置m_z的值就可以让一个精灵看起来离自己越来越远。
七、容器类CCArray
CCArray *array = CCArray::create();它不用确定存储对像的类型,每个对像类型可以不相同。
八、绘制图形类
在节点类CCNode中可以重写 draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated)函数并在其中绘制图形
void HelloWorld::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated)
{
Node::draw(renderer,transform,transformUpdated);
//画线
glLineWidth(3.0f);
ccDrawColor4B(255,0,255,255);
ccDrawLine(Point(0,0),Point(800,480));
//画圆
glLineWidth(2);
ccDrawColor4B(0, 255, 255, 255);
ccDrawCircle( Point(400,240), 50, CC_DEGREES_TO_RADIANS(90), 50, true);
//画多边形
CCPoint vertices2[] = { ccp(30,130), ccp(30,230), ccp(50,200) };
ccDrawPoly( vertices2, 3, true);
//画贝塞尔曲线
ccDrawQuadBezier(ccp(0,480), ccp(400,240), ccp(800,480), 50);
}
九、定时器
在游戏中,时常需要隔一段时间更新一些数据或者是人物位置,Cocos2D-x 中提供了这些时间调度的函数,所有 CCNode 类的子类都有这样的函数。
1.更新定时器
//开启定时器
this->scheduleUpdate();
//重写虚函数update
void HelloWorld::update(float dt)
{
}
2.自定义定时器
//开启定时器,延时2s执行,执行3+1次,执行间隔1s
this->schedule(schedule_selector(HelloWorld::log),1,3,2);
//回调函数
void HelloWorld::log(float dt)
{
}