code of the Ninja();

// in search of swift, efficient, and invisible code

2011-03-02

Partially Erasing Surfaces in Game Maker

This post is part of a series for enthusiasts of the legacy software Game Maker 8.0, exploring its features and functionality in depth.

Hey there, Code Ninjas!

One of the cool things about Game Maker 8 is the ability to export PNGs with an alpha channel for transparency. There's no separate functions for doing so, though; if you want to be sure the exported image is in PNG format, you have to make sure the extension is explicitly ".png", like so:

sprite_save("sprite.png");
screen_save_part("screenie.png", 320, 224);

It's especially cool to create partially transparent surfaces and export them. After creating a surface, you can use the draw_clear_alpha() function to make it completely transparent:

surface_set_target(surface);

draw_clear_alpha(c_black, 0); // clear the entire surface with fully transparent colour

surface_reset_target();

One thing that's annoying, though, is the way that drawing with a partial alpha to a surface works. Instead of blending with the colour underneath, the colour is completely replaced, alpha and all. Effectively this punches "holes" in the surface image.

You'd think this could exploited to create some kind of eraser tool. Draw pixels with an alpha of 0 to the surface to erase pixels that are already there, leaving fully transparent pixels behind.

This doesn't work, though, for some reason. Very low alpha values such as 0 or 0.01 function exactly as you'd normally expect when drawing to the screen, even though higher values such as 0.7 differ when using surfaces.

So much for the ability to erase pixels from a surface using that method... But there is another way.

Set the blend mode to bm_subtract before drawing to the surface and you'll effectively be able to erase from the image:

surface_set_target(surface);

draw_set_blend_mode(bm_subtract);
draw_set_color(c_white); // color doesn't actually matter
draw_set_alpha(1); // alpha must be 1 to fully erase pixels

// erase an "X" across the surface
draw_line(0, 0, surface_get_width(surface), surface_get_height(surface));
draw_line(surface_get_width(surface), 0, 0, surface_get_height(surface));

draw_set_blend_mode(bm_normal);

surface_reset_target();

This trick may come in handy on occasion, especially when making games where the user is allowed to paint custom textures for things - an erase tool is essential.

Until we meet again, happy coding!

No comments:

Post a Comment