GameMaker: Studio

GameMaker: Studio

Not enough ratings
Fun with Surfaces Bonus Chapter: Fog of War
By Scorcher24
In the last episode of "Fun with Surfaces", I showed you how to create a fancy minimap. But what is a minimap without Fog of War,right?
   
Award
Favorite
Favorited
Unfavorite
Prerequesites
You need to have worked through this Tutorial first and/or downloaded the GMZ:
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=289563579

This is a continuation of the previous guide.
It surfaced...
Okay, so we got our minimap working. Now we need a fog of war over that minimap to hide the map from the player at first. We are going to use another surface for that and we are going to use blending. If you are not familiar with blending, it basically describes how the image is drawn on the screen. You can do that either normally, so it just drawn, or you can render a difference between 2 images. And that is what we are going to do. If you want to do more, see this[docs.yoyogames.com] page in YoYo's Documentation about it.
Let there be light...
To remove the Fog of War, we need a "light". Now this is not a traditional light, it is merely a picture of one. So create a new sprite, 64x64 or whatever suits you. Now edit this picture and create a simple white circle:


This is what we are going to draw on the surface, to make the minimap shine through. This should be easy enough to do it yourself.
Editing the minimap object
Bring up the minimap object we created earlier and add a new variable to the Create Event:

oSurfFog = -1;

The next step is to create a new script in the "Draw Event":

/// Create and draw Fog of War Surface if (!surface_exists(oSurfFog)) { // Create a surface with the size of our room oSurfFog = surface_create( room_width, room_height ); // Set the target surface_set_target( oSurfFog ); // Clear with black draw_clear(c_black); // Tell GMS we are done surface_reset_target(); } // Find the player, we should have only one var o = instance_nearest( x, y, objPlayer ); // Set the target surface_set_target( oSurfFog ); // Set the blend mode. draw_set_blend_mode( bm_src_colour ); // Draw our light onto the surface ( I scaled it up to 2x, because 64x64 was too small) draw_sprite_ext(sprLight, 0, o.x, o.y, 2, 2, 0, c_white, 1 ); // Reset blend mode draw_set_blend_mode( bm_normal ); // Reset the target surface_reset_target();

Pretty straight forward, huh? What it does is it paints the light onto the surface and makes it white. Through bm_src_color this is blended together with the light, letting the minimap surface come through.
Drawing the surface over the minimap
Switch to the "Draw GUI Event". Create a new script and make sure it is listed AFTER the script in which we draw our minimap, to ensure it is drawn over the minimap.

Now open the script of the minimap and delete the part with the rectangle. This got moved to this new script, so it is still drawn over the surface.

/// Draw Fog of War Surface to Screen if (surface_exists(oSurfFog)) { var old = draw_get_color(); draw_set_color(c_red); draw_surface_stretched( oSurfFog, 40, 40, room_width/8, room_height/8 ); draw_rectangle( 40, 40, room_width/8+40, room_height/8+40, true); draw_set_color(old); }
This is pretty open and shut. It just draws the surface on the same position as the minimap and readds the red rectangle.
Conclusion
I thought about doing this after I came up with the minimap and it was actually a lot easier than I initially though. Here is how it looks like:

1 Comments
BOYCOTT S-T-E-A-M! 23 Jun, 2016 @ 2:06am 
Haven't tried this one yet, but I found your minimap one very useful and informative. The way this functions seems pretty much identical to the way layer masks work in art software like GIMP.