Изменяющие цвет спрайты Cocos2d - PullRequest
4 голосов
/ 29 февраля 2012

Мне нужен мой спрайт для перехода к одному цвету в другой и так далее ... как синий оттенок, затем зеленый, а затем фиолетовый, но я не могу найти хороших действий для этого, и мне интересно, должен ли я использовать анимацию? или для этого есть встроенное действие?

Ответы [ 3 ]

11 голосов
/ 29 февраля 2012

вы можете использовать действие CCTintTo для изменения цвета спрайта

[sprite runAction:[CCTintTo actionWithDuration:2 red:255 green:0 blue:0]];
4 голосов
/ 24 декабря 2012

, так как я видел несколько вопросов о замене цветов пикселей в спрайтах, и я не видел ни одного хорошего решения (все решения только окрашивают цвет, и ни один из них не может изменить массив цветов, не заставляя вас создавать несколько Слои изображений, которые создают конечное изображение, которое вы хотите, то есть: один слой для сковородок, другой для показа, другой для рубашки, другой для цвета волос ... и так далее - обратите внимание, что у них есть свои преимущества, такие как способность использовать точные градиенты)

Мое решение позволяет вам изменять массив цветов, то есть вы можете иметь одно изображение с известными цветами (вам не нужны градиенты в этом слое, только цвета, которые вы ЗНАЕТЕ их значения - PS Это относится только к тем цветам, которые вы намереваетесь изменить, другие пиксели могут иметь любой цвет, который вы хотите) если вам нужны градиенты над изменяемыми цветами, создайте дополнительное изображение только с затенением и поместите его в качестве дочернего элемента спрайта.

также помните, что я совершенно новичок в cocos2d / x (3 дня), и что этот код написан для cocos2dx, но может быть легко перенесен в cocos2d.

также обратите внимание, что я не тестировал его на Android только на iOS, я не уверен, насколько способен 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 минимизировать артефакт. Вы также можете создать «исправление» слоев с черными контурами, чтобы скрыть артефакты и поместить их сверху и т. д. также убедитесь, что вы не используете эти «ключевые» цвета на остальной части изображения, вы не хотите, чтобы пиксели были изменены. Также имейте в виду, что тот факт, что альфа-канал не изменился, и что, если вы используете базовые изображения только с чистыми красными / зелеными / синими цветами, вы также можете оптимизировать эту функцию для автоматического устранения всех артефактов на краях (и избежать во многих случаях). случаи, необходимость в дополнительном слое тени) и другие интересные вещи (объединение нескольких изображений в одно растровое изображение - помните палитру анимации?)

наслаждайся;)

1 голос
/ 04 июня 2015

Если кто-то хотел это для cocos2d-x, то вот код:

somesprite->runAction(TintTo::create(float duration, Color3b &color));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...