Bug with Masking?

I have had a heck of a time trying to get masking to work on a specific sized static image.

A test project is attached. Please pay attention to the lifebars beneath the crewScrollView scrollable group (gridGroup). 

The first member, does not use a mask. It is simply distorted with manipulation of displayObject.width

The rest of the members (who are perfectly matched in size and orientation if you remove their masks) seem to be ~28% larger, for the purposes of using the mask to slide them down, rather than using a distortion (which messes up the smooth ends). This 1/3 enlargement? means that a 50% mask move down a life bar looks like a 33% This appears to be a bug in masking.

Can someone confirm that I’m not missing anything and that the behavior is simply aberrant?

This is not a mask issue, you’re doing your math incorrectly.  I’ve resolved this exact calculation before.  If I can find my example I’ll post it.

Also, not related to your question, but I though you should know.  One of the masks in your project doesn’t conform to masking rules: crewscrollmask.png  (692 x 319).  319 is not a multiple of 4.

BTW, thanks a lot for the sample project, but in the future, make your demos a single main.lua, config.lua, build.settings and assets.

  • OR -

Make the code that does the work a module.

Digging through someone else’s project and scenes is a pain when all you want to do is focus on the relevant code.

I’m not super comfortable sticking everything in a main.lua, but simplifying it is a good idea. I’ll take that advice.

I’m not sure how I’m doing my math incorrectly. If it’s just a calculation problem, it should be a one line change in scene:setMaskedFillBar (ln 137)

The offset looks correct and should roughly match the fillbar.width setting (ln 112)

Hi.  I’m playing around with this and you’ve got another issue.  Your sprites aren’t centered so when you use them they add an offset which is making all the calculations goofy.  You should fix this or better use discrete images.  You’re not saving anything with two images in a sheet.

You misunderstand.  I’m simply saying make the demo so simple we can immediately focus on the problem code.

Trust me, it is a math problem.  working on it now, but dealing with this art is slowing me down.

If you have the bar art as discrete image, please link them here.

Ahh… I see the problem.  You’ve got shadows in your art so of course the vertical center is not really the vertical center of the bar, but the center of the image bar + shadow.

The fillbar graphic does not have a shadow. The fillbar is in a group of its own called fillgroup.

        local fillgroup = display.newGroup()         gridGroup:insert(fillgroup)         local fill = util.getSpriteGfx(fillgroup, "test", "fillbar3-ui") -- returns a sprite, no shadow         fill.y = 207+1         fill.x = fillbar.x+5 -- snipped if/else         local fillmask = graphics.newMask("images/masks/fillbarmask4-ui.png")         fill:setMask(fillmask)         local dist = scene:setMaskedFillBar(fill, fill.width, runner.maxhitpoints/2, runner.maxhitpoints) -- does the algebra, fixes min/max         fill.maskX = 0-dist

The mask is specifically sized to match the size of the green bar sprite. The backing shouldn’t affect it at all, being in a different group (and scaled). Maybe this isn’t true?

This is the best I can do w/ the assets you provided:

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2017/08/maskfillbarbetter.zip

Debug feature (white lines) turned on in this demo:

https://www.youtube.com/watch?v=eIL5Um5tT44&feature=youtu.be

You’re right the fill bar does not have a shadow, but the tray does.  All of these things are related when you make a bar and work out the masking and calculations.  A progress bar has a number of parts that all affect the percent filled/offset/scaling calcs.

In reality the size of the green bar versus the mask is wrong.  

For this usage, you want them both to have the same dimensions so the black part of your mask doesn’t overlap the art of the bar.

In my example I played some scaling games to help this, but it isn’t exactly right.  So, I hope it gets you started, but there is more work to get this looking right.

One more note and I’ll leave this alone.

The example I gave is just so-so.  It is a bit long (the module) and has many components to make a single progress bar style HUD.

You can make this a lot easier if you don’t give the bar rounded edges.  Instead, create a Corona compliant mask that also has nice feathering on the inner edge.  

Then, create a newImageRect() with your unrounded green bar and mask it directly.

Scale this bar to fit the frame you have provided.

Finally, change the mask x-offset to get the percentage filled percent.

This is all off-the-top-of my head conjecture so I’d experiment w/ it first.

Wow, that is a really nice set of work. 

Sliding the bar around works under the mask, as you demonstrated, which is not the issue I’m trying to address.

