Composition for a "shadow layer": a layer with multiple children, which has an alpha < 1.0

Im trying to create the following:
A "shadows layer":
A layer with multiple children (each is a shadow of a game entity),
the layer itself has an alpha < 1.0 (let's say 0.5),
without overlapping objects adding to the alpha value.

meaning: even if children in the shadow layer intersect, the layer itself should keep a "flat" alpha value.

I cant use cache since the this layer is "dynamic": the child objects are moving...
I've been trying to use ble, no success:
this.shadowLayer = new Container().ble('???').alp(0.5);

coming from the old Flash AS3 world, i was able to achieve it there, using some property on the parent layer.
I do hope there's something similar here :slight_smile:

Hi @EZ123 - welcome to the ZIM Forum. Here are a few ways with the first way being the best.

It does update the cache... possibly, you could create the same scene twice and not cache.

Thanks for the great examples!

Unfortunately I'm aiming for a different look (top down isometric), with different constraints:

  1. The background isn't a flat color, but rather a bitmap
  2. The entities are bitmaps / sprites
  3. The shadows are also bitmap / sprites, BUT are different from the entities themselves

here's a sample code (can be tested in the editor) that demonstrates the required look and the shadow issue (i'm not sure how to share it in the editor):

// Given F, S, W, H or frame, stage, stageW, stageH
// assume background is a bitmap, and not a flat color
const gradient = new GradientColor(['#FF0', '#F8F'], [0,1], 0,0, 0,H);
const bg = new Rectangle(W, H, gradient);
S.addChild(bg);

// shadowsLayer - shadows are bitmaps/sprites, different from entities
const shadowsLayer = new Container().ble('normal').alp(0.5);
S.addChild(shadowsLayer);

// entitiesLayer - entities are bitmaps/sprites, different from shadows
const entitiesLayer = new Container();
S.addChild(entitiesLayer);

// add entities and shadows
const data = [
    { x: 128, y: 256, tc: 'red', fc: 'darkred' },
    { x: 128, y: 192, tc: 'green', fc: 'darkgreen' },
    { x: 64, y: 192, tc: 'blue', fc: 'darkblue' },
    { x: 32, y: 32, tc: 'red', fc: 'darkred' },
];

// assume their position is updated
data.forEach((data) => {
    // entity
    const entity = new Container();
    const top = new Rectangle(64, 64, data.tc).addTo(entity).loc(0, -16);
    const front = new Rectangle(64, 16, data.fc).addTo(entity).loc(0, 48);
    entitiesLayer.addChild(entity);
    entity.x = data.x;
    entity.y = data.y;
    // shadow
    const shadow = new Shape().f('black').mt(0, 0).lt(64, 0).lt(80, 16).lt(80, 80).lt(16, 80).lt(0, 64).ef();
    shadowsLayer.addChild(shadow);
    shadow.x = data.x;
    shadow.y = data.y;
});

S.update();

Appreciate any help with that

You can make the Frame color and outerColor clear. As in

new Frame(FIT, 1024, 768, clear, clear, ready);

And put the background image under the stage in HTML and CSS using z-index.

Or use multiple frames with the background image on the first frame and the app with its frame colors clear as the second frame. In which case, probably in the second frame ready event use F.setDefault();

The caching of the scene should work fine with bitmaps, shapes, etc.

To share with the editor, you can log in and save the file. Then you can keep your files, make lists of them, etc. Try it! It is handy.

I'm building and changing the background (built with bitmaps) dynamically so I cant use the HTML / CSS for that.

Here's the sample in the editor:

You can see the shadows issue when they overlap and the overlapping section has alpha > 0.5.
can I do something with the shadowsLayer layer (blending / caching) to fix this shadows issue?

Hi EZ.

If your shadows are only shapes, you can just cache() and then set alpha of the whole layer like the example above. We put the updateCache() in a Ticker as you say you will be dynamically updating.

If you have a shadow layer that has color and you no longer want color but rather it all to be black like a shadow, and you need to update underneath the shadow then you can use ColorEffect() to turn the shadow layer all one color.

Awesome!
This is what I was looking for.
Really appreciate the quick and detailed support :slight_smile:

1 Like