基础复习

【http 请求中 post 与get的区别:】

get提交的时候数据  放到URL后面,
post放在HTTP协议  消息体中。

【lua函数中:和.的区别】:
function a:foo()
   //这里可以直接用self
    print(self.x)--输出a.x的值
end

function a.fool()
   //这里不能直接用self 必须 在参数里显示地传入self 
   // function a.foo(self)
          print(self.x)
      end
end

【lua的基本数据类型】:number(双精度浮点数),bol(true和false),
string(‘’或者“”,字符,字符串),nil,function(方法),table(表),thread(线程),userdata(用户自定义类型).

【lua 模拟类的写法】:使用table和function模拟类,table描述对象属性、function 表示行为方法。
cocos2d-lua引擎自己封装了类class:
cocos-lua的继承:一共有三种继承(
1、类继承自方法:
   local classA = class(“classA”,function()                  return cc.Scene:create() 
   end)
2、类继承自原生c++类:
   local classB = class("classB",cc.Node)
3、类继承自lua纯table
   local classC = class("classC",{a=1})

【lua面向对象编程】:元表 metatable,对table的一系列预定义操作(使用元方法操作table,怎么添加元方法呢,setmetatable)
元方法:重要代表__index和__newindex。

__index的使用:(在查找表元素时)

1、在表中找,找到返回元素,没找到进行2;
2、判断表是否有元表,如果有则进行3,没有返回空;
3、判断元表中有没有__index方法;没有返回nil;如果__index方法传入的是一个table,则重复步骤123;若__index传入的是function 则返回函数的返回值。

【c++数组的优缺点:】
数组定义:固定大小的相同类型的元素的顺序集合

优点:通过键值查找 和遍历方便。(总结访问方便)

缺点:增加和删除速度慢;占用的内存地址是连续的,不能过长;长度固定不能改变;C++中元素类型必须统一;通过值查找速度慢。

【热更新核心思想】
1、读取本地的配置文件 (配置文件为所有游戏资源文件的MD5值,可以是任意文件格式的);
2、从服务 器下载配置文件和本地对比;
3、下载更新文件并写入本地;
4、设置搜索路径的优先级。(更新文件地址中的文件具有优先级)
5、更改md5表单为最新。

【cocos动作实现机制】

基类:CCAction(抽象类)
派生类:CCFiniteTimeAction(大部分动作实现)
由CCFiniteTimeAction派生的两个主要类:
(CCActionInstant、CCActionInterval)
瞬时动作类:CCActionInstant
    ⬇
主要的派生类(CCFlipX,CCShow,CCHide,CCCallFunc);

持续性动作类:CCActionInterval
    ⬇
主要的派生类(CCMoveTo,CCMoveBy,CCScaleTo,CCDelayTime);

动作执行过程:
当一个CCNode执行runAction(CCAction*action )方法时。会调用ActionManager的addAction方法,ActionManager 会将新的CCAction和对应的目标节点CCNode,添加到其管理的【动作表中】。将动作添加到动作队列后,对该CCAction调用成员函数startWithTarget(CCNode*pTarget)来绑定该动作的执行者。

ActionManager的初始化在CCDirector的初始化里执行。
【在里面通过CCSchedule定时调度器为ActionManager注册了一个定期更新任务】
所以:
以上准备完之后,在每一帧刷新时,ActionManager都会遍历其【动作表】中的动作,并调用该动作的step(ccTimedt)方法。step中主要负责计算m_elapsed(动作执行的时间),并调用update(float time),来完成动作的实现。
注意;在update执行过程中。会检测该动作的生命周期,isDone()
bool Repeat::isDone(void) const
{
    return _total == _times;
};如果时间到了就从动作列表中删除。

总结:计算刷新次数 是根据update 的参数(0--1),如果等于1就停止刷新。所以在瞬时动作中update的参数总是1。(不需要多次刷新);CCRepeatForever 动作的 isDone 函数始终返回 false。

【【【在Director的 init中ActionManager向Schedule注册了一个最高优先级的回调。然后每一帧回调更新_scheduler->update(_deltaTime); 
都会调用ActionManager的update方法。】】】

【事件机制】

Event(EventCustom)
EventListener(EventListenerCustom)
EventDispatcher(与节点绑定)

Event 事件EventCustom:new(data)(data中包含Name和其他的数据)

EventListener事件监听器(一个回调函数、一个订阅者类型type,以及一个listenerlD(custom自定义是EventName))
EventListenerCustom:new(name,callbacks)

EventDispatcher (增加或删除Listener
例如:增加: EventDispatcher:addEventListenerWithFixPriority 或者 WithGraphPriority
删除:EventDispatcher:removeCustomEventListeners(evtName)
      EventDispatcher:removeEventListener(handler))
EventDispatcher (方法dispatchEvent 触发事件 eventDispatcher.dispatchEvent(event),触发之后完成回调(执行回调函数,传递data))

【调度管理器】

cocos2d-x引擎启动后Director类会创建一个默认的调度管理器,所有的Node类默认都会引入Director的调度管理器,调度管理器会在Director的 mainLoop里的 drawscene方法里被每一帧都调度

“单例模式 ”
Director  TextureCache(纹理缓存) 

UserDefault(用户信息)
cc.UserDefault:getInstance()

SpriteFrameCache(精灵帧缓存工具)
cc.SpriteFrameCache:getInstance()

FileUtils(文件管理工具)
cc.FileUtils:getInstance()

ActionManager PoolManager (代码内)

“简单工厂模式” (create方法)
“观察者模式” (事件机制, 监听与派发)
“二段构建模式” (create 方法内 先new()分配内存,在init初始化内容,并顺带进行了内存管理)
“装饰者模式”

【cocos2d-x如何实现跨平台】
cocos工程中封装了各个平台的入口文件,通过接口转换,最终运行到CCAplication的run方法

主类CCApplicationProtocol(定义)
 ↓
主类 CCAplication (继承)
 ↓ 
AppDelegate app (继承并实现)
在创建app对象时 调用其构造函数 以及父类构造函数
在AppDelegate 中实现applicationDidFinishLaunching()方法
在父类CCApplication 中run()开始,就调用了子类的APPDelegate中的同名方法。

简单说来:applicationDidFinishLaunching 是由 CCApplicationProtocol 定义,CCApplication 继承, AppDelegate 实现的 ~)

