cocos2dx性能优化之对象池

栏目: IOS · 发布时间: 7年前

内容简介:对象池机制:可回收与重复使用手机游戏的性能对于一款手机游戏来说,那是相当的重要了,我们常说的性能呢,一般包括耗电,发热情况,流畅度,是否存在卡帧等等。从专业的角度来说,包括FPS帧数,手速侦测,CPU和内存占用率等等。那我们今天就来说一下如何通过使用对象池的机制,有效的提高内存和计算效率,从而达到提高游戏流畅度的目的。

cocos2dx游戏性能优化之对象池

cocos2dx性能优化之对象池

对象池机制:可回收与重复使用

手机游戏的性能对于一款手机游戏来说,那是相当的重要了,我们常说的性能呢,一般包括耗电,发热情况,流畅度,是否存在卡帧等等。从专业的角度来说,包括FPS帧数,手速侦测,CPU和内存占用率等等。那我们今天就来说一下如何通过使用对象池的机制,有效的提高内存和计算效率,从而达到提高游戏流畅度的目的。

其本质与缓存类似,即希望能减少那些频繁使用的对象的重复创建和销毁,例如飞行射击类游戏中的子弹。使用对象池机制能带来两方面的收益,首先是减少对象初始化阶段的重复计算,其次是避免反复地向操作系统申请归还内存。一个很好的例子就是捕鱼游戏中的鱼,鱼和鱼之间的属性是类似的,不一样的仅仅是当前的坐标位置及正在播放的动画帧。那么,当鱼游出屏幕后,可以不对其进行销毁,而是暂存起来。某一时刻需要重新创建鱼时,我们可以将其从对象池中取出,重新申请内存并初始化,这样就大大减轻了 CPU 的负担。

一个高效实现的对象池还要考虑如何有效地处理对象的生成和归还,以及占用内存的动态增长等问题。

代码实现如下:

/*
** obejct pool template for create or destroy object
** by hnliu
** 2016.9.19
**/

#include "Singleton.h"
#include "Bullet.h"

template<class T>

class ObjectPool :public Singleton<ObjectPool<T>>
{
public:
    ObjectPool()
    {
        for (int i = 0; i < INITALCAPACITY; ++i)
        {
            auto pObj = new T();
            pObj->autorelease();
            pObj->retain();

            objects.push_back(pObj);
        }
    }

    ~ObjectPool()
    {
        for (auto iter = objects.begin(); iter != objects.end(); iter++)
        {
            (*iter)->release();
        }
        objects.clear();
    }

    //get a bullet
    T* getObject()
    {
        if (objects.empty())
        {
            for (int i = 0; i < INITALCAPACITY; ++i)
            {
                auto pObj = new T();
                pObj->autorelease();
                pObj->retain();

                objects.push_back(pObj);
            }
        }

        auto obj = objects.back();
        objects.pop_back();

        return obj;
    }

    void freeObject(T *obj)
    {
        //recycle part of pool
        if (objects.size() >= (1.5 * INITALCAPACITY))
        {
            for (int i = 0; i < INITALCAPACITY / 2; ++i)
            {
                auto obj = objects.back();
                obj->release();
                objects.pop_back();
            }
        }

        obj->reset();
        objects.push_back(obj);
    }

private:
    std::list<T*> objects;

    const int INITALCAPACITY = 256;
};

首先这是一个模板类,可以针对一切cocos2d::Ref的子类,使用起来也很方便,就是在初始话的地方ObjectPool::newInstance(),这样可以初始话一个鱼的对象池,对象池的构造函数中会初始化256个对象,不要忘记调用retain否则会在一帧结束后自动释放。

ObjectPool()
{
    for (int i = 0; i < INITALCAPACITY; ++i)
    {
        auto pObj = new T();
        pObj->autorelease();
        pObj->retain();

        objects.push_back(pObj);
    }

}

getObject方法可以从对象池里拿一个对象,然后,再使用结束了以后要使用freeObject归还对象。

T* getObject()
{
    if (objects.empty())
    {
        for (int i = 0; i < INITALCAPACITY; ++i)
        {
            auto pObj = new T();
            pObj->autorelease();
            pObj->retain();

            objects.push_back(pObj);
        }
    }

    auto obj = objects.back();
    objects.pop_back();

    return obj;
}

getObject方法,首先会判断对象池里还有没有对象了,如果发现没有了,就一次性创建256个对象,待使用,然后freeObject的时候,也会判断对象池里如果有充裕的对象,就会释放一部分对象。

void freeObject(T *obj)
{
    //recycle part of pool
    if (objects.size() >= (1.5 * INITALCAPACITY))
    {
        for (int i = 0; i < INITALCAPACITY / 2; ++i)
        {
            auto obj = objects.back();
            obj->release();
            objects.pop_back();
        }
    }

    obj->reset();
    objects.push_back(obj);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript Patterns

JavaScript Patterns

Stoyan Stefanov / O'Reilly Media, Inc. / 2010-09-21 / USD 29.99

What's the best approach for developing an application with JavaScript? This book helps you answer that question with numerous JavaScript coding patterns and best practices. If you're an experienced d......一起来看看 《JavaScript Patterns》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具