4

I have code to generate a player avatar spritesheet by pulling each individual body/clothing item and overlaying it in a particular order. Essentially, I'm trying to combine the clothing sheets into a single body by laying them over each other.

But the final output is ONLY the last item of clothing drawn.

Here is the two pieces of code I'm using to do it:

public function new(_username:String) 
{
    super();

    itemArray = new Array<String>();
    itemArray[0] = "Body";
    itemArray[1] = "Shoes";
    this.pixels = new BitmapData(Std.int(itemRect.width), Std.int(itemRect.height));

    for (itemName in itemArray)
    {
        //this.pixels.draw(prepareItem(itemName).pixels);
        var itemSprite:FlxSprite = prepareItem(itemName);
        stamp(itemSprite);
    }
}

private function prepareItem(assetName:String):FlxSprite
{
    var assetSprite:FlxSprite = new FlxSprite();
    assetSprite.loadGraphic("assets/images/" + assetName + ".png");

    assetSprite.pixels.threshold(assetSprite.pixels, itemRect, new Point(0, 0), "==", 0xFF00FF00);
    assetSprite.pixels.threshold(assetSprite.pixels, itemRect, new Point(0, 0), "==", 0xFFFF0000);

    return assetSprite;
}

As you can see, I've tried using draw() to draw pixels onto the existing BitmapData, and I'm also trying to stamp sprites generated from the clothes images.

I'm attaching an example to clarify my goal. Notice how the shoes are layered OVER the body. But with my current code, the shoes replace the body entirely.

Example

Body Shoes

Fuselight
  • 554
  • 6
  • 17

1 Answers1

3

But the final output is ONLY the last item of clothing drawn.

With your code, I'm actually seeing the two assets be drawn on top of each other - I guess that might not be noticable depending on the assets you were using.

The fix is simple: you need to offset subsequent sprites in your stamp() call, e.g. like this if you want to stack the assets vertically:

var currentY = 0;
for (itemName in itemArray)
{
    var itemSprite:FlxSprite = prepareItem(itemName);
    stamp(itemSprite, 0, currentY);
    currentY += Std.int(itemSprite.height);
}
Gama11
  • 31,714
  • 9
  • 78
  • 100
  • Hey, thanks for the answer. But I'm not looking to stack them vertically, I'm just trying to overlay them into a single sheet. That's my bad for an unclear question. – Fuselight Jun 26 '18 at 16:00
  • Could you maybe share both input images, so it's easy to reproduce? – Gama11 Jun 26 '18 at 18:31
  • Yes, I'll be sure to do that. – Fuselight Jun 28 '18 at 15:12
  • Thanks, that's helpful - I'm still not 100% clear on what the issue is though. With those images, the result looks like the image you posted with both body and shoes combined (https://i.stack.imgur.com/Hg4Y2.png). Isn't that the desired result? – Gama11 Jun 28 '18 at 15:48
  • Perhaps for some reason you're getting different results because of unrelated code in your project you didn't include in your question? Here's a .zip of the full project that's seemingly working fine for me: https://filebin.net/48wy41mcpcb1d7o3 – Gama11 Jun 28 '18 at 15:51
  • Hey Gama, I should have done more extensive testing of the .threshold() function. I forgot to add the green background to the images I provided, meaning you would have seen the same result. I'll post the solution once I figure out how to properly make use of threshold() in OpenFL. – Fuselight Jun 28 '18 at 16:16
  • Yeah, that's a great idea. I wasn't expecting threshold to not work, so I didn't think about it. – Fuselight Jun 28 '18 at 16:39