I’m trying to move the mask along the X axis. Sliding the bar gives a different effect, with the “strange” shadowed round end disappearing at the root instead of the receding edge, which is visually dissonant when I scale it up.

Taking into account what you wrote, the changes that caught my eye:

    hud.barGroup.maskScaleX = 120/(204-6) -- scale acounting for bar art width versus non-black part of mask     hud.barGroup.maskScaleY = 16/(36-12) -- scale acounting for bar art height versus non-black part of mask

I am perplexed by this calculation. I’ve never seen anything like it.

204 x 36 is the mask png total size, removing 3*2 and 6*2 from the useless pixels of the mask is a uniform subtraction. If I had seen this in any tutorial, it would make sense, but then it’s paired with this strange scaling.

I count the white part of the mask being 197 (not 198) since 1 side of the mask has an extra pixel of black to make it an even multiple of 4, which doesn’t seem to be an issue?

The bar sprite 123 x 24 (or maybe 124 x 24), so

120 and 16 comes from what calculation? It’s basically the exact pixel dimensions of the green bar (119x16) which is strange, because my texture packer detects it as so much larger.

>  Instead, create a Corona compliant mask that also has nice feathering on the inner edge.  

Masks that aren’t monochrome, “don’t work”. I mean that they don’t mask at all, as if they aren’t Corona compliant unless I do a black/white indexed tone in photoshop. I made a rounded mask, which should be sufficient for me anyway and gives me the nice rounded end on the receding side (either side) instead of a flat edge like a container mask, even with the expected visual dissonance.

Added simplest test case, as suggested.

This is not a mask issue, you’re doing your math incorrectly.  I’ve resolved this exact calculation before.  If I can find my example I’ll post it.

Also, not related to your question, but I though you should know.  One of the masks in your project doesn’t conform to masking rules: crewscrollmask.png  (692 x 319).  319 is not a multiple of 4.

BTW, thanks a lot for the sample project, but in the future, make your demos a single main.lua, config.lua, build.settings and assets.

  • OR -

Make the code that does the work a module.

Digging through someone else’s project and scenes is a pain when all you want to do is focus on the relevant code.

I’m not super comfortable sticking everything in a main.lua, but simplifying it is a good idea. I’ll take that advice.

I’m not sure how I’m doing my math incorrectly. If it’s just a calculation problem, it should be a one line change in scene:setMaskedFillBar (ln 137)

The offset looks correct and should roughly match the fillbar.width setting (ln 112)

Hi.  I’m playing around with this and you’ve got another issue.  Your sprites aren’t centered so when you use them they add an offset which is making all the calculations goofy.  You should fix this or better use discrete images.  You’re not saving anything with two images in a sheet.

You misunderstand.  I’m simply saying make the demo so simple we can immediately focus on the problem code.

Trust me, it is a math problem.  working on it now, but dealing with this art is slowing me down.

If you have the bar art as discrete image, please link them here.

Ahh… I see the problem.  You’ve got shadows in your art so of course the vertical center is not really the vertical center of the bar, but the center of the image bar + shadow.

The fillbar graphic does not have a shadow. The fillbar is in a group of its own called fillgroup.

        local fillgroup = display.newGroup()         gridGroup:insert(fillgroup)         local fill = util.getSpriteGfx(fillgroup, "test", "fillbar3-ui") -- returns a sprite, no shadow         fill.y = 207+1         fill.x = fillbar.x+5 -- snipped if/else         local fillmask = graphics.newMask("images/masks/fillbarmask4-ui.png")         fill:setMask(fillmask)         local dist = scene:setMaskedFillBar(fill, fill.width, runner.maxhitpoints/2, runner.maxhitpoints) -- does the algebra, fixes min/max         fill.maskX = 0-dist

The mask is specifically sized to match the size of the green bar sprite. The backing shouldn’t affect it at all, being in a different group (and scaled). Maybe this isn’t true?

This is the best I can do w/ the assets you provided:

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2017/08/maskfillbarbetter.zip

Debug feature (white lines) turned on in this demo:

https://www.youtube.com/watch?v=eIL5Um5tT44&feature=youtu.be

You’re right the fill bar does not have a shadow, but the tray does.  All of these things are related when you make a bar and work out the masking and calculations.  A progress bar has a number of parts that all affect the percent filled/offset/scaling calcs.