cocos2d lua 对象池封装

作者: 90d81be3ec65 | 来源:发表于2018-03-21 23:55 被阅读129次
  • 最近心情比较低落,想找些事转移下注意力,于是就产生了这篇文章。讲真,写写东西还真能让自己平静。对象池主要应用于游戏中频繁产生消失的物体,比如王者荣耀里面的小兵、SLG游戏里面的地图格、飞机大战里面的飞机子弹,捕鱼游戏里面的鱼,按照传统做法,用的时候创建,不用的时候移除,那么带来的内存开销是巨大的,可以通过实现创建好保存在内存中来解决此类问题。废话不多上,附上初版(未完成动态扩容及缩容,后续完善)代码:
local M = {}
ObPool = M

function M.new(name, size)
    size = size or 1
    local pool, cls = M[name] or {_usingNum = 0}, _G[name]
    for i = 1, size do
        local obj, index = cls.new(), #pool + 1
        obj:retain()
        obj._index = index
        pool[index] = obj
    end
    M[name] = pool
end

function M.delete(name)
    local pool = M[name]
    if pool == nil then return end

    for _, obj in pairs(pool) do
        obj:release()
    end
    M[name] = nil
end

function M.getOb(name)
    local pool = M[name]
    if pool == nil then return end

    local usingNum = pool._usingNum + 1
    pool._usingNum = usingNum

    local obj = pool[usingNum]
    if obj == nil then
        M.new(name)
        obj = pool[usingNum]
    end
    return obj
end

function M.backOb(obj)
    local pool = M[obj.__cname]
    local usingNum = pool._usingNum
    pool._usingNum = usingNum - 1

    -- 交换释放的对象和对象池中最后一个元素的位置,并交换索引,因为getOb()都是取的最后一个位置
    local tmp, tmpIndex = pool[usingNum], obj._index
    pool[usingNum], obj._index = obj, usingNum
    pool[tmpIndex], tmp._index = tmp, tmpIndex
end
  • 需要放入对象池的对象的类写法,说的有点绕,就是通过这个类创造出来的对象需要放入对象池。
local M = class("TestSprite", function()
    return cc.Sprite:create()
end)

function M:ctor()
    -- 初始化
end

--[[
    此函数非必须:
    将对象归还对象池时候,清理遗留下的状态和变量;
    以免下次使用时候附带“杂物”;
]]
function M:poolReset()

end

--[[
    此函数必须:
    从父类移除时候,清理自己并归还对象池
]]
function M:onCleanup()
    local f = self.poolReset()
    if f then f(self) end
    ObPool.backOb(self)
end

function M
  • 附加说明,TestSprite在require的时候以及加入lua 全局变量表_G中。如下对cocos2d class略作改变,加了一句if classname then _G[classname] = cls end
    ,因此可以通过_G["TestSprite"]取得TestSprite类。
function class(classname, super)
    local superType = type(super)
    local cls

    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end

    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        cls = {}

        if superType == "table" then
            -- copy fields from super
            for k,v in pairs(super) do cls[k] = v end
            cls.__create = super.__create
            cls.super = super
        else
            cls.__create = super
        end

        cls.ctor = function() end
        cls.__cname = classname
        cls.__ctype = 1

        function cls.new(...)
            local instance = cls.__create(...)
            -- copy fields from class to native object
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
        end

    else
        -- inherited from Lua Object
        if super then
            cls = clone(super)
            cls.super = super
        else
            cls = {ctor = function() end}
        end

        cls.__cname = classname
        cls.__ctype = 2 -- lua
        cls.__index = cls

        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end

    if classname then _G[classname] = cls end

    return cls
end
  • 使用例子简单说明如下,还未完全测试。写了一晚上困死了先睡觉,代码明后天再测试下,有bug的话会更新。
-- 对象池里面new出100个TestSprite
ObPool.new("TestSprite", 100)

-- delete对象池中所有TestSprite
ObPool.delete("TestSprite")

-- get
local spr = ObPool.getOb("TestSprite")
parent:addChild(spr)

相关文章

  • cocos2d lua 对象池封装

    最近心情比较糟糕,想找些事转移下注意力,于是就产生了这篇文章。讲真,写写东西还真能让自己平静。废话不多上,附上代码...

  • Cocos2d-lua工程运行流程的理解

    关键词: cocos2d-lua项目启动流程 lua调用cocos2d引擎API 开发环境: 引擎版本:Cocos...

  • Unity对象池封装

    一共分为两个类,SubPool与ObjectPool,SubPool类为总对象池包含ObjectPool的子池子,...

  • Lua弱引用GameObject的坑

    1、背景   在Lua写了个GameObject的对象池,在某个特殊地方发现,GameObject还存在,但是Lu...

  • iOS工程集成Cocos2d-x lua模块

    本片文章针对iOS原生工程集成 Cocos2d-x lua 游戏模块, 如果只是为了导出 Cocos2d 工程到i...

  • lua使用自定义动态库

    阅读服务端框架skynet. 里面涉及了c封装的so供给lua层调用本文主要讲述如何封装一个so。并供给lua层调...

  • tolua笔记

    LuaState●LuaState封装了对lua 主要数据结构 lua_State 指针的各种堆栈操作。●一般对于...

  • 看图学习23种设计模式(一)

    命令模式 工业级案例:java中使用线程池时,就是将一系列的命令封装为thread对象,然后交由线程池处理。 策略...

  • 线程池的使用

    1.创建线程池代理者,由于创建线程池所需参数过多,因此封装在代理者中创建,需要拿到线程池对象时,找其代理者即可 2...

  • cocos2dx-lua 加速器调研(一)

    cocos2d Speed调研 一.搭建cocos2d-x 4.0项目 主要是纯c++和纯Lua游戏(4.0里面已...

网友评论

  • 4a3c3e234b46:应用场景是怎样的呢
    90d81be3ec65:@天天天占 当一个场景用到很多精灵,可以预先创建好放在对象池中。比如卡包界面list英雄几百个,地图上地图格成千上万个,都可以预先创建好,当该英雄在list中的位置不在屏幕范围内或者地图格不在视野范围内那么归还对象池,给新的英雄或者地图格重复使用。:smile:感谢问这个问题,好像我写了半天没写应用场景,有空补上。
  • 松子军师:写了一晚上困死了这一句给赞。
    90d81be3ec65:@Y我_8d5e :sweat_smile:别闹

本文标题:cocos2d lua 对象池封装

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