GameMaker: alpha mask on isometric tiles

As you might have noticed, process of making nice-looking isometric games can be tricky.
Especially that part when you want your terrain look like actual terrain rather than arrangement of isometric images.
Common approach to this is to use alpha channel mask(s) to smooth edges of tiles.
Here I've made a script that applies such mask to given sprite, handling all additional actions needed.

So, you pass a sprite and a mask to script. Mask can look like this for a 64x32 tile:

Obviously you can get further and draw something more creative like 'curly' edges.
So, the script is...

// scr_smooth_tile(tile:sprite, mask:sprite)
// tile: sprite to apply mask to
// mask: grayscale alpha mask sprite, can be larger than source
// Applies edge mask to given isometric tile.
// Source sprite will be modified upon execution.
// by YellowAfterlife
// src: http://www.yellow.indieis.me/2012/02/25/gamemaker-alpha-mask-on-iso-tiles/
var spr, bit, i,
    src, sn, sw, sh, sw2, sh2, sx, sy, su, sv,
    msk, mw, mh, mx, my, mu, mv;
// source parameters:
src = argument0;
sn = sprite_get_number(src);
sw = sprite_get_width(src);
sh = sprite_get_height(src);
sx = sprite_get_xoffset(src);
sy = sprite_get_yoffset(src);
sh2 = sh >> 1;
sw2 = sw >> 1;
su = -sw2 + sx;
sv = -sh2 + sy;
// mask parameters:
msk = argument1;
mw = sprite_get_width(msk);
mx = (mw >> 1);
mh = sprite_get_height(msk);
my = (mh >> 1);
mu = (mw - sw) >> 1;
mv = (mh - sh) >> 1;
// surface:
bit = surface_create(mw, mh);
surface_set_target(bit);
for (i = 0; i < sn; i += 1) {
    draw_clear_alpha(0, 0);
    draw_sprite(src, i, mx + su, my + sv);
    // side-straight:
    draw_sprite(src, i, mx + su - sw2, my + sv - sh2);
    draw_sprite(src, i, mx + su + sw2, my + sv - sh2);
    draw_sprite(src, i, mx + su - sw2, my + sv + sh2);
    draw_sprite(src, i, mx + su + sw2, my + sv + sh2);
    // side-diag:
    draw_sprite(src, i, mx + su - sw, my + sv);
    draw_sprite(src, i, mx + su + sw, my + sv);
    draw_sprite(src, i, mx + su, my + sv - sh);
    draw_sprite(src, i, mx + su, my + sv + sh);
    // create from \ add to sprite:
    if (i == 0) {
        spr = sprite_create_from_surface(bit, 0, 0, mw, mh, false, false, mu + sx, mv + sy)
    } else {
        sprite_add_from_surface(spr, bit, 0, 0, mw, mh, false, false)
    }
}
surface_reset_target();
sprite_set_alpha_from_sprite(spr, msk);
sprite_assign(src, spr);

... or download this example

Download GMK

Related posts:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.