• Hey! Guest! The 40th (!!!) GMC Jam will take place between February 25th, 12:00 UTC to March 1st 12:00 UTC. Why not join in this very special anniversary jam! Click here to find out more!

GML Show sprite on collision only (Shader?)

Jochum

Member
Hey everyone,

I'm trying to show a sprite on the place that it collides only. This way I can create a type of shadow from one planet on top of the planets underneath:
The shadow is created by showing the same sprite, making it black and lowering the alpha.

Screenshot:
screenshot_game.jpg

Hopefully, someone knows how to create this.
Best,
SirGoose :duck:
 
Last edited:

Jochum

Member
To be quite honest, I'm not sure what you want.
Can you try explaining differently?
I'm trying to create a shadow from the earth sprite on the planet's sprites underneath (Moon & Mars). I thought the best way to do this is to create an enlarged sprite of the earth (right behind the original earth sprite) and put the alpha to ~ 30%. The problem is that you can see that grayed out earth sprite on the background as well, I just want to show the sprite where it collides with the Moon and Mars sprite. And that way create a realistic shadow.

Do you know how I can achieve this or is there a better way to create the shadow of the Earth sprite on the underlying planet sprites?
 

Tthecreator

Your Creator!
Well, now I understand.
One thing you could do (without having to use shaders) is to use a blend mode like this:

GML:
var bm = gpu_get_blendmode_ext();
bm[0] = bm_dest_alpha;//try out different blend modes if it isn't working
bm[1] = bm_inv_src_alpha;//try out different blend modes if it isn't working
gpu_set_blendmode_ext(bm);
Normally when you draw a sprite over another sprite the following formula is used:
GML:
new_destination_color_red = source_color_red * source_alpha + destination_color_red * (1-source_alpha).
//(same for blue and green and alpha)
Here the source is any pixel from the image you are trying to draw. The destination is any pixel which is already drawn there.
Note that if the source alpha were 0, no actual change would be made to the image.

Now when you execute the function I gave you, the formulate changes to this:
GML:
new_destination_color_red = source_color_red * destination_alpha + destination_color_red * (1-source_alpha).
//(same for blue and green and alpha)
Now, when the destination has an alpha of 0, the new destination color will still have an alpha 0
 

Fanatrick

Member
The destination is any pixel which is already drawn there.
I believe this is where you misunderstood. He wants to mask the drawing area exclusively on objects underneath the currently drawn one, without drawing over anything else.

 

Jochum

Member
Well, now I understand.
One thing you could do (without having to use shaders) is to use a blend mode like this:

GML:
var bm = gpu_get_blendmode_ext();
bm[0] = bm_dest_alpha;//try out different blend modes if it isn't working
bm[1] = bm_inv_src_alpha;//try out different blend modes if it isn't working
gpu_set_blendmode_ext(bm);
Normally when you draw a sprite over another sprite the following formula is used:
GML:
new_destination_color_red = source_color_red * source_alpha + destination_color_red * (1-source_alpha).
//(same for blue and green and alpha)
Here the source is any pixel from the image you are trying to draw. The destination is any pixel which is already drawn there.
Note that if the source alpha were 0, no actual change would be made to the image.

Now when you execute the function I gave you, the formulate changes to this:
GML:
new_destination_color_red = source_color_red * destination_alpha + destination_color_red * (1-source_alpha).
//(same for blue and green and alpha)
Now, when the destination has an alpha of 0, the new destination color will still have an alpha 0
Thanks for your help! I see that this requires a lot of knowledge to apply. I managed to have two sprites blend thanks to another tutorial. Incidentally, the overlay sprite moves with the planet sprite, while the overlay sprite should have a separate movement.

I have uploaded the code. Would you know how I can make this possible?

Code:
 
Top