Color Change Sprites Cocos2d

I need my sprite to go from one color to another, and so on ... like a blue tint, then green and then purple, but I can’t find any good action for this, and I wonder if animation should be used? or is there a built-in action for this?

+4
source share
3 answers

you can use the CCTintTo action to change the color of the sprite

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

since I saw several questions about replacing pixel colors in sprites, and I did not see any good solution (all solutions only shade the color, and none of them can change the array of colors, without forcing you to create several that build the final image that you if you want, that is: one layer for pots, another for show, another for shirt, another for hair color ... and this continues - note that they have their own advantages, such as the ability to use accurate gradients)

my solution allows you to change the array of colors, that is, you can have one image with known colors (you do not want any gradients in this layer, only the colors that you KNOW their values ​​- PS this only applies to the colors that you intend for changes, other pixels can have any color you want) if you need gradients over the colors you change, create an additional image with only shading and put it as the child of the sprite.

also remember that i'm super-new to cocos2d / x (3 days) and this code is written for cocos2dx, but can be easily ported to cocos2d.

Also note that I did not test it on android only on iOS, I'm not sure how capable the official version of gcc for Android is and how it will deal with how I allocate _srcC and _dstC, but again this is easy to port.

so here it is:

 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; } 

To use it, follow these steps:

 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]) ); 

Of course, if you need speed, you must create an extension for the sprite that creates the pixel shader, which speeds it up during rendering;)

btw: this solution may lead to some artifacts at the edges in some cases, so you can create a large image and scale it, allowing GL to minimize the artifact. you can also create β€œfix” layers with black outlines to hide artifacts and place them on top, etc. also make sure that you do not use these β€œkey” colors in the rest of the image that you do not want the pixels to change. also remember that the fact that the alpha channel does not change, and that if you use basic images with only red / green / blue colors, you can also optimize this function to automatically eliminate all artifacts around the edges (and avoid many cases, the need for an additional layer of hue) and other interesting things (multiplexing several images into one raster image - remember the palette animation?)

enjoy;)

+4
source

If someone needed this for cocos2d-x, here is the code:

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

Source: https://habr.com/ru/post/1398944/


All Articles