Legacy GM Making objects appear invisible when moving behind other invisible objects.

W

Wuzzems

Guest
I thought of possibly making an object mimic the background but sadly the background is moving. Basically I want to move an object behind another invisible object, and as it moves behind that object it should be completely transparent, the parts that have moved behind it so far. Pretty much something like the invisibility cloak from Harry Potter.
 

CMAllen

Member
Well, one way you could do it is to have your 'moving' objects draw to a surface, then draw a special 'mask' sprite type (which is straight black with the alpha values higher for the parts you want to disappear and 0 for the areas that shouldn't disappear) of your cloaking object(s) in bm_subtract mode. Then you draw that surface instead of the actual sprite, using the object's sprite offset values to draw the surface in the correct place. That should simulate an object 'disappearing' behind another 'invisible' object.

So I'd do it something like this:
Code:
[moving_obj (whatever name that might be) STEP EVENT]
cloaking_obj = instance_position(x,y,obj_cloakers);

[moving_obj DRAW EVENT]
if(cloaking_obj != noone) {
    surf_cloak = surface_create(sprite_get_width(sprite_index), sprite_get_height(sprite_index);
    surface_set_target(surf_cloak);
    draw_sprite(sprite_index, image_index,sprite_get_xoffset(sprite_index), sprite_get_yoffset(sprite_index));
    draw_set_blend_mode(bm_subtract);
    cloakx = cloaking_obj.x - x;
    cloaky = cloaking_obj.y - y;
    draw_sprite(cloaking_obj.sprite_index,cloaking_obj.image_index,
        cloakx+sprite_get_xoffset(cloaking_obj.sprite_index),
        cloaky+sprite_get_yoffset(cloaking_obj_sprite_index));
    draw_set_blend_mode(bm_normal);
    surface_reset_target();
    draw_surface(surf_cloak, x - sprite_get_xoffset(sprite_index),
        y - sprite_get_yoffset(sprite_index));
    surface_free(surf_cloak);
} else {
    draw_self();
}
It should be noted that while this code *should* work, it comes with some limitations. It won't work with multiple cloaking objects, since it only checks for a single possible collision with a cloaking object, so a player must fully exit a given cloaking object before another cloaking object can apply the effect or only one will be applied. It may not work with dynamic sprites that change sizes or include parts that rotate independently of the main sprite (but you could tweak it to do so, within reason). It will also not work properly with objects that are at different scale values (it currently operates under the assumption that all objects have a uniform 1.0 scale). You could adjust the code to account for this, as it's simply getting the respective entity's image_xscale and image_yscale values and multiplying the related values by those scale values (such as the surface_create part so that the surface is large enough to accommodate a scaled up moving_obj sprite).

Hope this helps or points you in the right direction! (edit for legibility of code)
 
W

Wuzzems

Guest
Thanks a lot. I'll see if it will work for my situation, if not I'll probably just go with animation and make the object snap to a certain location while the animation is playing to make it look like it's still moving. I'll write back if something goes awry.
 
Top