Author Topic: Dynamic FlxSprite coloring  (Read 4390 times)

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
Dynamic FlxSprite coloring
« on: Sun, Apr 29, 2012 »
I was emailing "initials" about this the other day, he gave me a bit of a starting point for this discovery...

The original Flash version of Flixel of course allows you to do things like "sprite.color = 0xff0000;" to instantly tint an FlxSprite to be red. When I developed the prototype of my game Connectrode in Flixel, I colored all of the sprites this way in the Flash version...

...Then I brought Connectrode over to the iOS version of Flixel and discovered this capability didn't work! There's a "color" member on FlxSprite's on the iOS version; but if you set it, nothing happens. At that time, I just made special textures for each color, and moved on.

It's a year since then and I'm trying to do a "thank you" update to Connectrode, to thank all the players who bought the game out of solidarity last month (when some drama went down between me, Zynga, and my former CEO). One thing I had always wanted to do was make my "matching colored tiles" game playable by people who were colorblind. To allow for this, I wanted to let players choose their own colors for the 6 piece types used in the game - so, I looked into solving dynamic tinting for real.

Turns out this is pretty simple. Go to the function FlxSprite.renderSprite()... look for the line "glPushMatrix();"... and right after that line, add these lines of code:

Code: [Select]
float redMultiplier = ((float)( _color >> 16 & 0xff )) / 255.0f;
float greenMultiplier = ((float)( _color >> 8 & 0xff )) / 255.0f;
float blueMultiplier = ((float)( _color & 0xff )) / 255.0f;
float alphaMultiplier = _alpha;
glColor4f( redMultiplier, greenMultiplier, blueMultiplier, alphaMultiplier);

The color tinting of FlxSprites will now work exactly as you'd expect. Hope this helps folks!
I'm just one guy trying to make some interesting decisions!

initials

  • Contributor
  • ****
  • Posts: 378
  • Karma: +0/-0
  • Initials
    • View Profile
    • Initials Blog. Code and other things.
Re: Dynamic FlxSprite coloring
« Reply #1 on: Sun, Apr 29, 2012 »
This is awesome!
It opens up the doors to do some really powerful things with OpenGLes.

I'm planning on trying Y-Axis rotates, Z-Axis depth, rainbow mode... all sorts of things.

The other thing I want to do which I have already done in my custom Flash flixel version, is make a
Code: [Select]
[FlxSprite fadeToColor:uint duration:float]. It works great for fading sprites out to black to make a silhouette effect.

Thanks IQ.
« Last Edit: Sun, Apr 29, 2012 by initials »
Initials: Super Lemonade Factory, Super Lemonade Factory Part Two, Above The Clouds, Revvolvver, Four Chambers of the Human Heart

tokyotron

  • Member
  • **
  • Posts: 27
  • Karma: +0/-0
    • View Profile
Re: Dynamic FlxSprite coloring
« Reply #2 on: Fri, May 11, 2012 »
I tried it. Didn't work... until I realized that everything inside " - (void) setColor:(unsigned int)Color;" was commented out. I just added
Code: [Select]
_color = Color; and now it seems to work. This can be real useful I agree  ::)

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
Re: Dynamic FlxSprite coloring
« Reply #3 on: Tue, May 29, 2012 »
Whoops, thanks for catching that tokyotron! I had messed around that code early in Connectrode development and totally forgotten it was another necessary change.
I'm just one guy trying to make some interesting decisions!

tokyotron

  • Member
  • **
  • Posts: 27
  • Karma: +0/-0
    • View Profile
Re: Dynamic FlxSprite coloring
« Reply #4 on: Mon, Jun 11, 2012 »
You can also try encapsulating glDrawArrays with GL_COLOR_ARRAY...

   glColorPointer(4, GL_UNSIGNED_BYTE, 0, gRectColors);
   glEnableClientState(GL_COLOR_ARRAY);
   glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
   glDisableClientState(GL_COLOR_ARRAY);



Where gRectColors could look like this

static const GLubyte gRectColors[] =   {
   255, 0, 0, 255, // red?
   0, 255, 0, 255, // g?
   0, 0, 255, 255 // b?
};

It would allow more different kinds of colorings with nice gradients and stuff.
Now if you look at FlxSprite again you can see that glEnableClientState(GL_COLOR_ARRAY); is already in there, but it seems disabled or only active under some circumstances (_alpha != 1.0 || filled). So should be possible maybe already provided _colors is really used. Not really sure what "filled" and that stuff means yet but if needed I'm sure it wouldn't be too hard to work it out.

initials

  • Contributor
  • ****
  • Posts: 378
  • Karma: +0/-0
  • Initials
    • View Profile
    • Initials Blog. Code and other things.
Re: Dynamic FlxSprite coloring
« Reply #5 on: Wed, Jun 13, 2012 »
I really appreciate your input here Tokyotron. Great to learn some new OpenGLes tricks.
Initials: Super Lemonade Factory, Super Lemonade Factory Part Two, Above The Clouds, Revvolvver, Four Chambers of the Human Heart