颜色变化的精灵 Cocos2d

4

我希望我的精灵可以从一种颜色渐变到另一种颜色,如蓝色,然后是绿色,再到紫色,循环往复... 但我找不到任何好的操作来实现这一点,并且想知道,我是否应该使用动画? 或者有没有集成的操作可用于此?


你尝试过CCTintTo吗? - Bruno Domingues
3个回答

11

你可以使用CCTintTo动作来改变精灵的颜色

[sprite runAction:[CCTintTo actionWithDuration:2 red:255 green:0 blue:0]];

4

由于我看到了一些关于在精灵中替换像素颜色的问题,而且我没有看到任何好的解决方案(所有的解决方案只是对颜色进行着色,它们都不能改变一个颜色数组而不强制你创建多个图像层来构建你想要的最终图像,即:为裤子创建一层,为鞋子创建另一层,为衬衫创建另一层,为头发颜色创建另一层...等等-请注意,它们确实有其优点,如使用准确的渐变)

我的解决方案允许您更改颜色数组,这意味着您可以拥有一个已知颜色的单个图像(您不希望该层中有任何渐变,只有您知道其值的颜色-PS,这仅适用于您打算更改的颜色,其他像素可以具有任何颜色)如果您需要在更改的颜色上添加渐变,请创建一个仅包含阴影的附加图像,并将其作为精灵的子对象放置。

还要注意,我对cocos2d/x非常新(3天),而且这段代码是针对cocos2dx编写的,但可以轻松移植到cocos2d。

还要注意,我只在iOS上测试过它,没有在Android上进行测试,我不确定Android官方gcc的能力以及它如何处理我分配_srcC和_dstC的方式,但是这也很容易移植。

所以就是这样:

cocos2d::CCSprite * spriteWithReplacedColors( const char * imgfilename, cocos2d::ccColor3B * srcColors, cocos2d::ccColor3B * dstColors, int numColors )
{
    CCSprite *theSprite = NULL;

    CCImage *theImage = new CCImage;
    if( theImage->initWithImageFile( imgfilename ) )
    {
        //make a color array which is easier to work with
        unsigned long _srcC [ numColors ];
        unsigned long _dstC [ numColors ];
        for( int c=0; c<numColors; c++ )
        {
            _srcC[c] = (srcColors[c].r << 0) | (srcColors[c].g << 8) | (srcColors[0].b << 16);
            _dstC[c] = (dstColors[c].r << 0) | (dstColors[c].g << 8) | (dstColors[0].b << 16);
        }

        unsigned char * rawData = theImage->getData();
        int width = theImage->getWidth();
        int height = theImage->getHeight();

        //replace the colors need replacing
        unsigned int * b = (unsigned int *) rawData;
        for( int pixel=0; pixel<width*height; pixel++ )
        {
            register unsigned int p = *b;
            for( int c=0; c<numColors; c++ )
            {
                if( (p&0x00FFFFFF) == _srcC[c] ) 
                {
                    *b = (p&0xFF000000) | _dstC[c];
                    break;
                } 
           }
            b++;
        }

        CCTexture2D *theTexture = new CCTexture2D();
        if( theTexture->initWithData(rawData, kCCTexture2DPixelFormat_RGBA8888, width, height, CCSizeMake(width, height)) )
        {
            theSprite = CCSprite::spriteWithTexture(theTexture);
        }
        theTexture->release();
    }
    theImage->release();

    return theSprite;
}

只需按照以下步骤使用它:

ccColor3B src[] = { ccc3( 255,255,255 ), ccc3( 0, 0, 255 ) };
ccColor3B dst[] = { ccc3( 77,255,77 ), ccc3( 255, 0 0 ) };
//will change all whites to greens, and all blues to reds. 
CCSprite * pSprite =  spriteWithReplacedColors( "character_template.png", src, dst, sizeof(src)/sizeof(src[0]) );

当然,如果你需要速度,你可以创建一个扩展程序来为精灵创建一个像素着色器,在渲染时进行硬件加速 ;)
顺便说一下:这种解决方案可能会在某些情况下导致边缘出现一些伪像,所以你可以创建一个大图像并将其缩小,让GL来最小化这种伪像。你还可以创建"修复"层,用黑色轮廓来隐藏伪像并放置在顶部等等。此外,请确保不要在其他你不希望像素改变的图像上使用这些'键'颜色。还要记住,alpha通道没有被改变,如果你只使用纯红/绿/蓝色的基本图像,你也可以优化此函数以自动消除所有边缘伪像(在许多情况下,避免需要额外的阴影层)和其他很酷的东西(多路复用几个图像到单个位图 - 记得调色板动画吗?)
享受吧 ;)

在纹理加载时替换颜色是一个不错的方法,但在Android上,当应用程序重新进入前台时,纹理会被重新加载。为了使其通用化,需要扩展纹理缓存机制以了解颜色数组。 - Vlad Cioaba
如何替换不仅仅是颜色而且还包括alpha通道? - Dainius Kreivys

1

如果有人想在cocos2d-x中使用此代码,这里是代码:

somesprite->runAction(TintTo::create(float duration, Color3b &color));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接