2012-02-29 107 views
4

我需要我的精灵过渡到一种颜色到另一种颜色,然后......蓝色色调然后是绿色然后紫色,但我找不到任何好的动作,我想知道,我应该使用动画?或者有没有为此采取的行动?颜色变化的小精灵Cocos2d

+0

您是否试过CCTintTo? – 2012-02-29 02:12:58

+0

还没有尝试thx – mattblessed 2012-02-29 02:21:40

回答

11

可以使用CCTintTo行动改变精灵

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

,因为我看到了有关在精灵置换像素颜色的几个问题的颜色,我did'nt看到什么好的解决办法(所有解决方案仅在着色颜色,并且它们中的任何一个都不能改变颜色数组而不强制你创建构成最终图像的多个图像层,即:一层用于平底锅,另一层用于展示,其他用于衬衫,另一层用于头发颜色。 ..并继续 - 注意他们确实有他们的优势,如使用精确梯度的能力)

my solut ion允许您更改颜色数组,这意味着您可以使用已知颜色的单个图像(您不希望此图层中有任何渐变色,只有您知道其值的颜色 - 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])); 

当然,如果你需要的速度,你会创造,创造一个像素一个精灵的延伸着色器,它会在渲染时加速;)

btw:这种解决方案可能会在某些情况下在边缘产生一些假象,因此您可以创建一个大图像并缩小它,lettin GL最小化人造物。 您还可以创建带黑色轮廓的“修复”图层,以隐藏文物并将其放置在顶部等。 还确保您不希望像素的图像的其余部分使用这些“关键”颜色改变。 也记住alpha通道没有改变的事实,并且如果您仅使用纯红/绿/蓝颜色的基本图像,您还可以优化此功能以自动消除边缘上的所有假象(并避免很多情况下,额外遮阳层的需求)和其他有趣的东西(复用多个图像到一个单一的位图 - 记调色板动画)

享受;)

+0

在纹理加载时替换颜色是一种很好的方法,但在android上,当应用程序重新进入前景时,纹理将被重新加载。为了使其一般化,需要扩展纹理缓存机制以知道颜色数组。 – 2015-02-02 12:13:29

+0

如何更换不仅颜色,而且alpha通道? – 2017-10-29 15:01:21

1

如果有人想这个对了cocos2d-x在这里?是代码:

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