melonjs / melonJS

a fresh, modern & lightweight HTML5 game engine
https://melonjs.org
MIT License
5.93k stars 643 forks source link

[BUG] Sprites do not support opacity / alpha settings in Canvas mode #1120

Closed wpernath closed 2 years ago

wpernath commented 2 years ago

OS platform / Browser

Mac OS 12.4 / Chrome 104

melonJS version

13.1.1

Bug description

I am using a background image in my game menu screens as shown in one of your examples:

this.backgroundImage = new Sprite(game.viewport.width / 2, game.viewport.height / 2, {
    image: loader.getImage("background-pic"),
});

// scale to fit with the viewport size
this.backgroundImage.scale(game.viewport.width / this.backgroundImage.width, game.viewport.height / this.backgroundImage.height);
this.backgroundImage.setOpacity(0.3);

this.addChild(this.backgroundImage, 0);

In WebGL mode, this uses the opacity-settings and the background image gets darker. In canvas rendering mode, the whole image is drawn without respecting this setting.

Thanks for all your help.

wpernath commented 2 years ago

I just tested it with another Sprite (my Player sprite). If I add it to the game world with opacity settings, it will be displayed as is (so no darker / lighter support). If I am directly setting player.alpha = 0.3, the background starts to shine through.

However, this does not work with the sprite in my original post. But my game menu screens are all inherited from Container. Perhaps this is part of the issue?

obiot commented 2 years ago

actually it's not a bug with Sprite, it has to do with composition in Canvas mode. By default Container's background Colors is (0, 0, 0, 0) (so no background color), and in this case the background image wil keep being drawn over itself, visually "removing" the opacity level you defined for your image

if you add me.game.world.backgroundColor.alpha = 1.0; to your code, you will see that then the behaviour is correct as the display is cleared with a black background at every frame. and this then should be the correct behaviour if you want to change the opacity level of your image.

Now another bug I then realized is that in WebGL the behaviour is not correct, when no background color is specified (e.g. alpha = 0), the WebGL renderer still clear the background, where it should not. And that's why you could not see this issue in WebGL but you could with Canvas.

obiot commented 2 years ago

sorry sometimes I'm getting lost myself in all the code and options, but the actual proper way is also to set the transparent option to true, this will anyway end up doing the same thing in Canvas mode, but does enable a transparent background with both rendererer.

obiot commented 2 years ago

so with the latest change, with transparent being false by default both renderer will have the same behaviour and your background should be correct

https://github.com/melonjs/melonJS/commit/16a7a597e5f59cc662e49455f41b9a14a06ae772

wpernath commented 2 years ago

Thanks a lot, Oliver!

I just have used my game with the latest melonjs from GitHub, but now I am getting an exception:

melonjs.module.js:7396 Uncaught TypeError: Cannot read properties of undefined (reading 'transparent') at WebGLCompositor.clear (melonjs.module.js:7396:27) at WebGLRenderer.clearColor (melonjs.module.js:31268:32) at World.draw (melonjs.module.js:21469:22) at Camera2d.draw (melonjs.module.js:23018:19) at eval (melonjs.module.js:23180:20) at Map.forEach () at DefaultLoadingScreen.draw (melonjs.module.js:23178:22) at Application.draw (melonjs.module.js:22294:19) at _renderFrame (melonjs.module.js:23425:10)

I have just replaced node_modules/melonjs/dist/* with the output of npm run dist of the source of melonjs... Did I do anything wrong here?

As always: Thank you!!

obiot commented 2 years ago

Oh boy, what did i do ! 😂😂😂

obiot commented 2 years ago

here it is, sorry my fault actually, I committed a changes I was not planning to while trying different things ! I also updated the builds in the dist directory (so that you don't need to rebuild the whole thing).

obiot commented 2 years ago

@wpernath all good now, can I close this one ?

wpernath commented 2 years ago

Let me test it today. I am going to give feedback by end of (my) today. Thank you!

obiot commented 2 years ago

sure of course !

wpernath commented 2 years ago

I have just tested it and it seems to work now. My background component now sets

this.transparent = true

and it seems to look identical on CANVAS and WebGL renderer!

Many, many thanks for your work!

obiot commented 2 years ago

awesome ! thanks :)