zoukankan      html  css  js  c++  java
  • 更改 cocos2dx CCRenderTexture 的使用方式

    在使用 cocos2d for iphone 的时候就觉得 CCRenderTexture 的使用有些奇葩,

    它内含了一个 CCSprite 成员变量,谓之曰方便使用,

    也许是未能理解到设计者的妙处,我一直对这个都是心存疑虑。

    CCRenderTexture,从名称来看,它应该被划分到 Texture 的范畴,

    以直观的方式来思考,那么我应该是用 CCSprite 的 spriteWithTexture:(CCRenderTexture*) 这个方法来使用这个东西。

    但实际上不是这样的,须以 spriteWithTexture:renderTexture.sprite.texture 的方式来使用。

    这令我不爽,但是也还妨害无大。

    到了  cocos2d-x 里面以后,我才发现,cocos2d-x 并不是简简单单对 cocos2d-iphone 做了翻译,

    它还改变了一些东西,用过的肯定都会发现,spriteWithFile 改成 create() 了,

    而且还不仅仅只是限于 CCSprite,很多类型都采用了 create() 的静态构造策略,

    我非常喜欢这一点,以往是 [CCSprite spriteWithFile],现在是 CCSprite::create() ,能少好几个字符,

    代码多起来了以后,这点儿小方便就能节省不少的时间。

    扯远了,ok,回到正题~

    cocos2d-x 里面,CCRenderTexture 的 sprite 成员还被预设性的加到了该 CCRenderTexture 对象里面。

    我只在 debug 模式下做开发,所有 assert 是有效的。

    这样的话,要像我之前在 cocos2d-iphone 里面那样重新 new 一个 CCSprite 对象来使用这个 CCRenderTexture 动态纹理的话,

    就不行了,因为 CCNode addChild 里面的断言 parent != NULL 过不了,

    简而言之就是:

    1。 CCRenderTexture 的 Sprite 成员没法再给加到别的 layer 里面去了,

    因为他已经有 CCRenderTexture 这个 “父亲” 了,要加的话你只能把 CCRenderTexture 对象加到某个 layer 里面去,

    然后 CCRenderTexture 的 sprite 成员自然而然也就被加到 layer 里面去了。

    这样有一个弊端,也是导致我思索这个问题的直接诱因。

    在  cocos2d-x 里面,CCRenderTexutre 生成的动态纹理 CCTexture2D 对象是脱离 CCTextureCache 独立存在的,

    这块动态纹理所占据的内存会在该 CCRenderTexture 销毁的时候被清理掉。

    如果我采用的是 cocos2d-box2d 模板,我在遍历 b2World 对象里面的各种附着了 sprite 的body 的时候,

    发现有需要将某个 body 连带他上面附着的 sprite 删除掉了,而且这个动作一直充斥在游戏运行的过程中的话,

    那我在销毁 sprite 的时候就没那么简单了,我还得判断一下这个 sprite 的父节点是不是 CCRenderTexture 才行,

    是的话连带这个 CCRenderTexture 都得干掉。

    (注:动态纹理占据的内存只会在 CCRenderTexture 被销毁的时候释放!

    简单销毁 CCRenderTexture 的 sprite 成员是不具有实际释放纹理的作用的)

    当然,这也并不是什么非常非常难的操作,但这让我觉得别扭。

    所以经过思考,我觉得吧 CCRenderTexture 的设计稍作更改:

    1。创建一个新的类型 BYRenderTexture(BY 的寓意为 Bruce Yang,也就是我的英文名了)

    这个 BYRenderTexture 到底和 CCRenderTexture 有何不同呢?

    BYRenderTexture 里面剔除了这个 鸡肋的 Sprite 成员变量。

    这虽然只是很小的改动,但是由我的经验来看,把扩展功能放在一个新建的类型里面,

    下次要用的时候翻出来会容易的多

    (假入直接在 cocos2d 源码里面做改动,可能在完成数个 cocos2d 项目过后,

    你做的扩展就会被淹没在大海里面,被忘却或者变地非常难以检索)。

    2。扩展一个 CCSprite 类型 —— BYSprite

    BYSprite 主要新增了一个 createWithRenderTexture(BYRenderTexture*)  的静态创建方法。

    它的优点就在于使用直观,在他释放的时候同时也会将 BYRenderTexture 的动态纹理释放干净。


    下面贴上相关代码:

    BYRenderTexture 仅移除 CCSprite 成员变量及相关 getter&& setter,

    另外,将 m_pTexture->release() 这一行代码由 BYRenderTexture() 的后几行转移到 ~BYRenderTexture() 析构里面的第一行。

    重点是 BYSprite 的代码,如下:

    BYSprite.h

    //
    //  BYSprite.h
    //  DreamStack
    //
    //  Created by user on 12-12-26.
    //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
    //
    
    #ifndef DreamStack_BYSprite_h
    #define DreamStack_BYSprite_h
    
    #include "cocos2d.h"
    #include "BYRenderTexture.h"
    
    USING_NS_CC;
    
    class BYSprite : public CCSprite {
    private:
        BYRenderTexture* m_pRenderTex;
    public:
        static BYSprite* createWithRenderTexture(BYRenderTexture* in_pRenderTex);
        
        BYSprite(BYRenderTexture* in_pRenderTex);
        ~BYSprite();
        
    };
    
    #endif

    BYSprite.cpp

    //
    //  BYSprite.cpp
    //  DreamStack
    //
    //  Created by Bruce Yang on 12-12-26.
    //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
    //
    
    #include "BYSprite.h"
    
    BYSprite* BYSprite::createWithRenderTexture(BYRenderTexture* in_pRenderTex) {
        BYSprite* t_pSprite = new BYSprite(in_pRenderTex);
        if (t_pSprite && t_pSprite->initWithTexture(in_pRenderTex->getTexture())) {
            t_pSprite->autorelease();
            return t_pSprite;
        }
        CC_SAFE_DELETE(t_pSprite);
        return NULL;
    }
    
    BYSprite::BYSprite(BYRenderTexture* in_pRenderTex) : m_pRenderTex(in_pRenderTex) {
        CCAssert(in_pRenderTex, "入参不可为空~");
        in_pRenderTex->retain();
        m_pRenderTex = in_pRenderTex;
    }
    
    BYSprite::~BYSprite() {
    //    printf(" ### ~BYSprite\n");
        m_pRenderTex->release();
    }

    使用也很简单(这里仅创建了一块全白的动态纹理做测试):

    CCTexture2DPixelFormat t_oFmt = kCCTexture2DPixelFormat_RGBA8888;
    BYRenderTexture* t_pRt = BYRenderTexture::create(in_fWidth, in_fHeight, t_oFmt);
    t_pRt->beginWithClear(1.f, 1.f, 1.f, 1.f);
    t_pRt->end();
        
    m_pSprite = BYSprite::createWithRenderTexture(t_pRt);
    m_pSprite->setFlipY(true);
    t_pLayerParent->addChild(m_pSprite)



  • 相关阅读:
    Mybatis如何插入空字段
    为什么要将action实例设置为多例
    hibernate dynamic-update="true"属性不起作用原因(转载)
    查找到匹配的进程并关闭 linux ps -ef
    Mac 下解决修改IntelliJ IDEA 由于修改配置之后无法启动问题
    再聊移动端页面的适配
    重学前端
    前端面试
    使用Flexible实现手淘H5页面的终端适配
    vue-cli3.0 使用px2rem 或 postcss-plugin-px2rem
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212072.html
Copyright © 2011-2022 走看看