• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Silhouettes With Tiles, in a tile based room

M

Muddykat

Guest
GM Version: Studio
Target Platform: Windows
Download: see code posted below
Links: NA

This is just to help people who want silhouettes with tiles but have tiles on the floor or have other troubles with tiles that shouldn't have a silhouette

This code is a modified version of a previous tutorial, if you would like a link to the original pm me.

Create event in a Control object

Code:
    tileSurf=-1; //Surface to draw tiles which can obstruct the player
    silhouetteSurf=-1; //Surface to draw the player's silhouette
 
    playerSprite=obj_lifeform.sprite_index; //get the player sprite
    spriteWidth = sprite_get_width(playerSprite); //width of player sprite
    spriteHeight = sprite_get_height(playerSprite); //height
    spriteXOff = sprite_get_xoffset(playerSprite); //x origin value
    spriteYOff = sprite_get_yoffset(playerSprite); //y origin value
 
 
    // top left coordinate of the player sprite is where we will draw the surface
    surfXPos=obj_lifeform.x-spriteXOff; //player.x - xorigin = left side of sprite
    surfYPos=obj_lifeform.y-spriteYOff; //player.y - yorigin = top side of sprite
 
    color=c_fuchsia; //Color of the silhouette
 
 
    // This is to store all of the tile data so we can access it quickly
    bkList[0]=0;
    xxList[0]=0;
    yyList[0]=0;
    leftList[0]=0;
    topList[0]=0;
    widthList[0]=0;
    heightList[0]=0;
 
    tile=tile_get_ids(); //Get all the tiles in the room
 
 
    for(i=0;i<array_length_1d(tile);i++)//loop through all the tiles and store their data in the arrays
    {
        bkList=tile_get_background(tile);
   
        xxList=tile_get_x(tile);
        yyList=tile_get_y(tile);
   
        dpList=tile_get_depth(tile);
   
        leftList=tile_get_left(tile);
        topList=tile_get_top(tile);
   
        widthList=tile_get_width(tile);
        heightList=tile_get_height(tile);
    }
Draw Event in the Control Object

Code:
//Update player variables as create event
playerSprite=obj_lifeform.sprite_index;
spriteWidth = sprite_get_width(playerSprite);
spriteHeight = sprite_get_height(playerSprite);
spriteXOff = sprite_get_xoffset(playerSprite);
spriteYOff = sprite_get_yoffset(playerSprite);
surfXPos=obj_lifeform.x-spriteXOff;
surfYPos=obj_lifeform.y-spriteYOff;

if!surface_exists(tileSurf) //Create surface
{
    tileSurf=surface_create(spriteWidth,spriteHeight); //Dimensions = player sprite dimensions
}

//tile=tile_get_ids() //Get all the tiles in the room

surface_set_target(tileSurf);//draw to tileSurf
draw_clear_alpha(c_black,0);//clear tileSurf

for(i=0;i<array_length_1d(bkList);i++)//loop through all the tiles and grab their data
{

    bk=bkList;
    xx=xxList;
    yy=yyList;
    left=leftList;
    top=topList;
 
    width=widthList;
    height=heightList;
    //Only draw the tiles if they are below the player
    //This allows the player to be infront, and behind objects, and only draw the silhouette if player is behind them.
    if dpList > obj_lifeform.depth continue;
 
    //draw the tile to the surface
    draw_background_part(bk,left,top,width,height,xx-surfXPos,yy-surfYPos);
}
surface_reset_target();//reset draw target


if !surface_exists(silhouetteSurf)//create silhouetteSurf
    silhouetteSurf=surface_create(spriteWidth,spriteHeight); //Dimensions = player sprite dimensions

surface_set_target(silhouetteSurf);//draw to silhouetteSurf

    draw_clear_alpha(c_black,0); //clear surface
    draw_surface(tileSurf,0,0); //draw the tile surface to silhouetteSurf
    draw_set_blend_mode_ext(bm_dest_alpha,bm_inv_dest_alpha); //Important blend mode to draw the silhouette
  
    d3d_set_fog(1,color,0,0); //This set's the color of your silhouette
 
    //draw the player to the surface so a silhouette can be made from it
    //IMPORTANT- you must still draw you player sprite normally at a lower depth than this object
    //so the silhouette can be drawn above the player sprite
    //The objPlayer's depth is -10 and objSilhouette's depth is -100
    with obj_lifeform
        draw_sprite_ext(sprite_index,image_index,x-other.surfXPos,y-other.surfYPos,image_xscale,image_yscale,0,-1,.5);

    d3d_set_fog(0,c_fuchsia,0,0); //Stop coloring the sprite
    
    draw_set_blend_mode(bm_normal); //reset blend mode
    
surface_reset_target();//reset draw target

draw_surface(tileSurf,surfXPos,surfYPos); // Draw the tile surface
draw_surface_ext(silhouetteSurf,surfXPos,surfYPos,1,1,0,-1,1); //the the silhouette surface

Don't Forget to Free the Surface and what not, that's pretty self-explanatory.

The main difference between this code and the original is it's better at detecting WHEN to apply the Silhouette, Instead of relying on the Y-axis variable. This code checks the DEPTH of all the tiles and compares them to the Object that has the Silhouettes Depth, Thus making the Silhouette Effect more reliable.

Hope this helps
 
Last edited by a moderator:
Top