【新的渲染流程】

现在,一个渲染流程是这样的:


(1)drawScene开始绘制场景


(2)遍历场景的子节点,调用visit函数,递归遍历子节点的子节点,以及子节点的子节点的子节点,以及…


(3)对每一个子节点调用draw函数


(4)初始化QuadCommand对象,这就是渲染命令,会丢到渲染队列里


(5)丢完QuadCommand就完事了,接着就交给渲染逻辑处理了。


(6)是时候轮到渲染逻辑干活干活,遍历渲染命令队列,这时候会有一个变量,用来保存渲染命令里的材质ID,遍历过程中就拿当前渲染命令的材质ID和上一个的材质ID对比,如果发现是一样的,那就不进行渲染,保存一下所需的信息,继续下一个遍历。好,如果这时候发现当前材质ID和上一个材质ID不一样,那就开始渲染,这就算是一个渲染批次了。


Ref* Ref::autorelease()
{
    PoolManager::getInstance()->getCurrentPool()->addObject(this);
    return this;
}

_managedObjectArray(Object对象集合)

void AutoreleasePool::addObject(Ref* object)
{
    _managedObjectArray.push_back(object);
}

_releasePoolStack(autoreleasePool对象集合)
void PoolManager::push(AutoreleasePool *pool)
{
    _releasePoolStack.push_back(pool);
}

MainLoop(主循环)
         ↓
void DisplayLinkDirector::mainLoop()
{
    if (_purgeDirectorInNextLoop)
    {
        _purgeDirectorInNextLoop = false;
        purgeDirector();
    }
    else if (! _invalid)
    {
        drawScene();
     
        // release the objects
        (获得当前_releasePoolStack的releaPool进行clear操作)
    PoolManager::getInstance()->getCurrentPool()->clear();
    }
}
      ↓(clear操作)

void AutoreleasePool::clear()
{
对当前autoreleasePool中的所有ref元素进行release操作

    std::vector releasings;
    releasings.swap(_managedObjectArray);
    for (const auto &obj : releasings)
    {
        obj->release();(循环结束之后,当前池中的所有object引用计数减一)
    }
}
到此一帧的自动释放池释放工作完成,poolManager继续操作下一个autoreleasePool

【cocos2d-x屏幕适配】
屏幕适配 函数
----//屏幕实际分辨率(并非设备长宽,游戏内只讨论分辨率,不考虑实际尺寸)
frameSize = director:getFrameSize()
宽高分别是FW,FH
设计分辨率宽高分别是DW,DH
屏幕分辨率与设计分辨率的比值:scaleX = FW/DW scaleY = FH/DH

