美文网首页
分析quick-cocos3.3的display.lua源码

分析quick-cocos3.3的display.lua源码

作者: 凉拌姨妈好吃 | 来源:发表于2018-07-02 15:51 被阅读0次

这个模块主要封装了大多与显示有关的功能,并负责根据config.lua中定义的分辨率设计计算屏幕的设计分辨率。


因为Cocos是通过节点树来渲染整个场景,所以无论是场景、层、精灵、标签和菜单等都是继承自Node。所以我们在新建一个newLayer的时候,其实也会在节点树上新增一个节点
场景是所有节点的根节点,引擎渲染一个场景的时候,从树根往上渲染,底层的节点图像将被上层节点的图像覆盖。

这是用于创建颜色填充层的,其实大致与上面的普通创建一样,只是多了一些配置。我们要非常注意里面的node:setTouchSwallowEnabled(true),它设置了触摸吞噬为true。
什么是触摸吞噬?
它的作用就是是否继续传递触摸消息,在绘制节点的时候,越是在屏幕下方的,ZOrder越大的,越先接收到触摸事件,如果设置吞噬,那么下方的所有节点将不会接收到触摸消息了

tolua.type(filename)用于返回变量的类型,下面会根据它的类型选择不一样的精灵创建方式
string.byte(filename) == 35因为没有传入位置,所以默认返回第一个位置的Asii码,这里用于判断第一个Ascii码是否为35,即#
params.capInsets是图像要变形的大小
sprite:setPosition(x, y)根据传入的x,y设置它的position
九宫格图像
一个矩形图像会被分为9个部分,然后根据要求拉伸图像,同时保证拉伸后的图像四边不变形

创建一个平铺的精灵



math.angle2radian(params.startAngle)角度转弧度
local radii = startRadian + i * radianPerSegm每段弧度乘以i,算出最后的弧长
points[#points + 1] = {posX + radius * math.cos(radii), posY + radius * math.sin(radii)}计算圆的点的位置
注意display.newPolygon(points, params, self)这个函数非常重要,几乎所有的画图形都会用到它,可以用来划线,比如在这里就是给圆画有颜色的边线
异步加载图片
void TextureCache::addImageAsync(const std::string &path, const std::function<void(Texture2D*)>& callback)
{
    Texture2D *texture = nullptr;

    std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path);

    auto it = _textures.find(fullpath);
    if( it != _textures.end() )
        texture = it->second;

    if (texture != nullptr)
    {
        callback(texture);
        return;
    }

    // 慢启动
    if (_asyncStructQueue == nullptr)
    {             
        _asyncStructQueue = new queue<AsyncStruct*>();
        _imageInfoQueue   = new deque<ImageInfo*>();        

        // 创建一个线程不停尝试加载图片资源
        _loadingThread = new std::thread(&TextureCache::loadImage, this);

        _needQuit = false;
    }

    if (0 == _asyncRefCount)
    {
//创建定时器,会去执行TextureCache::addImageAsyncCallBack
        Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(TextureCache::addImageAsyncCallBack), this, 0, false);
    }
//引用计数+1
    ++_asyncRefCount;

    // generate async struct
    AsyncStruct *data = new (std::nothrow) AsyncStruct(fullpath, callback);

    // add async struct into queue
//避免多线程访问
    _asyncStructQueueMutex.lock();
//它将会在loadImage中进行移除
    _asyncStructQueue->push(data);
    _asyncStructQueueMutex.unlock();
  //唤醒等待线程
    _sleepCondition.notify_one();
}

我们在调用loadImage时,会将刚才上面添加在asyncStructQueue的队列中移去加载过的结构体



保存图片信息到结构体中,将结构体放在加载完成的队列中。



从上面的图片信息的队列取出图片信息,然后初始化图片,缓存纹理

注意BatchNode和Node直接的区别

-- 下面的代码绘制 100 个图像只用了 1 次 OpenGL draw call
local batch = display.newBatchNode(imageName)
for i = 1, 100 do
    local sprite = display.newSprite("#Sprite0001.png")
    batch:addChild(sprite)
end

-- 下面的代码绘制 100 个图像则要使用 100 次 OpenGL draw call
local group = display.newNode()
for i = 1, 100 do
    local sprite = display.newSprite("#Sprite0001.png")
    group:addChild(sprite)
end

看源码可以发现,只要牵扯到新建精灵帧的都会先去缓存中取取看有没有存在相关的精灵帧

function display.newSpriteFrame(frameName)
    local frame = sharedSpriteFrameCache:getSpriteFrame(frameName)
    if not frame then
        printError("display.newSpriteFrame() - invalid frameName %s", tostring(frameName))
    end
    return frame
end

相关文章

网友评论

      本文标题:分析quick-cocos3.3的display.lua源码

      本文链接:https://www.haomeiwen.com/subject/ziskuftx.html