Bitmapped graphics, or maybe some other option?

In my football game, I have 32 teams at this time, and 32 sets of sprites with each team’s white jerseys, and 32 sets of sprites with each team’s color jerseys.

In the original Tom Landry Strategy Football game, I had bitmapped graphics, so an array of I think 16 or 32 colors per team. This allowed me to have one set of images (instead of 32), and simply put a different value into the array index that was associated with the helmet stripe, etc.

But when I rewrote my game for iOS back in 2011, I saw no support for bitmapped graphics, so I just created separate spritesheets.

I’d really like to get back to something different now, that would allow me to have one sheet of sprites for white jerseys and one set for color jerseys, and let the users assign color values to different pieces (pants color, pants stripe, jersey color, shoulder stripe, etc), especially now that I want to be able to support more than 32 teams.

Does anyone have any suggestions on how to do this?

thanks!

Hey, I have a thought that I’m going to try, and I’ll share the results here.

My Landry game used bitmap graphics, but those aren’t really supported any more, so I created separate spritesheets for every team, and of course, that’s a lot of work, AND I have no idea how I’ll handle it when I have larger leagues.

BUT after thinking about it, and a search that brought up this link, I’m going to try something different and see if I can get it to work:

  1. create test white_jerseys.png and color_jerseys.png files, where I have specific colors in certain spots and ONLY in those spots. For example put a specific color for the pants, another color for the pant stripe, etc.
  2. when I load a spritesheet, go across the whole sheet if possible (or each sprite if necessary, computers are fast, LOL) and substitute another color for the given color. So the user might pick a shade of green for the pants and shade of yellow for the stripe, etc.

I hope this works, but it does leave another issue - helmet logos. If I can get the dynamic colors to work, then what I’ll try to do is provide optional team helmet logos (left and right) and see if I can somehow skew the logo just right for each sprite. I don’t know if this will work either. If not, we may use logos for the first pass.

I don’t know how many sprites you have, but if I was to do something like this, I’d either do that link’s solution, where you take a spritesheet, replace #FFFFF00 with like #FF0000 if your team’s color is red etc, then #FFFFFF01 with a slightly darker color of red for shading, and so on for each color you need to recolor.

But given how many different colors you’ve got, it might be easier to use a shader to do roughly the same thing, only dynamically. You wouldn’t need to load in the customized sprite sheet, just the one for both teams.

tl;dr basically I don’t know, the two ideas you suggest are the two things I can think of.

@TankorSmash, @slackmoehrle, and anyone else, I’ve been looking over the APIs, and I can’t find a way to get the actual data for a spritesheet, SpriteFrame, Sprite, or Texture, so that I can change the colors.

Here’s what I’m currently doing:

  1. based on the team, set the filename of the spritesheet
  2. call SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistFilename, spritesheetFilename)
  3. when animating, based on which sprite I need, I call sprite[i]->setSpriteFrame(SpriteFrameCache::getInstance()->spriteFrameByName(frameName));

So, one, is there a better way, and two, how the heck can I modify it to do this?

  1. use a common file name to load a spritesheet that has colors I’ll change
  2. somehow get the data for either the overall spritesheet, individual frames, or something, so that I can change the colors
  3. get the spriteFrame for my sprite, and it should already be colored (unless it turns out that I have to color every sprite on the fly)

Any ideas would be appreciated. Thanks.

You can create a Texture from an Image I think, and you can get the bytes from an Image, so you could go that way to edit the images. I’ve been curious about it so I’ll be following the thread too.

I would go with shaders and mask option. You have one spritesheet with basic “models”. The second one is “mask” spritesheet (or the same spritesheet, it doesn’t really matter).

Now, you would have to create final sprite in few steps:

  1. Get model from model spritesheet.
  2. Get proper mask (e.g. t-shirt mask) from mask spritesheet (it would be perfect to have mask the same size as a model).
  3. Use simple shader to render model with mask - here you set the color for the mask.
  4. Render it to texture.
    Goto 2 if you need to add more masks to the model.

I think this is a very flexible option. This way you can customize your character in any way, but of course it takes more steps.

Ok, I got something to work (see below)! Long way to go, in my case, because I’ve discovered that I have a ton of options to consider - some teams have solid shoulders, some have one vertical stripe, or one horizontal stripe, or two horizontal stripes, etc.

And I still have no idea how I’ll do logos, but maybe I can skew them, since I know each of my 78 sprites. I wonder if it’s possible to paste a logo onto a sprite so that it’s now part of the spriteframe, rather than having to constantly paste it. I image it would be some kind of xor operation or something.

As for my test, I changed my approach to this:

  1. create arrays of “editableColors” and “selectedColors”
  2. wrote a function, based on that other fellows, that creates a Texture2D and changes the colors
  3. then uses that Texture2D to add to my FrameCache

Works great!

Hey, that sounds really interesting, but I’m not 100% sure I follow. So, have a spritesheet like now, with all the sprite images, and then have different spritesheets that are just pieces:

  1. one with shoulders having one stripe
  2. a different one with shoulders having two stripes
  3. another with legs having an upper stripe
  4. another with legs having a lower stripe
  5. yet another with legs having full-length stripe (yes, I’ve actually seen all three versions!)
    etc?

and then, let the user pick “I want pants with just a lower stripe” etc, and then they choose the corresponding color?

Is this what you mean? If so, I like the idea a lot. What I don’t know, though, is how to then combine them so that my pants spritesheet merges on top of the basic spritesheet (after coloring the pants).

Thanks much!

Let the baseSprite be your main sprite (read from the spritesheet).

Then, you have a set of other sprites “masks”, like “pantsMask”, “tshirtMask” etc. (it must be the same size as baseSprite, so that you don’t care about the mask positioning inside baseSprite).

Then you have a “maskShader” which takes “mask” as a first parameter and “color” as a second parameter. maskShader just go for every pixel in “mask” and (e.g. if opacity is >0 or any other condition) replaces it with “color” and renders to baseSprite texture.

You run maskShader with your baseSprite. You render it to RenderTexture (same size as baseSprite) and you get eg. baseSpriteWithRedPants. Now you can use this baseSpriteWithRedPants as an input for the next mask.

This is the idea. Of course it needs to be coded nicely - it could be done like “skins”, if you keep the history of changes you could dynamically swap the skins etc. It is up to you :slight_smile: And if you need more details about how to create the final sprite you just need more detailed shaders and masks (like two colors pants etc.).

2 Likes