setDesignResolutionSize(设计后width, 设计后height,resolutionPolicy_type)

第一种,EXACT_FIT(不等比例缩放,可能会变形)
第二种,NO_BORDER (无黑边,以设备分辨率与设计分辨率 比例大的进行缩放 Fwidth/Dwidth)
第三种,SHOW_ALL(全屏幕显示,以比例小的进行缩放,可能有黑边)
----------------------
以下两种:屏幕长宽比 与 设计分辨率长宽比 无拉伸变形
第四种:FIXED_HEIGHT(固定设计高度,(固定比例为)scaleX = scaleY,
传入高度DH,传入宽度DW = FW/scaleX,屏幕与设计分辨率的比值)
第五种:FIXED_WIDTH(固定设计宽度,(固定比例为)scaleY = scaleX
传入高度DH = FH/sacleY,传入宽度DW)

【assert】断言断言
assert(arg1,arg2)
assert(a==b,print("============="))
断言arg1是条件  当arg1是false时执行arg2

【纹理 优化内存】

写到这里才发现,其实只需要下面一句话就可以搞定。 
这类图片会不会同时出现多个,同时出现时,内存开销是否无法接受, 如果确实无法接受,则使用GPU纹理,否则,优先考虑JPG,JPG+ALPHA,或者PNG8。就是说,首先要减小安装包大小,如果内存有无法接受的情况,才需要用GPU纹理进行优化。
--------------------- 
提示与技巧: 

1、一帧一帧载入游戏资源 

2、减少绘制调用,打包大图 

3、载入纹理时按照从大到小的顺序 

4、避免高峰内存使用 

5、使用载入屏幕预载入游戏资源 

6、需要时释放空闲资源
 
7、收到内存警告后释放缓存资源 

8、使用纹理打包器优化纹理大小、格式、颜色深度等 

9、使用JPG格式要谨慎
10、请使用RGB4444颜色深度16位纹理 

11、请使用NPOT纹理,不要使用POT纹理 

12、避免载入超大纹理 

13、推荐1024*1024 NPOT pvr.ccz纹理集,而不要采用RAW PNG纹理
--------------------- 

【忽略锚点】:

Ignore Anchor Point全称是ignoreAnchorPointForPosition,作用是将锚点固定在一个地方;
如果设置其值为true,则图片资源的Anchor Pont固定为左下角,否则即为所设置的位置。

关于ccTouchBegan的返回值 
true: 
本层的后续Touch事件可以被触发,并阻挡向后层传递 
false: 
本层的后续Touch事件不能被触发,并向后传递 

【排序笔记】
冒泡排序: 重点是 每次遍历取出一个最大/最小值,放在末尾
选择排序:每次排序 取出一个最大/最小值,放在开头
(排好序的值在哪里 很关键,意味着遍历的结束条件)

【C++创建对象】
构造函数:先基类 再派生类
析构函数:先派生类 再基类

【父类 指针指向子类对象】
例: void foo1 ();
       virtual void  foo2();
Parent *p1 = new Child();
delete p1;
构造函数 函数调用 :{ 先调用父类构造 ,再调用子类构造 };
析构函数:
第一种情况:
{ 父类析构函数不是虚函数,则 此情况只会调用父类析构函数,不调用子类析构};
第二种情况:
{ 父类析构函数是虚函数,则 先调用子类析构函数,再调用父类析构函数
}
【方法调用】
p1->foo1;
p1->foo2;
结果:
parent foo1
Child foo2
结论:如果父类函数不是虚函数,则调用父类;如果是虚函数 ,则调用子类实现;
【子类对象】
Child c1;
c1.foo1();
c1.foo2();
构造:先父类再子类;析构 先子类再父类;
方法:都只调用 子类方法;
【总结】
{
    如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用哪个函数
    要根据【指针的原型】来确定,而不是根据指针实际指向的对象类型确定。
}
{
    在父类指针指向子类对象做对象销毁时,由于析构函数不是虚函数,则delete时,父类指针只能调用父类自己的析构函数,      这就造成了上述对象部分销毁的错误状况;
}
【引用和指针的区别】

    Parent *p1 = new Parent();
    Parent *p2 = new Parent();
    Parent& q = *p1;
    q = *p2;

 1.引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变。(上例中q并没有等于*p2)
 2. 引用必须指向有效的变量,指针可以为空。(引用必须初始化)
 3. sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
 4. 指针和引用自增(++)自减(-–)意义不一样。
 5. 相对而言,引用比指针更安全。

你可能感兴趣的:(cocos2dx,学习笔记)